139 lines
3.5 KiB
Terraform
139 lines
3.5 KiB
Terraform
terraform {
|
|
required_version = ">= 1.6"
|
|
required_providers {
|
|
google = {
|
|
source = "hashicorp/google"
|
|
version = "~> 5.0"
|
|
}
|
|
}
|
|
|
|
# Store state in GCS — create the bucket manually once before first apply
|
|
backend "gcs" {
|
|
bucket = "drb-tf-state"
|
|
prefix = "drb/state"
|
|
}
|
|
}
|
|
|
|
provider "google" {
|
|
project = var.project_id
|
|
region = var.region
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Static external IP
|
|
# ---------------------------------------------------------------------------
|
|
|
|
resource "google_compute_address" "drb" {
|
|
name = "drb-server-ip"
|
|
region = var.region
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Firewall rules
|
|
# ---------------------------------------------------------------------------
|
|
|
|
resource "google_compute_firewall" "allow_web" {
|
|
name = "drb-allow-web"
|
|
network = "default"
|
|
|
|
allow {
|
|
protocol = "tcp"
|
|
ports = ["80", "443"]
|
|
}
|
|
|
|
source_ranges = ["0.0.0.0/0"]
|
|
target_tags = ["drb-server"]
|
|
}
|
|
|
|
resource "google_compute_firewall" "allow_ssh" {
|
|
name = "drb-allow-ssh"
|
|
network = "default"
|
|
|
|
allow {
|
|
protocol = "tcp"
|
|
ports = ["22"]
|
|
}
|
|
|
|
# Restrict SSH to your IP(s) and Gitea runner IP
|
|
source_ranges = var.allowed_ssh_cidrs
|
|
target_tags = ["drb-server"]
|
|
}
|
|
|
|
# MQTT is NOT exposed externally — edge nodes connect via WireGuard (see below)
|
|
# If you need to temporarily allow direct MQTT access for testing, uncomment and
|
|
# restrict source_ranges to your node IPs.
|
|
#
|
|
# resource "google_compute_firewall" "allow_mqtt" {
|
|
# name = "drb-allow-mqtt"
|
|
# network = "default"
|
|
# allow {
|
|
# protocol = "tcp"
|
|
# ports = ["8883"] # TLS MQTT, not 1883
|
|
# }
|
|
# source_ranges = ["YOUR_NODE_CIDR"]
|
|
# target_tags = ["drb-server"]
|
|
# }
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Compute Engine VM
|
|
# ---------------------------------------------------------------------------
|
|
|
|
resource "google_compute_instance" "drb_server" {
|
|
name = "drb-server"
|
|
machine_type = var.machine_type
|
|
zone = var.zone
|
|
tags = ["drb-server"]
|
|
|
|
boot_disk {
|
|
initialize_params {
|
|
image = "debian-cloud/debian-12"
|
|
size = 30 # GB — enough for Docker images + mosquitto data
|
|
type = "pd-balanced"
|
|
}
|
|
}
|
|
|
|
network_interface {
|
|
network = "default"
|
|
access_config {
|
|
nat_ip = google_compute_address.drb.address
|
|
}
|
|
}
|
|
|
|
metadata = {
|
|
ssh-keys = "${var.ssh_user}:${var.ssh_public_key}"
|
|
}
|
|
|
|
# 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
|
|
service_account {
|
|
scopes = ["cloud-platform"]
|
|
}
|
|
|
|
lifecycle {
|
|
# Prevent Terraform from destroying + recreating on metadata changes
|
|
ignore_changes = [metadata_startup_script]
|
|
}
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Cloud DNS records
|
|
# ---------------------------------------------------------------------------
|
|
|
|
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]
|
|
}
|
|
|
|
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]
|
|
}
|