feat(infra): update SOPS configuration, cloud-init templates, and secondary disk automation (#26)

### Summary of Changes

This PR incorporates the final infrastructure optimizations following
the initial merge of PR #25:

1. **SOPS & Secrets Management**:
- Generated dedicated Age keypair
(`age1jpa7hqyzzdfq7lvnw3l8qy6648mtjgpcqnljl5jz92dcqjrnsqfsn7m0fl`) and
updated `.sops.yaml`.
- Added SOPS-encrypted production secrets for PostgreSQL
(`ci/k8s/apps/postgres/secret.sops.yaml`) and Umami Analytics
(`ci/k8s/apps/umami/secret.sops.yaml`).
   - Verified 100% clean round-trip decryption.

2. **Cloud-Init Template & Git Safety**:
- Converted `user-data.yaml` into `user-data.template.yaml` with clear
stubs for public SSH keys and private Age keys.
- Added `ci/cloud-init/user-data.yaml` to `.gitignore` to prevent
accidental secret leaks.

3. **Persistent Secondary Storage**:
- Added automated detection, ext4 formatting, and mounting of secondary
persistent disk (`/dev/vdb`) to `/var/lib/rancher/k3s/storage` with
`noatime` in `user-data.template.yaml`.

4. **Golden Image Naming & Workflows**:
- Updated image naming convention to include hyphenated UTC timestamps:
`com-ermnvldmr-debian-12-k3s-amd64-YYYY-MM-DD-HH-MM-SS-sha-<short_sha>.qcow2`.
   - Verified successful CI golden image build and S3 upload.
This commit is contained in:
deytenit authored and GitHub committed 2026-08-23 14:02:08 +03:00
1 parent 710873e72c
commit 502ef94bb2
14 files changed
+234 -79

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
instance-id: debian-packer
local-hostname: debian-k3s
+14
View File
@@ -0,0 +1,14 @@
#cloud-config
ssh_pwauth: true
disable_root: false
chpasswd:
list: |
debian:packer
root:packer
expire: false
users:
- default
- name: debian
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
lock_passwd: false
+28 -29
View File
@@ -7,14 +7,14 @@ packer {
}
}
variable "debian_iso_url" {
variable "debian_cloud_image_url" {
type = string
default = "https://cdimage.debian.org/cdimage/archive/12.8.0/amd64/iso-cd/debian-12.8.0-amd64-netinst.iso"
default = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-amd64.qcow2"
}
variable "debian_iso_checksum" {
variable "debian_cloud_image_checksum" {
type = string
default = "file:https://cdimage.debian.org/cdimage/archive/12.8.0/amd64/iso-cd/SHA512SUMS"
default = "file:https://cloud.debian.org/images/cloud/bookworm/latest/SHA512SUMS"
}
variable "vm_name" {
@@ -22,35 +22,33 @@ variable "vm_name" {
default = "com-ermnvldmr-debian-12-k3s-amd64.qcow2"
}
variable "accelerator" {
type = string
default = "kvm"
}
source "qemu" "debian_k3s" {
iso_url = var.debian_iso_url
iso_checksum = var.debian_iso_checksum
output_directory = "output-qemu"
shutdown_command = "echo 'packer' | sudo -S shutdown -P now"
disk_size = "10G"
format = "qcow2"
accelerator = "kvm"
http_directory = "ci/packer/http"
ssh_username = "root"
ssh_password = "packer"
ssh_timeout = "25m"
vm_name = var.vm_name
net_device = "virtio-net"
disk_interface = "virtio"
efi_boot = true
iso_url = var.debian_cloud_image_url
iso_checksum = var.debian_cloud_image_checksum
disk_image = true
disk_size = "10G"
format = "qcow2"
output_directory = "output-qemu"
shutdown_command = "echo 'packer' | sudo -S shutdown -P now"
accelerator = var.accelerator
cd_files = ["ci/packer/cidata/user-data", "ci/packer/cidata/meta-data"]
cd_label = "cidata"
ssh_username = "debian"
ssh_password = "packer"
ssh_timeout = "5m"
vm_name = var.vm_name
net_device = "virtio-net"
disk_interface = "virtio"
headless = true
qemuargs = [
["-m", "2048M"],
["-smp", "2"],
["-serial", "mon:stdio"]
]
boot_wait = "5s"
boot_command = [
"<wait><wait><wait>c<wait>",
"linux /install.amd/vmlinuz auto=true priority=critical preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg --- quiet<enter>",
"initrd /install.amd/initrd.gz<enter>",
"boot<enter>"
["-smp", "2"]
]
}
@@ -58,6 +56,7 @@ build {
sources = ["source.qemu.debian_k3s"]
provisioner "shell" {
execute_command = "echo 'packer' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'"
scripts = [
"ci/packer/scripts/01-base-system.sh",
"ci/packer/scripts/02-install-k3s.sh",
+3 -5
View File
@@ -1,14 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail
set -eu
export DEBIAN_FRONTEND=noninteractive
echo "=== Configuring Base System for Cloud Image ==="
# Install essential kernel modules and utilities
apt-get update
apt-get install -y --no-install-recommends \
cloud-init \
qemu-guest-agent \
linux-image-amd64 \
socat \
conntrack \
ipset \
@@ -18,7 +16,6 @@ apt-get install -y --no-install-recommends \
unattended-upgrades \
curl \
ca-certificates \
gnupg \
tar \
gzip
@@ -49,6 +46,7 @@ datasource:
EOF
# Ensure DHCP on eth0
mkdir -p /etc/network/interfaces.d
cat << 'EOF' > /etc/network/interfaces.d/eth0
auto eth0
iface eth0 inet dhcp
+2 -1
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
set -eu
export DEBIAN_FRONTEND=noninteractive
echo "=== Installing K3s Binary (First-Boot Isolation) ==="
+5 -2
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
set -eu
export DEBIAN_FRONTEND=noninteractive
echo "=== Sanitizing Machine Identity & Temporary Files ==="
@@ -16,7 +17,9 @@ ln -sf /etc/machine-id /var/lib/dbus/machine-id
# Remove generated SSH host keys (re-created by cloud-init on first boot)
rm -f /etc/ssh/ssh_host_*
# Clean cloud-init logs and state
# Clean cloud-init logs, state, and reset temporary build DNS
rm -f /etc/resolv.conf
touch /etc/resolv.conf
cloud-init clean --logs || true
rm -rf /var/lib/cloud/instances/*