From 1fab179066dabbd6586fbed1b4bb51baf9ed2c6c Mon Sep 17 00:00:00 2001 From: Tobias Manske Date: Thu, 14 Jul 2022 02:56:08 +0200 Subject: [PATCH] Hetzner Cloud Terraform setup --- restore-tests/.gitignore | 67 ++++++++++++++++ restore-tests/Makefile | 4 + restore-tests/ansible.tf | 11 +++ restore-tests/configure.bu | 7 ++ restore-tests/ignition.tf | 9 +++ restore-tests/main.tf | 88 ++++++++++++++++++++++ restore-tests/outputs.tf | 3 + restore-tests/setup.ign | 1 + restore-tests/templates/ansible.ign.tpl | 1 + restore-tests/templates/inventory.yaml.tpl | 12 +++ restore-tests/variables.tf | 49 ++++++++++++ restore-tests/versions.tf | 24 ++++++ 12 files changed, 276 insertions(+) create mode 100644 restore-tests/.gitignore create mode 100644 restore-tests/Makefile create mode 100644 restore-tests/ansible.tf create mode 100644 restore-tests/configure.bu create mode 100644 restore-tests/ignition.tf create mode 100644 restore-tests/main.tf create mode 100644 restore-tests/outputs.tf create mode 120000 restore-tests/setup.ign create mode 100644 restore-tests/templates/ansible.ign.tpl create mode 100644 restore-tests/templates/inventory.yaml.tpl create mode 100644 restore-tests/variables.tf create mode 100644 restore-tests/versions.tf diff --git a/restore-tests/.gitignore b/restore-tests/.gitignore new file mode 100644 index 0000000..71625f7 --- /dev/null +++ b/restore-tests/.gitignore @@ -0,0 +1,67 @@ +.envrc +# Created by https://www.toptal.com/developers/gitignore/api/terraform,vim,nvim,ansible +# Edit at https://www.toptal.com/developers/gitignore?templates=terraform,vim,ansible + +### Ansible ### +*.retry + +### Terraform ### +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +# End of https://www.toptal.com/developers/gitignore/api/terraform,vim,nvim,ansible +artifacts/ +*.hcl diff --git a/restore-tests/Makefile b/restore-tests/Makefile new file mode 100644 index 0000000..0b1a694 --- /dev/null +++ b/restore-tests/Makefile @@ -0,0 +1,4 @@ +all: artifacts/release/coreos-installer + +artifacts/release/coreos-installer: + docker run --rm -v "${PWD}/artifacts:/artifacts" clux/muslrust:stable cargo install --bin=coreos-installer --target=x86_64-unknown-linux-musl --root=/artifacts coreos-installer --force diff --git a/restore-tests/ansible.tf b/restore-tests/ansible.tf new file mode 100644 index 0000000..7765edb --- /dev/null +++ b/restore-tests/ansible.tf @@ -0,0 +1,11 @@ +resource "local_file" "inventory" { + filename = "${var.files_dir}/inventory.yaml" + content = templatefile( + "${path.module}/templates/inventory.yaml.tpl", + { + server_under_test_ip = hcloud_server.under_test.ipv4_address, + server_under_test_hostname = hcloud_server.under_test.name, + ssh_private_key_file = local_sensitive_file.ssh_private_key.filename + } + ) +} diff --git a/restore-tests/configure.bu b/restore-tests/configure.bu new file mode 100644 index 0000000..703b9c3 --- /dev/null +++ b/restore-tests/configure.bu @@ -0,0 +1,7 @@ +variant: fcos +version: 1.4.0 +ignition: + config: + merge: + - local: ./artifacts/ansible.ign + - local: ./setup.ign diff --git a/restore-tests/ignition.tf b/restore-tests/ignition.tf new file mode 100644 index 0000000..128cb9e --- /dev/null +++ b/restore-tests/ignition.tf @@ -0,0 +1,9 @@ +resource "local_file" "ignition" { + filename = "${var.files_dir}/ansible.ign" + content = templatefile( + "${path.module}/templates/ansible.ign.tpl", + { + ssh_public_key = chomp(one(tls_private_key.root[*].public_key_openssh)) + } + ) +} diff --git a/restore-tests/main.tf b/restore-tests/main.tf new file mode 100644 index 0000000..00c011d --- /dev/null +++ b/restore-tests/main.tf @@ -0,0 +1,88 @@ +provider "hcloud" { + token = var.hcloud_token +} + +resource "tls_private_key" "root" { + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "hcloud_ssh_key" "this" { + name = var.ssh_key_name + public_key = one(tls_private_key.root[*].public_key_openssh) +} + +resource "local_sensitive_file" "ssh_private_key" { + filename = "${var.files_dir}/id_rsa" + file_permission = "0600" + directory_permission = "0755" + content = one(tls_private_key.root[*].private_key_pem) +} + +resource "hcloud_server" "under_test" { + name = var.hcloud_server_name + labels = { "os" = "coreos" } + + server_type = "cx31" + datacenter = var.hcloud_server_datacenter + + # Image is ignored, as we boot into rescue mode, but is a required field + image = "fedora-36" + rescue = "linux64" + ssh_keys = concat(hcloud_ssh_key.this[*].name, var.ssh_extra_key_names) + + + connection { + host = hcloud_server.under_test.ipv4_address + timeout = "5m" + private_key = file(local_sensitive_file.ssh_private_key.filename) + # Root is the available user in rescue mode + user = "root" + } + + provisioner "local-exec" { + command = "butane --pretty --strict -d . configure.bu > ${var.files_dir}/configure.ign" + } + + + # Copy Ignition config to server + provisioner "file" { + content = file("${var.files_dir}/configure.ign") + destination = "/root/setup.ign" + } + + provisioner "file" { + source = "${path.module}/artifacts/bin/coreos-installer" + destination = "/usr/local/bin/coreos-installer" + } + + # Install Fedora CoreOS in rescue mode + provisioner "remote-exec" { + inline = [ + "set -x", + "set -e", + # "apt update", + # "apt install -y cargo", + # "cargo install coreos-installer", + "chmod 755 /usr/local/bin/coreos-installer", + # Download and install Fedora CoreOS to /dev/sda + "coreos-installer install /dev/sda -i /root/setup.ign", + "shutdown -r now" + ] + } + + # # Configure CoreOS after installation + # provisioner "remote-exec" { + # connection { + # host = hcloud_server.under_test.ipv4_address + # timeout = "1m" + # agent = true + # user = "core" + # } + # + # inline = [ + # "sudo hostnamectl set-hostname ${hcloud_server.under_test.name}" + # # Add additional commands if needed + # ] + # } +} diff --git a/restore-tests/outputs.tf b/restore-tests/outputs.tf new file mode 100644 index 0000000..d9219cd --- /dev/null +++ b/restore-tests/outputs.tf @@ -0,0 +1,3 @@ +output "server_under_test_ip" { + value = hcloud_server.under_test.ipv4_address +} diff --git a/restore-tests/setup.ign b/restore-tests/setup.ign new file mode 120000 index 0000000..ed1ff8e --- /dev/null +++ b/restore-tests/setup.ign @@ -0,0 +1 @@ +../coreos-config/setup.ign \ No newline at end of file diff --git a/restore-tests/templates/ansible.ign.tpl b/restore-tests/templates/ansible.ign.tpl new file mode 100644 index 0000000..f50b426 --- /dev/null +++ b/restore-tests/templates/ansible.ign.tpl @@ -0,0 +1 @@ +{"ignition":{"version":"3.0.0"},"passwd":{"users":[{"name":"core","sshAuthorizedKeys":["${ssh_public_key}"]}]}} diff --git a/restore-tests/templates/inventory.yaml.tpl b/restore-tests/templates/inventory.yaml.tpl new file mode 100644 index 0000000..d6535f4 --- /dev/null +++ b/restore-tests/templates/inventory.yaml.tpl @@ -0,0 +1,12 @@ +--- +all: + hosts: + ${server_under_test_hostname}: + ansible_host: ${server_under_test_ip} + ansible_user: core + ansible_ssh_private_key_file: ${ssh_private_key_file} + network_interface: ens3 + children: + unprovisioned: + hosts: + ${server_under_test_hostname}: null diff --git a/restore-tests/variables.tf b/restore-tests/variables.tf new file mode 100644 index 0000000..c36fa54 --- /dev/null +++ b/restore-tests/variables.tf @@ -0,0 +1,49 @@ +variable "hcloud_token" { + description = "Hetzner Cloud API Token" + type = string +} + +variable "ssh_key_name" { + description = "Name of your public key to identify at Hetzner Cloud portal" + type = string + default = "restore_test_key" +} + +variable "ssh_extra_key_names" { + description = "Name of additional public keys installed on the system" + type = list(any) + default = [ + "zahnrad" + ] +} + +variable "files_dir" { + description = "Directory to store artifacts" + type = string + default = "artifacts/" +} + +variable "hcloud_server_type" { + description = "vServer type name, lookup via `hcloud server-type list`" + type = string + default = "cx11" +} + +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 = "www1" +} + +# Update version to the latest release of fcct +variable "tools_fcct_version" { + description = "See https://github.com/coreos/fcct/releases for available versions" + type = string + default = "0.6.0" +} diff --git a/restore-tests/versions.tf b/restore-tests/versions.tf new file mode 100644 index 0000000..d54181a --- /dev/null +++ b/restore-tests/versions.tf @@ -0,0 +1,24 @@ +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = ">= 1.32.0" + } + + local = { + source = "hashicorp/local" + version = ">= 2.1.0" + } + + tls = { + source = "hashicorp/tls" + version = ">= 3.1.0" + } + + ignition = { + source = "community-terraform-providers/ignition" + version = ">= 2.1.0" + } + } +} +