Skip to content

Infrastructure Provisioning

The homelab uses OpenTofu (an open-source Terraform fork) to declaratively manage external infrastructure. This ensures that DNS records, security policies, and tunnels are always in sync with the NixOS configuration.

  1. Nix Integration: modules/nixos/infra/cloudflare.nix reads active entries from config.homelab.proxies.
  2. Generated Variables: Nix writes terraform.tfvars.json with the domain, host prefix, user emails, username, and proxy map.
  3. State Management: OpenTofu keeps its working state in /var/lib/cloudflare-infra/.
  4. Automatic Sync: infra.cloudflare.service runs tofu apply -auto-approve during the system activation lifecycle.
  5. Tunnel Runtime: cloudflared.service starts after provisioning and reads the generated tunnel token from /var/lib/cloudflare-infra/tunnel.token.

For each service defined in homelab.proxies, the system automatically creates:

  • A CNAME Record:
    • For local services, it points service-home.javiersc.com to the Cloudflare Tunnel.
    • For cloudflare-pages services, it queries the Cloudflare REST API dynamically (via the hashicorp/http provider) to fetch the assigned .pages.dev subdomain and point the CNAME there, avoiding Cross-User Banned errors.
  • A Cloudflare Access Application: Protects the URL with Zero Trust.
  • An Access Policy: Restricts access to the main admin email and configured member emails from CONFIG.nix.
  • A Pages Custom Domain: Links the CNAME to the Cloudflare Pages project (only for cloudflare-pages services).
FileRole
modules/nixos/infra/cloudflare.nixNixOS module that generates variables, manages systemd, fetches 1Password values, and installs homelab-reset.
modules/nixos/infra/cloudflare/main.tfOpenTofu configuration for DNS, Access, Pages domains, and Cloudflare Tunnel ingress.
modules/nixos/infra/cloudflare/reset.shReset implementation used by homelab-reset.
modules/nixos/services/cloudflared.nixEnables Cloudflare infrastructure and runs the generated tunnel token.
MASTER_SECRETS.nixStores the 1Password references for Cloudflare account ID, zone ID, API token, and tunnel secret.

If Cloudflare resources become out of sync, or you encounter persistent “Resource already exists” errors, you can perform a “surgical strike” reset.

The system provides a reset wrapper script to wipe everything and start fresh:

Terminal window
nix shell nixpkgs#jq nixpkgs#curl nixpkgs#systemd -c bash scripts/homelab-reset-cloudflare

What this command does:

  1. Stops the local cloudflared tunnel.
  2. Authenticates with 1Password to get API tokens.
  3. Deletes all homelab-related DNS records and Access Apps via Cloudflare API.
  4. Deletes the Cloudflare Tunnel itself.
  5. Wipes the local OpenTofu state directory.
  6. Triggers a fresh nixos-rebuild switch.
  7. Restarts the provisioning and the tunnel.
  • When you manually deleted something in the Cloudflare Dashboard and Tofu is confused.
  • When you get error 1013 (Tunnel already exists) repeatedly.
  • When migrating to a new Cloudflare account or zone.

If a rebuild finishes but a service is not accessible:

Terminal window
sudo journalctl -u infra.cloudflare -f

To see if the local machine is successfully connected to Cloudflare:

Terminal window
sudo journalctl -u cloudflared -f

A healthy tunnel should show Connection ... established.

If older documentation, scripts, or snapshots reference /var/lib/provisioning, treat that as legacy state. The current path is /var/lib/cloudflare-infra/, and the legacy directory should only be removed after confirming the new provisioning path works.