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.
How it Works
Section titled “How it Works”- Nix Integration:
modules/nixos/infra/cloudflare.nixreads active entries fromconfig.homelab.proxies. - Generated Variables: Nix writes
terraform.tfvars.jsonwith the domain, host prefix, user emails, username, and proxy map. - State Management: OpenTofu keeps its working state in
/var/lib/cloudflare-infra/. - Automatic Sync:
infra.cloudflare.servicerunstofu apply -auto-approveduring the system activation lifecycle. - Tunnel Runtime:
cloudflared.servicestarts after provisioning and reads the generated tunnel token from/var/lib/cloudflare-infra/tunnel.token.
Provisioned Resources
Section titled “Provisioned Resources”For each service defined in homelab.proxies, the system automatically creates:
- A CNAME Record:
- For local services, it points
service-home.javiersc.comto the Cloudflare Tunnel. - For
cloudflare-pagesservices, it queries the Cloudflare REST API dynamically (via thehashicorp/httpprovider) to fetch the assigned.pages.devsubdomain and point the CNAME there, avoiding Cross-User Banned errors.
- For local services, it points
- 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-pagesservices).
Source Files
Section titled “Source Files”| File | Role |
|---|---|
modules/nixos/infra/cloudflare.nix | NixOS module that generates variables, manages systemd, fetches 1Password values, and installs homelab-reset. |
modules/nixos/infra/cloudflare/main.tf | OpenTofu configuration for DNS, Access, Pages domains, and Cloudflare Tunnel ingress. |
modules/nixos/infra/cloudflare/reset.sh | Reset implementation used by homelab-reset. |
modules/nixos/services/cloudflared.nix | Enables Cloudflare infrastructure and runs the generated tunnel token. |
MASTER_SECRETS.nix | Stores the 1Password references for Cloudflare account ID, zone ID, API token, and tunnel secret. |
Disaster Recovery: Full Reset
Section titled “Disaster Recovery: Full Reset”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:
nix shell nixpkgs#jq nixpkgs#curl nixpkgs#systemd -c bash scripts/homelab-reset-cloudflareWhat this command does:
- Stops the local
cloudflaredtunnel. - Authenticates with 1Password to get API tokens.
- Deletes all homelab-related DNS records and Access Apps via Cloudflare API.
- Deletes the Cloudflare Tunnel itself.
- Wipes the local OpenTofu state directory.
- Triggers a fresh
nixos-rebuild switch. - Restarts the provisioning and the tunnel.
When to use it?
Section titled “When to use it?”- 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.
Troubleshooting
Section titled “Troubleshooting”Check Provisioning Logs
Section titled “Check Provisioning Logs”If a rebuild finishes but a service is not accessible:
sudo journalctl -u infra.cloudflare -fCheck Tunnel Status
Section titled “Check Tunnel Status”To see if the local machine is successfully connected to Cloudflare:
sudo journalctl -u cloudflared -fA healthy tunnel should show Connection ... established.
State Directory Mismatch
Section titled “State Directory Mismatch”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.