boma/terraform/modules/hetzner_vm/main.tf

75 lines
1.8 KiB
Terraform
Raw Normal View History

# cloud-init: create the unprivileged `ansible` user with ubongo's key + sudo.
# (Mirrors the proxmox_vm module's user_account; Hetzner has no structured field.)
locals {
# Indentation matches the closing EOT (2 spaces) so `<<-` strips to column 0 —
# cloud-config requires `#cloud-config` as the first line with no leading space.
user_data = <<-EOT
#cloud-config
users:
- name: ansible
groups: [sudo]
sudo: "ALL=(ALL) NOPASSWD:ALL"
shell: /bin/bash
ssh_authorized_keys:
- ${var.ansible_ssh_pubkey}
package_update: true
packages:
- python3
EOT
}
resource "hcloud_ssh_key" "ansible" {
name = "${var.name}-ansible"
public_key = var.ansible_ssh_pubkey
}
resource "hcloud_firewall" "this" {
name = "${var.name}-fw"
# SSH from the control node only.
rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = var.ssh_admin_cidrs
}
# Public web (Caddy 80/443) + NetBird STUN/TURN (3478/udp) — only when public_web
# (ADR-024, M4). Host nftables stays catalog-driven (ADR-020).
dynamic "rule" {
for_each = var.public_web ? ["80", "443"] : []
content {
direction = "in"
protocol = "tcp"
port = rule.value
source_ips = ["0.0.0.0/0", "::/0"]
}
}
dynamic "rule" {
for_each = var.public_web ? ["3478"] : []
content {
direction = "in"
protocol = "udp"
port = rule.value
source_ips = ["0.0.0.0/0", "::/0"]
}
}
}
resource "hcloud_server" "this" {
name = var.name
server_type = var.server_type
location = var.location
image = var.image
ssh_keys = [hcloud_ssh_key.ansible.id]
user_data = local.user_data
firewall_ids = [hcloud_firewall.this.id]
labels = var.labels
public_net {
ipv4_enabled = true
ipv6_enabled = true
}
}