terraform { required_providers { hcloud = { source = "hetznercloud/hcloud" version = "~> 1.0" } } } provider "hcloud" { token = var.hcloud_token } variable "hcloud_token" { description = "Hetzner Cloud API Token" type = string sensitive = true } variable "ssh_public_key_path" { description = "Path to SSH public key" type = string } variable "ssh_private_key_path" { description = "Path to SSH private key" type = string } # variable "acme_email" { # description = "Email for Let's Encrypt certificates" # type = string # default = "engineering@fourlights.nl" # } variable "image" { type = string default = "ubuntu-24.04" } variable "location" { type = string default = "nbg1" } variable "server_type" { type = string default = "cx22" } variable "datacenter" { type = string default = "nbg1-dc3" } variable "name" { type = string default = "enterprise" } variable "zone" { type = string default = "fourlights.dev" } variable "hdns_token" {} variable "ghcr_username" {} variable "ghcr_token" {} locals { acme_email = "engineering+${var.name}@fourlights.nl" } resource "hcloud_primary_ip" "server_ipv4" { name = "${var.name}-ipv4" type = "ipv4" assignee_type = "server" datacenter = var.datacenter auto_delete = false } resource "hcloud_primary_ip" "server_ipv6" { name = "${var.name}-ipv6" type = "ipv6" assignee_type = "server" datacenter = var.datacenter auto_delete = false } module "dns" { source = "./dns" hdns_token = var.hdns_token zone = var.zone ipv4_address = hcloud_primary_ip.server_ipv4.ip_address ipv6_address = hcloud_primary_ip.server_ipv6.ip_address root = "visualworkplace" } # SSH Key resource "hcloud_ssh_key" "default" { name = "terraform-key" public_key = file(var.ssh_public_key_path) } # Persistent volume for MinIO resource "hcloud_volume" "minio_data" { name = "minio-data" size = 50 location = var.location } # Server with comprehensive cloud-init setup resource "hcloud_server" "server" { name = var.name image = var.image server_type = var.server_type location = var.location ssh_keys = [hcloud_ssh_key.default.id] user_data = templatefile("${path.module}/cloud-init.yml", { acme_email = local.acme_email ssh_public_key = hcloud_ssh_key.default.public_key, ghcr_username = var.ghcr_username ghcr_token = var.ghcr_token }) public_net { ipv4_enabled = true ipv6_enabled = true ipv4 = hcloud_primary_ip.server_ipv4.id ipv6 = hcloud_primary_ip.server_ipv6.id } lifecycle { replace_triggered_by = [ # This ensures server gets rebuilt when user_data changes ] } } # Attach volume resource "hcloud_volume_attachment" "minio_data" { volume_id = hcloud_volume.minio_data.id server_id = hcloud_server.server.id automount = false # We'll handle mounting in cloud-init } # Wait for cloud-init to complete resource "null_resource" "wait_for_cloud_init" { depends_on = [hcloud_server.server] connection { type = "ssh" host = hcloud_server.server.ipv4_address user = "fourlights" timeout = "10m" agent = true agent_identity = var.ssh_private_key_path } provisioner "remote-exec" { inline = [ "echo 'Waiting for cloud-init to complete...'", "cloud-init status --wait", "echo 'Cloud-init completed successfully'" ] } } output "server_ip" { value = hcloud_server.server.ipv4_address } output "haproxy_stats" { value = "http://${hcloud_server.server.ipv4_address}:8404/stats" } output "haproxy_api" { value = "http://${hcloud_server.server.ipv4_address}:5555" } output "server_domain" { value = module.dns.server_domain } output "installed" { value = true depends_on = [null_resource.wait_for_cloud_init] }