Terraform files
Find a file
2026-07-18 13:49:38 +02:00
Claude test syntax fix 2026-07-13 16:22:04 +02:00
Claude_test added talos configuration 2026-07-18 13:49:38 +02:00
.gitignore Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00
butane.yaml.tftpl Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00
main.tf Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00
README.md Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00
terraform.tfvars.example Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00
variables.tf Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00
versions.tf Starting point Terraform voor Infra 2026-06-25 13:39:23 +02:00

Fedora CoreOS on Proxmox via Terraform (bpg/proxmox)

Provisions a Fedora CoreOS VM on Proxmox from the official proxmoxve image, with Ignition rendered from Butane in-process. The image always resolves to the latest build on your chosen stream, and existing VMs are never rebuilt when a new build is published.

How it works

  1. data.http reads the Fedora CoreOS stream.json at plan time and pulls the latest proxmoxve qcow2 URL + checksum.
  2. proxmox_virtual_environment_download_file downloads it into Proxmox. decompression_algorithm = "zst" also transparently decompresses the .xz.
  3. ct_config transpiles butane.yaml.tftpl to Ignition; it's stored as a Proxmox snippet (uploaded over SSH).
  4. proxmox_virtual_environment_vm boots from the image. The proxmoxve platform reads the Ignition from the attached config drive (delivered as cloud-init user-data).
  5. lifecycle.ignore_changes = [disk[0].file_id] guarantees an upstream release can't trigger a rebuild of a running VM.

After first boot, Fedora CoreOS (Zincati) keeps the running OS updated on its own — Terraform's only job is the initial build.

Prerequisites in Proxmox (one-time)

  • API token for a dedicated user with VM/datastore privileges.
  • SSH access to the node for the token's user (snippet upload needs it). ssh { agent = true } uses your local ssh-agent.
  • On the snippet datastore (default local): enable the Snippets content type (Datacenter → Storage → select storage → Content).
  • On the image datastore (default local): ISO image content enabled (on by default).

Usage

cp terraform.tfvars.example terraform.tfvars   # then edit
# or: export PROXMOX_VE_API_TOKEN='terraform@pve!provider=...'

terraform init
terraform plan
terraform apply

Notes / troubleshooting

  • proxmoxve not found / null during plan: your stream/arch may not carry it yet. Check: curl -s https://builds.coreos.fedoraproject.org/streams/stable.json | jq '.architectures.x86_64.artifacts.proxmoxve'
  • wrong file extension on download: the .img filename already works around this; it affects PVE older than 8.4.
  • Holding a node at a specific OS version (compliance, etc.) is a Zincati concern, not an image-pinning one — configure the Zincati update strategy in Butane rather than trying to control it from Terraform.
  • If decompression_algorithm = "zst" ever fails on the .xz in your PVE version, the fallback is to unxz the image locally and upload it with proxmox_virtual_environment_file (content_type = "iso") instead.