iac/terraform
Sergei Poljanski f912e9d955 terraform: require hcloud provider 1.70
With provider 1.54 the plan replaces both servers. Hetzner stopped
returning a server's datacenter, the old provider derived the location
from it, and a location that reads back empty differs from "hel1",
which forces replacement. Only prevent_destroy stood in the way.

Provider 1.70.2 reads the location properly: the same plan then shows
the two firewall updates and nothing else. The lock file is not
tracked, so raise the version constraint to keep the old provider out.

Run terraform init -upgrade once in existing checkouts.

Assisted-by: Claude:fable-5-2
2026-11-12 16:01:58 +04:00
..
cloud-init terraform: never replace a running server 2026-11-12 06:47:08 +04:00
.gitignore terraform 2025-11-01 13:43:31 +02:00
dns.tf ansible 2025-11-01 22:46:38 +02:00
firewall.tf terraform: match the servers; open only ports in use 2026-11-12 15:52:29 +04:00
keys.tf terraform 2025-11-01 13:43:31 +02:00
outputs.tf terraform 2025-11-01 13:43:31 +02:00
providers.tf terraform: require hcloud provider 1.70 2026-11-12 16:01:58 +04:00
README.md terraform: match the servers; open only ports in use 2026-11-12 15:52:29 +04:00
s3.tf terraform 2025-11-01 13:43:31 +02:00
servers.tf terraform: match the servers; open only ports in use 2026-11-12 15:52:29 +04:00
terraform.tfvars.example terraform 2025-11-01 13:43:31 +02:00
variables.tf terraform 2025-11-01 13:43:31 +02:00
vpc.tf terraform 2025-11-01 13:43:31 +02:00

ASXP.IO Infrastructure

Hetzner Cloud infrastructure managed via Terraform.

Servers

  • asxpio-ops (CX23: 2 vCPU, 4GB) - Traefik, Forgejo, app stacks
  • asxpio-services (CX43: 8 vCPU, 16GB) - CI runner, game servers, SillyTavern

Both have Hetzner daily backups plus delete and rebuild protection.

Both servers carry prevent_destroy and ignore changes to user_data, image and ssh_keys: cloud-init only runs at first boot, and hcloud would otherwise replace a running server when those change. Edits to cloud-init/*.yaml therefore describe a rebuild, not the live machine; day-to-day configuration is in ../ansible.

Storage (S3-compatible)

Terraform State:

  • asxpio-terraform-main (hel1)
  • asxpio-terraform-repl (fsn1)

Backups:

  • asxpio-backups-main (hel1)
  • asxpio-backups-repl (fsn1)

Immich (buckets kept, service not running):

  • asxpio-immich-main (hel1)
  • asxpio-immich-repl (fsn1)

Network

  • VPC: 10.10.0.0/20
  • WireGuard VPN: 10.20.0.0/24
  • IPv4 + IPv6 enabled

Cost

Item Monthly
ops CX23 €3.71
services CX43 €11.15
IPv4 (2x) €1.24
S3 (1TB) €6.19
S3 1TB Traffic €1.24
Total €22.29

Setup

1. Initialize

terraform init

2. Configure secrets

Edit terraform.tfvars:

hcloud_token = "your-token"
s3_access_key = "your-key"
s3_secret_key = "your-secret"
s3_endpoint_hel1 = "hel1.your-objectstorage.com"
s3_endpoint_fsn1 = "fsn1.your-objectstorage.com"

3. Deploy

terraform plan
terraform apply

4. Enable S3 backend (optional)

After buckets are created:

# Set credentials
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"

# Or use ~/.aws/credentials file
mkdir -p ~/.aws
cat > ~/.aws/credentials <<EOF
[default]
aws_access_key_id = your-key
aws_secret_access_key = your-secret
EOF

# Uncomment backend in providers.tf
# Then migrate state
terraform init -migrate-state

DNS Management

Current: Managed manually via hcloud CLI

Zones: asxp.io (61604), czsk.it (61606), childfr.ee (61605)

TODO: Migrate to Terraform-managed DNS when provider v1.54.0+ is available:

# Upgrade provider in providers.tf
hcloud = {
  source  = "hetznercloud/hcloud"
  version = "~> 1.54"
}

# Import existing zones
terraform import hcloud_zone.asxp_io 61604
terraform import hcloud_zone.czsk_it 61606
terraform import hcloud_zone.childfr_ee 61605

# Example DNS resource
resource "hcloud_zone" "asxp_io" {
  name = "asxp.io"
  mode = "primary"
  labels = {
    managed_by = "terraform"
  }
}

resource "hcloud_zone_rrset" "apex_a" {
  zone = hcloud_zone.asxp_io.name
  name = "@"
  type = "A"
  records = [
    { value = "95.217.19.240", comment = "ops-server" },
  ]
}

See: https://github.com/hetznercloud/terraform-provider-hcloud/releases/tag/v1.54.0

Files

  • servers.tf - Server definitions + cloud-init
  • s3.tf - S3 buckets (6 total)
  • vpc.tf - Private network
  • firewall.tf - Security rules
  • dns.tf - DNS docs (manual management)
  • keys.tf - SSH keys
  • cloud-init/*.yaml - Server provisioning