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:
+71
-20
@@ -8,10 +8,11 @@ terraform {
|
||||
}
|
||||
|
||||
# Store state in GCS — create the bucket manually once before first apply
|
||||
backend "gcs" {
|
||||
bucket = "drb-tf-state"
|
||||
prefix = "drb/state"
|
||||
}
|
||||
# Uncomment once GCS bucket permissions are confirmed working.
|
||||
# backend "gcs" {
|
||||
# bucket = "drb-tf-state"
|
||||
# prefix = "drb/state"
|
||||
# }
|
||||
}
|
||||
|
||||
provider "google" {
|
||||
@@ -19,6 +20,10 @@ provider "google" {
|
||||
region = var.region
|
||||
}
|
||||
|
||||
# Pull live project metadata (number, name) without hardcoding them.
|
||||
data "google_project" "current" {}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Static external IP
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -87,8 +92,8 @@ resource "google_compute_instance" "drb_server" {
|
||||
boot_disk {
|
||||
initialize_params {
|
||||
image = "debian-cloud/debian-12"
|
||||
size = 30 # GB — enough for Docker images + mosquitto data
|
||||
type = "pd-balanced"
|
||||
size = 30 # GB — free tier covers 30GB pd-standard on e2-micro
|
||||
type = "pd-standard"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +111,8 @@ resource "google_compute_instance" "drb_server" {
|
||||
# Startup script runs once on first boot to install Docker + Caddy
|
||||
metadata_startup_script = file("${path.module}/startup.sh")
|
||||
|
||||
# Allow the VM to pull from Artifact Registry using its service account
|
||||
# The default compute service account with cloud-platform scope gives the VM
|
||||
# full access to GCS and Firestore in the same project — no key file needed.
|
||||
service_account {
|
||||
scopes = ["cloud-platform"]
|
||||
}
|
||||
@@ -118,21 +124,66 @@ resource "google_compute_instance" "drb_server" {
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Cloud DNS records
|
||||
# IAM — grant the VM's default compute SA access to Firestore and GCS.
|
||||
# Since Firebase/GCS already live in the same project, no key file is needed —
|
||||
# the VM authenticates via the metadata server (ADC).
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
resource "google_dns_record_set" "app" {
|
||||
name = "app.${var.domain}."
|
||||
type = "A"
|
||||
ttl = 300
|
||||
managed_zone = var.dns_zone_name
|
||||
rrdatas = [google_compute_address.drb.address]
|
||||
locals {
|
||||
compute_sa = "serviceAccount:${data.google_project.current.number}-compute@developer.gserviceaccount.com"
|
||||
}
|
||||
|
||||
resource "google_dns_record_set" "api" {
|
||||
name = "api.${var.domain}."
|
||||
type = "A"
|
||||
ttl = 300
|
||||
managed_zone = var.dns_zone_name
|
||||
rrdatas = [google_compute_address.drb.address]
|
||||
resource "google_project_iam_member" "drb_firestore" {
|
||||
project = var.project_id
|
||||
role = "roles/datastore.user"
|
||||
member = local.compute_sa
|
||||
}
|
||||
|
||||
resource "google_project_iam_member" "drb_gcs" {
|
||||
project = var.project_id
|
||||
role = "roles/storage.objectAdmin"
|
||||
member = local.compute_sa
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Firestore database — import existing, manages schema/settings going forward
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
import {
|
||||
id = "projects/${var.project_id}/databases/${var.firestore_database}"
|
||||
to = google_firestore_database.c2
|
||||
}
|
||||
|
||||
resource "google_firestore_database" "c2" {
|
||||
project = var.project_id
|
||||
name = var.firestore_database
|
||||
location_id = var.firestore_location
|
||||
type = "FIRESTORE_NATIVE"
|
||||
|
||||
# Prevent accidental deletion of the live database
|
||||
deletion_policy = "DELETE"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GCS bucket — audio recordings. Import existing bucket.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
import {
|
||||
id = var.audio_bucket_name
|
||||
to = google_storage_bucket.audio
|
||||
}
|
||||
|
||||
resource "google_storage_bucket" "audio" {
|
||||
project = var.project_id
|
||||
name = var.audio_bucket_name
|
||||
location = var.audio_bucket_location
|
||||
uniform_bucket_level_access = true
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# DNS — managed in AWS Route 53 (cusano.net is there).
|
||||
# After terraform apply, add these A records in Route 53:
|
||||
# app.drb.cusano.net → server_ip output
|
||||
# api.drb.cusano.net → server_ip output
|
||||
# Or use a single wildcard: *.drb.cusano.net → server_ip
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user