add Terraform + Ansible infrastructure for GCP deployment
Provisions e2-micro VM (us-east1-b, free tier) with static IP, SSH and web firewall rules, Docker + Caddy startup script, and IAM bindings for Firestore and GCS access via ADC. Imports existing drb-calls bucket and c2-server Firestore database into state. Ansible roles handle first-time setup (swap, docker group) and all subsequent deploys via rsync + docker compose, with secrets managed via Ansible Vault. DNS stays on AWS Route 53.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
---
|
||||
# Sync code, write secrets, bring the stack up.
|
||||
|
||||
- name: Sync app code from local machine
|
||||
synchronize:
|
||||
src: "{{ local_repo_path }}"
|
||||
dest: "{{ app_dir }}/"
|
||||
delete: true
|
||||
recursive: true
|
||||
rsync_opts:
|
||||
- "--exclude=.git"
|
||||
- "--exclude=**/__pycache__"
|
||||
- "--exclude=**/.env"
|
||||
- "--exclude=**/gcp-key.json"
|
||||
- "--exclude=**/node_modules"
|
||||
- "--exclude=drb-c2-core/gcp-key.json"
|
||||
- "--exclude=infra/"
|
||||
become: false # rsync runs as the SSH user, not root
|
||||
|
||||
- name: Set ownership of app directory
|
||||
file:
|
||||
path: "{{ app_dir }}"
|
||||
state: directory
|
||||
owner: "{{ ssh_user }}"
|
||||
group: "{{ ssh_user }}"
|
||||
recurse: true
|
||||
|
||||
# No gcp-key.json needed — the VM authenticates to GCS/Firestore via ADC
|
||||
# (GCE metadata server). IAM roles are granted by Terraform.
|
||||
|
||||
- name: Template top-level .env (docker-compose MQTT creds)
|
||||
template:
|
||||
src: root.env.j2
|
||||
dest: "{{ app_dir }}/.env"
|
||||
owner: "{{ ssh_user }}"
|
||||
group: "{{ ssh_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Template c2-core .env
|
||||
template:
|
||||
src: c2-core.env.j2
|
||||
dest: "{{ app_dir }}/drb-c2-core/.env"
|
||||
owner: "{{ ssh_user }}"
|
||||
group: "{{ ssh_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Template discord-bot .env
|
||||
template:
|
||||
src: discord-bot.env.j2
|
||||
dest: "{{ app_dir }}/drb-server-discord-bot/.env"
|
||||
owner: "{{ ssh_user }}"
|
||||
group: "{{ ssh_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Template frontend .env
|
||||
template:
|
||||
src: frontend.env.j2
|
||||
dest: "{{ app_dir }}/drb-frontend/.env"
|
||||
owner: "{{ ssh_user }}"
|
||||
group: "{{ ssh_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Deploy Caddyfile
|
||||
template:
|
||||
src: Caddyfile.j2
|
||||
dest: /etc/caddy/Caddyfile
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Reload Caddy
|
||||
|
||||
- name: Bring the stack up (builds images if changed)
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ app_dir }}"
|
||||
build: always
|
||||
state: present
|
||||
pull: never
|
||||
become: true
|
||||
environment:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
|
||||
- name: Prune unused Docker images
|
||||
community.docker.docker_prune:
|
||||
images: true
|
||||
images_filters:
|
||||
dangling: true
|
||||
@@ -0,0 +1,13 @@
|
||||
# Managed by Ansible — do not edit manually on the server.
|
||||
|
||||
api.{{ domain }} {
|
||||
reverse_proxy localhost:8888 {
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
}
|
||||
}
|
||||
|
||||
app.{{ domain }} {
|
||||
reverse_proxy localhost:3000 {
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# drb-c2-core environment — Managed by Ansible. Do not edit manually.
|
||||
|
||||
MQTT_BROKER=mosquitto
|
||||
MQTT_PORT=1883
|
||||
MQTT_USER={{ vault_mqtt_c2_user }}
|
||||
MQTT_PASS={{ vault_mqtt_c2_pass }}
|
||||
|
||||
# No GCP_CREDENTIALS_PATH — the VM uses Application Default Credentials
|
||||
# via the GCE metadata server. The Terraform IAM bindings grant the required roles.
|
||||
FIRESTORE_DATABASE={{ vault_firestore_database }}
|
||||
GCS_BUCKET={{ vault_gcs_bucket }}
|
||||
|
||||
OPENAI_API_KEY={{ vault_openai_api_key }}
|
||||
GOOGLE_MAPS_API_KEY={{ vault_google_maps_api_key }}
|
||||
GEMINI_API_KEY={{ vault_gemini_api_key }}
|
||||
|
||||
SERVICE_KEY={{ vault_service_key }}
|
||||
NODE_API_KEY={{ vault_node_api_key }}
|
||||
|
||||
CORS_ORIGINS=["https://app.{{ domain }}"]
|
||||
@@ -0,0 +1,5 @@
|
||||
# drb-server-discord-bot environment — Managed by Ansible. Do not edit manually.
|
||||
|
||||
DISCORD_TOKEN={{ vault_discord_token }}
|
||||
C2_URL=http://c2-core:8000
|
||||
C2_SERVICE_KEY={{ vault_service_key }}
|
||||
@@ -0,0 +1,11 @@
|
||||
# drb-frontend environment — Managed by Ansible. Do not edit manually.
|
||||
|
||||
NEXT_PUBLIC_C2_URL=https://api.{{ domain }}
|
||||
|
||||
NEXT_PUBLIC_FIREBASE_API_KEY={{ vault_firebase_api_key }}
|
||||
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN={{ vault_firebase_auth_domain }}
|
||||
NEXT_PUBLIC_FIREBASE_PROJECT_ID={{ vault_firebase_project_id }}
|
||||
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET={{ vault_firebase_storage_bucket }}
|
||||
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID={{ vault_firebase_messaging_sender_id }}
|
||||
NEXT_PUBLIC_FIREBASE_APP_ID={{ vault_firebase_app_id }}
|
||||
NEXT_PUBLIC_FIRESTORE_DATABASE={{ vault_firestore_database }}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Top-level docker-compose environment — MQTT credentials for the broker container.
|
||||
# Managed by Ansible. Do not edit manually.
|
||||
|
||||
MQTT_C2_USER={{ vault_mqtt_c2_user }}
|
||||
MQTT_C2_PASS={{ vault_mqtt_c2_pass }}
|
||||
MQTT_NODE_USER={{ vault_mqtt_node_user }}
|
||||
MQTT_NODE_PASS={{ vault_mqtt_node_pass }}
|
||||
Reference in New Issue
Block a user