From 645b1a003c391b348d2f1c2e04ba73c2f575fbda Mon Sep 17 00:00:00 2001 From: Kristian Klausen Date: Fri, 28 Jul 2023 19:13:55 +0200 Subject: [PATCH] Add small script to fetch SSH keys from the EC2 metadata service This is meant to be used in the Hetzner cloud sandbox project, so SSH keys can be injected when a new VM is created from e.g. a CI pipeline, so that the CI pipeline can SSH to the newly created VM. The EC2 metadata service is used over the Hetzner metadata service, as it is supported by more providers (including Hetzner). --- README.md | 2 +- packer/archlinux.pkr.hcl | 12 +++++++++++- roles/install_arch/files/ec2-public-keys | 18 ++++++++++++++++++ .../install_arch/files/ec2-public-keys.service | 13 +++++++++++++ roles/install_arch/tasks/main.yml | 10 +++++++++- 5 files changed, 52 insertions(+), 3 deletions(-) create mode 100755 roles/install_arch/files/ec2-public-keys create mode 100644 roles/install_arch/files/ec2-public-keys.service diff --git a/README.md b/README.md index 7ab03624..976fda85 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ This will take some time after which a new snapshot will have been created on th For the sandbox project please run - packer build -var $(misc/get_key.py misc/vaults/vault_hetzner.yml hetzner_cloud_sandbox_infrastructure_api_key --format env | sed 's/_sandbox_infrastructure//') packer/archlinux.pkr.hcl + packer build -var $(misc/get_key.py misc/vaults/vault_hetzner.yml hetzner_cloud_sandbox_infrastructure_api_key --format env | sed 's/_sandbox_infrastructure//') -var install_ec2_public_keys_service=true packer/archlinux.pkr.hcl #### Note about terraform diff --git a/packer/archlinux.pkr.hcl b/packer/archlinux.pkr.hcl index 4acbf0f6..0986b568 100644 --- a/packer/archlinux.pkr.hcl +++ b/packer/archlinux.pkr.hcl @@ -18,6 +18,11 @@ variable "hetzner_cloud_api_key" { sensitive = true } +variable "install_ec2_public_keys_service" { + type = bool + default = false +} + # https://www.packer.io/docs/templates/hcl_templates/blocks/source source "hcloud" "rescue" { image = "ubuntu-22.04" @@ -40,6 +45,11 @@ build { host_alias = "packer-base-image" inventory_directory = "." playbook_file = "playbooks/tasks/install_arch.yml" - use_proxy = false + extra_arguments = [ + "--extra-vars", jsonencode({ + install_ec2_public_keys_service : var.install_ec2_public_keys_service + }) + ] + use_proxy = false } } diff --git a/roles/install_arch/files/ec2-public-keys b/roles/install_arch/files/ec2-public-keys new file mode 100755 index 00000000..d7d538c8 --- /dev/null +++ b/roles/install_arch/files/ec2-public-keys @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import os +from pathlib import Path + +import requests + +data = requests.get("http://169.254.169.254/2009-04-04/meta-data/public-keys") +data.raise_for_status() + +path = Path("/root/.ssh/authorized_keys") +path.parent.mkdir(mode=0o700, exist_ok=True) +os.chmod(path.parent, 0o700) + +with open(path, "w") as file: + for key in data.json(): + file.write(f"{key}\n") +os.chmod(path, 0o600) diff --git a/roles/install_arch/files/ec2-public-keys.service b/roles/install_arch/files/ec2-public-keys.service new file mode 100644 index 00000000..99d092bf --- /dev/null +++ b/roles/install_arch/files/ec2-public-keys.service @@ -0,0 +1,13 @@ +[Unit] +Description=Fetch SSH public keys from the metadata service +Before=sshd.service +After=systemd-networkd-wait-online.service +ConditionFirstBoot=yes + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/ec2-public-keys + +[Install] +WantedBy=multi-user.target diff --git a/roles/install_arch/tasks/main.yml b/roles/install_arch/tasks/main.yml index c9b8696f..2bd526a3 100644 --- a/roles/install_arch/tasks/main.yml +++ b/roles/install_arch/tasks/main.yml @@ -171,6 +171,13 @@ - name: Setup pacman-init.service on first boot copy: src=pacman-init.service dest=/mnt/etc/systemd/system/ owner=root group=root mode=0644 +- name: Setup ec2-public-keys on first boot + copy: src={{ item.src }} dest=/mnt/{{ item.dest }} owner=root group=root mode={{ item.mode }} + loop: + - {src: ec2-public-keys, dest: /usr/local/bin/, mode: 755} + - {src: ec2-public-keys.service, dest: /etc/systemd/system/, mode: 644} + when: install_ec2_public_keys_service | default(false) + - name: Remove generated keyring in the installation process file: path=/mnt/etc/pacman.d/gnupg state=absent @@ -178,7 +185,7 @@ file: path=/mnt/etc/machine-id state=absent - name: Enable services inside chroot - command: chroot /mnt systemctl enable sshd systemd-networkd systemd-resolved fstrim.timer pacman-init + command: chroot /mnt systemctl enable sshd systemd-networkd systemd-resolved fstrim.timer pacman-init {{ 'ec2-public-keys' if install_ec2_public_keys_service | default(false) }} register: chroot_systemd_services changed_when: "chroot_systemd_services.rc == 0" @@ -187,6 +194,7 @@ name: root_ssh vars: root_ssh_directory: /tmp/root.x86_64/mnt/root/.ssh + when: not install_ec2_public_keys_service | default(false) - name: Configure sshd template: src=sshd_config.j2 dest=/mnt/etc/ssh/sshd_config owner=root group=root mode=0644