hcloud replaces a server when user_data, image or ssh_keys change, and cloud-init only runs at first boot anyway. An edit to cloud-init, like adding a user, would therefore plan the destruction of a production machine. Ignore changes to those three attributes and set prevent_destroy on both servers, so cloud-init describes a rebuild and nothing else. Add user zerrtika to cloud-init to match the servers; the user was created on them by playbook 04. Assisted-by: Claude:fable-5-2 |
||
|---|---|---|
| .. | ||
| cloud-init | ||
| .gitignore | ||
| dns.tf | ||
| firewall.tf | ||
| keys.tf | ||
| outputs.tf | ||
| providers.tf | ||
| README.md | ||
| s3.tf | ||
| servers.tf | ||
| terraform.tfvars.example | ||
| variables.tf | ||
| vpc.tf | ||
ASXP.IO Infrastructure
Hetzner Cloud infrastructure managed via Terraform.
Servers
- asxpio-ops (2 vCPU, 4GB) - Traefik, Forgejo, app stacks
- asxpio-services (CX43: 8 vCPU, 16GB) - CI runner, game servers, SillyTavern
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 | €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-inits3.tf- S3 buckets (6 total)vpc.tf- Private networkfirewall.tf- Security rulesdns.tf- DNS docs (manual management)keys.tf- SSH keyscloud-init/*.yaml- Server provisioning