]>
| description | Terraform + Ansible capture of this server's setup (mail/git/web) |
| last change | Fri, 17 Jul 2026 19:54:46 +0000 (19:54 +0000) |
| URL | https://andrewgundersen.net/repos/server-iac |
Terraform + Ansible for reproducing the setup of the mail/git/web server currently
running as ubuntu-us-ord (Linode, us-ord), serving andrewgundersen.net and
crimata.com.
This captures the parts of the box that are pure configuration. It does not capture secrets — see below.
terraform/ Provisions the Linode itself (size, region, image, networking)
ansible/ Installs and configures software on a provisioned box
These can't be "replayed" from config — they're per-identity secrets that either need fresh generation per node or a separate secure transfer:
/etc/letsencrypt/) — regenerate fresh via
certbot --nginx for whatever hostname the new node actually has. Don't
try to copy these; a cert for one IP/hostname looks suspicious presented
from another./etc/chasquid/certs/<domain>/dkim_privkey.pem) —
these DO need to match what's published in DNS, so unlike TLS certs they
can't just be regenerated per node without also updating DNS. If this ever
becomes a real multi-node setup, these need deliberate secure distribution
(not this repo)./var/www/.ssh/id_ed25519_*) — each
mirrored git repo has its own SSH deploy key scoped to just that repo (see
the [[dedicated SSH keys]] rationale — least privilege, so a compromised
key only exposes one repo). These are generated per-setup, not shared./var/mail/*) — this is state, not config. Not in scope
for IaC at all; needs its own backup story.andrew, me) — set manually per node.This repo exists because of a discussion about whether it'd ever make sense to run this setup in more than one region for durability. The honest breakdown of what that would actually require:
post-receive hooks, same pattern already in use to
mirror to GitHub.dsync replication feature.
Not set up here — this repo only stands up a single node.None of that is implemented yet. This repo is step one: capture the single node's setup so it's reproducible, before deciding whether multi-node is actually worth the added complexity.
For directing clients to the nearest node once there's more than one, decided on GeoDNS first, anycast later if needed:
Chose GeoDNS for now because it's proportionate to actual scale (one user, two mailboxes) - revisit anycast only if a real need for sub-TTL failover shows up, not preemptively.
| 8 days ago | Andrew Gundersen | Fix 5 bugs found via dry-run provision of a real Linode main | commit | commitdiff | tree | snapshot (tar.gz zip tar.bz2) |
| 8 days ago | Andrew Gundersen | Document GeoDNS-first client routing decision | commit | commitdiff | tree | snapshot (tar.gz zip tar.bz2) |
| 8 days ago | Andrew Gundersen | Initial Terraform + Ansible capture of the mail/git... | commit | commitdiff | tree | snapshot (tar.gz zip tar.bz2) |
| 8 days ago | main | shortlog | log | tree |