From a0ecbbe1bce672c854841f46c980d486064f2de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20T=C3=B6lle?= Date: Sat, 30 Mar 2024 17:01:00 +0100 Subject: [PATCH] feat: initial templates --- .gitignore | 1 + README.md | 52 +++++++++++++++++++++++++++ butane-oem.yaml | 41 ++++++++++++++++++++++ flatcar.pkr.hcl | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 butane-oem.yaml create mode 100644 flatcar.pkr.hcl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..15b16b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +ignition-*.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..75d85fe --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Build Flatcar Snapshots on Hetzner Cloud with Packer + +## Requirements + +- Hetzner Cloud API Token +- Packer +- Butane +- Hetzner Cloud CLI (`hcloud`) + +This only works on Flatcar > `3913.0.0`, as this version has the appropriate versions of `ignition` and `afterburn` that +add support for the Hetzner Cloud metadata service. + +## Building Snapshots + +```shell +$ git clone ... # TODO +$ export HCLOUD_TOKEN=... +$ packer init flatcar.pkr.hcl +$ butane butane-oem.yaml --pretty --strict --output=ignition-oem.json + +# This will build Snapshots for x86 and arm. If you only need one, you can add +# `--only=hcloud.x86` or `--only=hcloud.arm` to the `packer build` command. +$ packer build flatcar.pkr.hcl +# ... Takes a few minutes +==> Builds finished. The artifacts of successful builds are: +--> hcloud.x86: A snapshot was created: 'flatcar-alpha-x86' (ID: 157132241) +--> hcloud.arm: A snapshot was created: 'flatcar-alpha-arm' (ID: 157132252) + +$ hcloud image list --type=snapshot --selector=os=flatcar +ID TYPE NAME DESCRIPTION ARCHITECTURE IMAGE SIZE DISK SIZE CREATED DEPRECATED +157132241 snapshot - flatcar-alpha-x86 x86 0.47 GB 20 GB Sat Mar 30 16:48:22 CET 2024 - +157132252 snapshot - flatcar-alpha-arm arm 0.42 GB 40 GB Sat Mar 30 16:48:24 CET 2024 - +``` + +## Create a Sever + +You can now create a new server from the snapshot. Not every feature might automatically work, as the snapshot is +missing the functionality from [`hc-utils`](https://github.com/hetznercloud/hc-utils). Configuring SSH Keys and User +Data (Ignition) will work as expected. + +```shell +# Get ID of the most recent flatcar snapshot for x86 +$ SNAPSHOT_ID=$(hcloud image list --type=snapshot --selector=os=flatcar --architecture=x86 -o=columns=id -o noheader --sort=created:desc | head) + +# Create a new server +# If you have, you can specify an Ignition config with `--user-data-from-file ignition-user.json` +$ hcloud server create --name flatcar-test --image $SNAPSHOT_ID --type cx11 --ssh-key +# Takes a minute or two + +# Now you can login, the following is a helper that calls `ssh` with the public ipv4 address of the server +$ hcloud server ssh flatcar-test +``` diff --git a/butane-oem.yaml b/butane-oem.yaml new file mode 100644 index 0000000..0655e05 --- /dev/null +++ b/butane-oem.yaml @@ -0,0 +1,41 @@ +variant: flatcar +version: 1.1.0 + +systemd: + units: + - name: "coreos-metadata.service" + enabled: true + contents: | + [Unit] + Description=Flatcar Metadata Agent + After=nss-lookup.target + After=network-online.target + Wants=network-online.target + [Service] + Type=oneshot + Restart=on-failure + RemainAfterExit=yes + ExecStart=/usr/bin/coreos-metadata --cmdline --attributes=/run/metadata/flatcar + ExecStartPost=/usr/bin/sed --in-place "s/AFTERBURN/COREOS/g ; s/AWS/EC2/g ; s/GCP/GCE/g" /run/metadata/flatcar + ExecStartPost=/usr/bin/ln -fs /run/metadata/flatcar /run/metadata/coreos + [Install] + RequiredBy=system-config.target + Alias=afterburn.service + - name: "coreos-metadata-sshkeys@root.service" + enabled: true + - name: "coreos-metadata-hostname.service" + # The unit in initramfs has restrictive conditions on the OEM platform that do not include Hetzner + enabled: true + contents: | + [Unit] + Description=Flatcar Metadata Agent Hostname + After=coreos-metadata.service + Requires=coreos-metadata.service + [Service] + EnvironmentFile=/run/metadata/flatcar + Type=oneshot + Restart=on-failure + RemainAfterExit=yes + ExecStart=/usr/bin/hostnamectl hostname "${COREOS_COREOS_HETZNER_HOSTNAME}" + [Install] + RequiredBy=system-config.target diff --git a/flatcar.pkr.hcl b/flatcar.pkr.hcl new file mode 100644 index 0000000..1315c22 --- /dev/null +++ b/flatcar.pkr.hcl @@ -0,0 +1,93 @@ +packer { + required_plugins { + hcloud = { + source = "github.com/hetznercloud/hcloud" + version = "~> 1" + } + } +} + +variable "hcloud_token" { + type = string + default = "${env("HCLOUD_TOKEN")}" + sensitive = true +} + +variable "hcloud_server_type" { + type = map(string) + default = { + x86 = "cx11" + arm = "cax11" + } +} + +variable "flatcar_install_script" { + type = string + default = "https://raw.githubusercontent.com/flatcar/init/flatcar-master/bin/flatcar-install" +} + +variable "flatcar_channel" { + type = string + default = "alpha" +} + +locals { + hcloud_location = "fsn1" + hcloud_rescue = "linux64" + hcloud_initial_os = "ubuntu-22.04" + flatcar_oem_id = "hetzner" +} + +source "hcloud" "flatcar" { + token = var.hcloud_token + + image = local.hcloud_initial_os + location = local.hcloud_location + rescue = local.hcloud_rescue + + snapshot_labels = { + os = "flatcar" + "flatcar.channel" = var.flatcar_channel + } + + ssh_username = "root" +} + + +build { + source "hcloud.flatcar" { + name = "x86" + server_type = var.hcloud_server_type["x86"] + snapshot_name = "flatcar-${var.flatcar_channel}-x86" + } + + source "hcloud.flatcar" { + name = "arm" + server_type = var.hcloud_server_type["arm"] + snapshot_name = "flatcar-${var.flatcar_channel}-arm" + } + + provisioner "file" { + source = "ignition-oem.json" + destination = "/ignition.json" + } + + provisioner "shell" { + inline = [ + # Download script and dependencies + "apt-get update", + "apt-get -y install gawk", + "curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 ${var.flatcar_install_script}", + "chmod +x flatcar-install", + + # Install flatcar + "./flatcar-install -s -C ${var.flatcar_channel} -i /ignition.json", + + # Setup Kernel Parameters for OEM Platform + "mkdir /root/OEM", + "mount /dev/disk/by-label/OEM /root/OEM", + "echo 'set oem_id=${local.flatcar_oem_id}' > /root/OEM/grub.cfg", + "umount /root/OEM", + ] + } +}