Created
June 17, 2025 09:47
-
-
Save stephankoelle/271c98b5615db6b8c55bda418b98d8da to your computer and use it in GitHub Desktop.
Terraform for Hetzner Cloud Fedora CoreOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Alter: | |
| # hcloud_server_type | |
| # ssh_public_key_file | |
| # ssh_private_key_file | |
| # versions.tf | |
| terraform { | |
| required_providers { | |
| hcloud = { | |
| source = "hetznercloud/hcloud" | |
| } | |
| } | |
| required_version = ">= 0.13" | |
| } | |
| #=========================================== | |
| #config.yaml : | |
| # For docs, see: https://coreos.github.io/butane/specs/ | |
| variant: fcos | |
| version: 1.5.0 | |
| passwd: | |
| users: | |
| - name: core | |
| groups: | |
| - docker | |
| - wheel | |
| - sudo | |
| ssh_authorized_keys: | |
| # Will be replaced by terraform script | |
| - $ssh_public_key | |
| #=========================================== | |
| # main.tf | |
| #https://community.hetzner.com/tutorials/howto-hcloud-terraform-fedora-coreos | |
| #https://releases.hashicorp.com/terraform/1.8.4/terraform_1.8.4_linux_amd64.zip | |
| #https://console.hetzner.cloud/projects/2938711/security/tokens | |
| # | |
| #/terraform-coreos (main)$ /tmp/terraform init | |
| #/terraform-coreos (main)$ /tmp/terraform apply | |
| #### | |
| # Variables | |
| ## | |
| variable "hcloud_token" { | |
| description = "Hetzner Cloud API Token" | |
| type = string | |
| } | |
| variable "ssh_public_key_file" { | |
| description = "Local path to your public key" | |
| type = string | |
| default = "~/.ssh/id_rsa_hetzner.pub" | |
| } | |
| variable "ssh_private_key_file" { | |
| description = "Local path to your private key" | |
| type = string | |
| default = "~/.ssh/id_rsa_hetzner" | |
| } | |
| variable "ssh_public_key_name" { | |
| description = "Name of your public key to identify at Hetzner Cloud portal" | |
| type = string | |
| default = "My-SSH-Key" | |
| } | |
| variable "hcloud_server_type" { | |
| description = "vServer type name, lookup via `hcloud server-type list`" | |
| type = string | |
| default = "cax11" #11 #41 | |
| } | |
| variable "hcloud_server_datacenter" { | |
| description = "Desired datacenter location name, lookup via `hcloud datacenter list`" | |
| type = string | |
| default = "hel1-dc2" | |
| } | |
| variable "hcloud_server_name" { | |
| description = "Name of the server" | |
| type = string | |
| default = "plantpamper1" | |
| } | |
| # Update version to the latest release of Butane | |
| variable "tools_butane_version" { | |
| description = "See https://github.com/coreos/butane/releases for available versions" | |
| type = string | |
| default = "0.19.0" | |
| } | |
| #### | |
| # Infrastructure config | |
| ## | |
| provider "hcloud" { | |
| token = var.hcloud_token | |
| } | |
| resource "hcloud_ssh_key" "key" { | |
| name = var.ssh_public_key_name | |
| public_key = file(var.ssh_public_key_file) | |
| } | |
| resource "hcloud_server" "master" { | |
| name = var.hcloud_server_name | |
| labels = { "os" = "coreos" } | |
| server_type = var.hcloud_server_type | |
| datacenter = var.hcloud_server_datacenter | |
| # Image is ignored, as we boot into rescue mode, but is a required field | |
| image = "fedora-39" | |
| rescue = "linux64" | |
| ssh_keys = [hcloud_ssh_key.key.id] | |
| connection { | |
| host = self.ipv4_address | |
| timeout = "15m" | |
| private_key = file(var.ssh_private_key_file) | |
| # Root is the available user in rescue mode | |
| user = "root" | |
| } | |
| # Wait for the server to be available | |
| provisioner "local-exec" { | |
| command = "until nc -zv ${self.ipv4_address} 22; do sleep 5; done" | |
| } | |
| # Copy config.yaml and replace $ssh_public_key variable | |
| provisioner "file" { | |
| content = replace(file("config.yaml"), "$ssh_public_key", trimspace(file(var.ssh_public_key_file))) | |
| destination = "/root/config.yaml" | |
| } | |
| # Copy coreos-installer binary, as initramfs has not sufficient space to compile it in rescue mode | |
| #provisioner "file" { | |
| # source = "coreos-installer" | |
| # destination = "/usr/local/bin/coreos-installer" | |
| #} | |
| # Install Butane in rescue mode | |
| provisioner "remote-exec" { | |
| inline = [ | |
| "set -x", | |
| # Convert ignition yaml into json using Butane | |
| #"wget -O /usr/local/bin/butane 'https://github.com/coreos/butane/releases/download/v${var.tools_butane_version}/butane-x86_64-unknown-linux-gnu'", | |
| "wget -O /usr/local/bin/butane 'https://github.com/coreos/butane/releases/download/v${var.tools_butane_version}/butane-aarch64-unknown-linux-gnu'", | |
| "chmod +x /usr/local/bin/butane", | |
| "butane --strict < config.yaml > config.ign", | |
| # coreos-installer binary is copied, if you have sufficient RAM available, you can also uncomment the following | |
| # two lines and comment-out the `chmod +x` line, to build coreos-installer in rescue mode | |
| "apt-get install -y podman", | |
| # "cargo install coreos-installer", | |
| ##"apt-get install -y openssl libzstd-dev libssl-dev", | |
| #"mount /dev/sda1 /mnt/", | |
| "df -h; ls -la", | |
| "podman run --net=host --pull=always --privileged --rm -v /dev:/dev -v /run/udev:/run/udev -v .:/data -w /data quay.io/coreos/coreos-installer:release install /dev/sda -i config.ign", | |
| ##"mkdir /mnt/cargoinst", | |
| ##"export CARGO_HOME=/mnt/cargoinst", | |
| ##"export RUSTUP_HOME=/mnt/cargoinst", | |
| ##"curl https://sh.rustup.rs -sSf | sh -s -- -y", | |
| ##". /mnt/cargoinst/env", | |
| ##"export CARGO_HOME=/mnt/cargoinst", | |
| ##"export RUSTUP_HOME=/mnt/cargoinst", | |
| ##"cargo install --target-dir /mnt/cargoinst/ coreos-installer", | |
| ##"chmod +x /mnt/cargoinst/bin/coreos-installer", | |
| # Download and install Fedora CoreOS to /dev/sda | |
| ##"/mnt/cargoinst/bin/coreos-installer install /dev/sda -i /root/config.ign", | |
| # Exit rescue mode and boot into coreos | |
| "reboot" | |
| ] | |
| } | |
| # Wait for the server to be available | |
| provisioner "local-exec" { | |
| command = "until nc -zv ${self.ipv4_address} 22; do sleep 15; done" | |
| } | |
| # Configure CoreOS after installation | |
| provisioner "remote-exec" { | |
| connection { | |
| host = self.ipv4_address | |
| timeout = "1m" | |
| private_key = file(var.ssh_private_key_file) | |
| # This user is configured in config.yaml | |
| user = "core" | |
| } | |
| inline = [ | |
| "sudo hostnamectl set-hostname ${self.name}" | |
| # Add additional commands if needed | |
| ] | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment