hetzner-alpine-k8s/alpine-on-hetzner/playbook.yml
Knut Ahlers d2c0a1406a
Replace volume dev-paths with UUIDs
in order to make the machines reboot-safe even when hcloud volumes are
attached at the time of boot and the device numbers are assigned in
another order than before which would break the reboot when using
`/dev/sda2` as a root volume

Signed-off-by: Knut Ahlers <knut@ahlers.me>
2023-11-10 13:31:48 +01:00

193 lines
5.8 KiB
YAML

---
- name: prepare environment
hosts: localhost
tasks:
- name: cache apk tools
get_url:
url: "{{ apk_tools_url }}"
dest: /cache/apk.static
checksum: "{{ apk_tools_checksum }}"
- name: configure alpine
hosts: all
gather_facts: false
vars:
chroot_directory: /mnt
root_device_path: "/dev/sda"
tasks:
- name: deploy apk-tools to rescue system
copy:
src: /cache/apk.static
dest: apk
mode: ug=rwx,o=r
- name: "zap all partitions on {{ root_device_path }} and create GPT table"
shell: "sgdisk --zap-all {{ root_device_path }}"
- name: "create boot partition {{ root_device_path }}-boot"
shell: "sgdisk -g -n1:0:{{ boot_size }} -t1:8300 -c1:boot -A1:set:2 {{ root_device_path }}"
- name: "create root partition {{ root_device_path }}-root"
shell: "sgdisk -g -n2:0:{{ root_size }} -t2:8300 -c2:root {{ root_device_path }}"
- name: mount-drives
shell: |
umount -R /mnt
mkfs.ext4 -q -L root /dev/disk/by-partlabel/root
mkfs.ext4 -m 0 -q -L boot /dev/disk/by-partlabel/boot
mount /dev/disk/by-partlabel/root {{ chroot_directory }}
mkdir -p {{ chroot_directory }}/boot
mount /dev/disk/by-partlabel/boot {{ chroot_directory }}/boot
- name: register uuid of boot disk
shell: |
blkid /dev/disk/by-partlabel/boot | grep -o '\bUUID="[^"]*"' | sed 's/"//g'
register: boot_uuid
- name: register uuid of root disk
shell: |
blkid /dev/disk/by-partlabel/root | grep -o '\bUUID="[^"]*"' | sed 's/"//g'
register: root_uuid
- name: initialize alpine-base in directory
shell: >-
./apk -X {{ alpine_repositories[0].url }}
-u
--allow-untrusted
--root /{{ chroot_directory }}
--initdb
add alpine-base
- name: prepare chroot
shell: |
mount --bind /dev {{ chroot_directory }}/dev
mount --bind /proc {{ chroot_directory }}/proc
mount --bind /sys {{ chroot_directory }}/sys
- name: copy resolv conf from the rescue system to the server
copy:
content: |
{% for nameserver in nameservers %}
nameserver {{ nameserver }}
{% endfor %}
dest: "{{ chroot_directory }}/etc/resolv.conf"
- name: setup networking
copy:
content: |
auto lo
iface lo inet loopback
{% for dif in dhcp_interfaces %}
auto {{ dif }}
iface {{ dif }} inet dhcp
iface {{ dif }} inet6 auto
{% endfor %}
dest: "{{ chroot_directory }}/etc/network/interfaces"
- name: write out hostname file
copy:
dest: "{{ chroot_directory }}/etc/hostname"
content: "{{ hostname }}"
- name: overwrite hosts file
copy:
dest: "{{ chroot_directory }}/etc/hosts"
content: |
127.0.0.1 {{ hostname }} localhost localhost.localdomain
::1 {{ hostname }} localhost localhost.localdomain
::1 {{ hostname }} localhost ipv6-localhost ipv6-loopback
fe00::0 ipv6-localnet
ff00::0 ipv6-mcastprefix
ff02::1 ipv6-allnodes
ff02::2 ipv6-allrouters
ff02::3 ipv6-allhosts
- name: install custom repository keys
copy:
dest: "{{ chroot_directory }}/etc/apk/keys/{{ item.name }}"
content: "{{ item.public_key }}"
loop: "{{ alpine_repository_keys }}"
- name: define alpine repositories
copy:
dest: "{{ chroot_directory }}/etc/apk/repositories"
content: |
{% for repository in alpine_repositories %}
{% if repository.tag | d(false) %}@{{ repository.tag }} {% endif %}{{ repository.url }}
{% endfor %}
- name: install requisite packages
shell: |
chroot {{ chroot_directory }} apk add --no-cache {{ item.key }}{{ item.value }}
loop: "{{ packages | dict2items }}"
- name: configure services
shell: |
chroot {{ chroot_directory }} rc-update add {{ item.key }} {{ item.value }}
loop: "{{ services | dict2items }}"
- name: enable cloud-init
shell: |
chroot {{ chroot_directory }} setup-cloud-init
when: packages["cloud-init"] is defined
- name: configure fstab
copy:
dest: "{{ chroot_directory }}/etc/fstab"
content: |
{{ root_uuid.stdout | trim }} / ext4 defaults,noatime 0 0
{{ boot_uuid.stdout | trim }} /boot ext4 defaults 0 2
- name: configure sysctl
copy:
dest: "{{ chroot_directory }}/etc/sysctl.conf"
content: |
{% for setting in sysctl | dict2items %}
{{ setting.key }} = {{ setting.value }}
{% endfor %}
- name: configure kernel modules
copy:
dest: "{{ chroot_directory }}/etc/modules"
content: |
{% for module in kernel_modules %}
{{ module }}
{% endfor %}
- name: configure extlinux
copy:
dest: "{{ chroot_directory }}/etc/update-extlinux.conf"
content: |
overwrite=1
vesa_menu=0
default_kernel_opts="{{ default_kernel_opts | join(" ") }}"
modules={{ extlinux_modules | join(",") }}
root={{ root_uuid.stdout | trim }}
verbose=0
hidden=1
timeout=1
default=lts
serial_port=
serial_baud=115200
xen_opts=dom0_mem=384M
password=''
- name: configure mkinitfs
copy:
dest: "{{ chroot_directory }}/etc/mkinitfs/mkinitfs.conf"
content: |
features="{{ kernel_features | join(" ") }}"
- name: install boot
shell: |
chroot {{ chroot_directory }} update-extlinux
chroot {{ chroot_directory }} extlinux -i /boot
chroot {{ chroot_directory }} dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/gptmbr.bin of={{ root_device_path }}
- name: execute arbitrary commands
shell: |
chroot {{ chroot_directory }} sh <<CHROOT_COMMAND_HD
{{ item }}
CHROOT_COMMAND_HD
loop: "{{ chroot_commands }}"