DNS as Code with Cloudflare, Terraform, and GitHub Actions
Managing all Cloudflare DNS from a single YAML file with a Python script, Terraform, and a GitHub Actions pipeline that applies changes on every merge to main.
Managing all Cloudflare DNS from a single YAML file with a Python script, Terraform, and a GitHub Actions pipeline that applies changes on every merge to main.
Replacing GitHub Actions secrets with HashiCorp Vault using JWT/OIDC auth so runners never hold static tokens, with the whole setup managed as code in Terraform.
Collapsing two copied and pasted Terraform pipelines into one versioned composite action and two reusable GitHub Actions workflows, plus the relative-path gotcha that almost shipped broken.
Moving my Tailscale tailnet policy out of the web-based ACL editor and into a git-managed policy.hujson file, tested against the live tailnet on every PR and applied automatically on merge to main.
Why I moved this blog off Hugo and onto Jekyll with the Chirpy theme, how I brought the posts across without breaking any links, and the GitHub Actions pipeline that builds, tests, and deploys the site for me.
Managing every Authentik group, user, and OAuth2 application as code with Terraform, secrets in Vault, and a GitHub Actions pipeline that plans on each PR and applies on merge to main.
Recovering a Proxmox Backup Server datastore that would not mount after a disk expand: diagnosing the missing filesystem and restoring a corrupted ext4 superblock.
Expanding a Proxmox Backup Server datastore after growing its virtual disk: fixing the GPT table, recreating the partition, and resizing the ext4 filesystem safely.
Growing an Ubuntu VM disk end to end: resizing the partition, extending the LVM physical and logical volumes, then the ext4 filesystem so the new space is usable.
Why I chose a static site over a CMS like Ghost or WordPress for my personal blog, and the thinking behind keeping day-to-day maintenance to a minimum.