infra/burst/workers/hetzner/main.tf (2182 bytes)
1 # Burst workers on Hetzner Cloud: one server for each entry of var.workers. The 2 # burst controller (python -m tools.burst) writes var.workers and applies this 3 # when the set changes; do not apply it by hand while burst mode is on. 4 5 terraform { 6 required_version = ">= 1.9" 7 required_providers { 8 hcloud = { 9 source = "hetznercloud/hcloud" 10 version = "~> 1.69" 11 } 12 } 13 backend "local" {} 14 } 15 16 # Reads HCLOUD_TOKEN. Keep the burst servers in a Hetzner project of their own. 17 provider "hcloud" {} 18 19 data "terraform_remote_state" "state" { 20 backend = "local" 21 config = { 22 path = var.state_file 23 } 24 } 25 26 locals { 27 state = data.terraform_remote_state.state.outputs.worker 28 } 29 30 # No inbound rule: Hetzner then drops all inbound traffic. A worker only 31 # connects out (the SSH tunnel, the bucket, the package indexes). 32 resource "hcloud_firewall" "worker" { 33 name = "subplz-burst-worker" 34 } 35 36 resource "hcloud_server" "worker" { 37 for_each = var.workers 38 39 name = each.key 40 server_type = each.value.machine 41 location = each.value.zone 42 image = "debian-12" 43 firewall_ids = [hcloud_firewall.worker.id] 44 labels = { 45 role = "subplz-burst-worker" 46 } 47 48 user_data = templatefile("${path.module}/../../cloud-init.yaml.tftpl", { 49 name = each.key 50 ref = each.value.ref 51 subplz_spec = var.subplz_spec 52 threads = var.threads 53 idle_checks = var.idle_checks 54 constraints = file("${path.module}/../../worker-constraints.txt") 55 web_server_ip = local.state.web_server_ip 56 ssh_port = local.state.ssh_port 57 known_hosts = local.state.known_hosts 58 tunnel_private_key = local.state.tunnel_private_key 59 database_url = local.state.database_url 60 redis_url = local.state.redis_url 61 bucket = local.state.bucket 62 s3_prefix = local.state.s3_prefix 63 storage_env = local.state.storage_env 64 }) 65 66 # A change of these would replace a server, and kill the job on it. New 67 # workers get the new values; the controller replaces old ones when idle. 68 lifecycle { 69 ignore_changes = [user_data, image] 70 } 71 }