Conversation
…eGuard VPN
Replace the old Ansible content (now consolidated in the ansible repo) with
a Terraform layout for multiple cloud providers.
- environments/<provider>/<project> roots (start with do/vpn; blank gcp)
- modules/digitalocean-wireguard: cheapest droplet + firewall + a dedicated
DO Project ("space") holding only the VPN; WireGuard configured via
cloud-init; generates a ready-to-import Mac client config
- Makefile to drive terraform per env (make tf-* env=do/vpn, alias vpn)
- CLAUDE.md documenting repo conventions for adding envs/infra
- scripts/vpn.sh helper to connect/disconnect via wg-quick
Co-authored-by: Cursor <cursoragent@cursor.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe repository is migrated from Ansible to Terraform. It adds a DigitalOcean WireGuard module and environment, a Makefile workflow, a VPN helper script, and updated repository guidance and documentation while removing the Ansible configuration and playbooks. ChangesAnsible-to-Terraform Repository Migration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.gitignore:
- Around line 17-20: The .gitignore entry for broad `*.conf` files is too
general and can hide legitimate configs; remove that pattern and keep the more
specific `**/generated/` ignore that already covers the generated WireGuard
client config. Update the ignore rules in `.gitignore` so only generated
artifacts are excluded, preserving real `.conf` files elsewhere.
In `@CLAUDE.md`:
- Around line 13-17: Add a language hint to the Markdown fence in CLAUDE.md for
the layout section so MD040 is satisfied; update the fenced block around the
repository layout examples to use a text language tag while keeping the existing
content unchanged. Locate the fix in the layout snippet near the
modules/environments/scripts examples.
In `@Makefile`:
- Around line 53-63: The guard-env target currently only validates that ENV is
set and that ENV_DIR exists, so placeholder environments like gcp still pass and
fail later in Terraform. Update guard-env to also verify the selected
environment directory is not a blank placeholder by checking for the expected
Terraform content/files before proceeding, using the ENV and ENV_DIR variables
in the Makefile logic. Keep the existing messaging pattern, but add a clear
failure path for empty placeholder roots so make targets stop early when the
environment is not usable.
In `@modules/digitalocean-wireguard/main.tf`:
- Around line 10-25: The digitalocean_droplet resource is generating a
full-tunnel client config with a default IPv6 route, but the droplet is not
provisioned for IPv6 by default. Update the droplet configuration in
digitalocean_droplet.this to either enable IPv6 at creation or remove the ::/0
client route from the cloud-init/template-driven WireGuard config so the client
and server settings stay consistent.
In `@modules/digitalocean-wireguard/templates/cloud-init.yaml.tftpl`:
- Around line 19-29: The WireGuard cloud-init template hardcodes the server
address prefix, so vpn_subnet_cidr is ignored. Update the flow from main.tf to
pass the configured CIDR prefix into cloud-init.yaml.tftpl, and change the
Address line in the template to use that variable instead of always rendering
/24. Use the existing symbols vpn_subnet_cidr, main.tf, and the server Address
block in the cloud-init template to locate the change.
In `@modules/digitalocean-wireguard/variables.tf`:
- Around line 1-5: The module naming/layout breaks the repo’s standard provider
slug convention, so update the DigitalOcean module to use the short `do` prefix
in its module identity and any related references. Adjust the module’s
`name`/branding and any caller source paths or documentation so they follow the
expected `modules/<provider>-<thing>` pattern with `do` rather than
`digitalocean`, keeping the DigitalOcean-specific code aligned with the repo’s
`do` convention.
- Around line 30-34: The `ssh_allowed_cidrs` variable in `variables.tf`
currently defaults to globally open CIDRs, which `main.tf` passes directly into
the firewall and exposes SSH on every new apply. Update the default in
`ssh_allowed_cidrs` to a safer, non-public value or remove the default so
callers must explicitly choose allowed sources, and make sure the firewall rule
in `main.tf` continues to read from that variable without widening access.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3e50d01c-cfa7-4346-9b5b-a6be8ab96508
📒 Files selected for processing (59)
.gitignoreCLAUDE.mdMakefileREADME-Windows.mdREADME.mdansible.cfgenvironments/do/vpn/.terraform.lock.hclenvironments/do/vpn/main.tfenvironments/do/vpn/outputs.tfenvironments/do/vpn/providers.tfenvironments/do/vpn/terraform.tfvars.exampleenvironments/do/vpn/variables.tfenvironments/do/vpn/versions.tfenvironments/gcp/.gitkeepgroup_vars/linux_dev.ymlgroup_vars/windows_dev.ymlinventories/local.ymlmodules/digitalocean-wireguard/main.tfmodules/digitalocean-wireguard/outputs.tfmodules/digitalocean-wireguard/templates/cloud-init.yaml.tftplmodules/digitalocean-wireguard/variables.tfmodules/digitalocean-wireguard/versions.tfplaybooks/dev-setup.ymlplaybooks/development.ymlplaybooks/gaming-setup.ymlplaybooks/production.ymlplaybooks/site.ymlplaybooks/windows-only.ymlplaybooks/windows-wsl2.ymlrequirements.ymlroles/common/defaults/main.ymlroles/common/handlers/main.ymlroles/common/meta/main.ymlroles/common/tasks/main.ymlroles/common/templates/tmux.conf.j2roles/git-config/defaults/main.ymlroles/git-config/handlers/main.ymlroles/git-config/meta/main.ymlroles/git-config/tasks/main.ymlroles/linux-dev/defaults/main.ymlroles/linux-dev/meta/main.ymlroles/linux-dev/tasks/main.ymlroles/mednafen-gaming/defaults/main.ymlroles/mednafen-gaming/meta/main.ymlroles/mednafen-gaming/tasks/main.ymlroles/mednafen-gaming/templates/select-controller.sh.j2roles/nvim-config/defaults/main.ymlroles/nvim-config/handlers/main.ymlroles/nvim-config/meta/main.ymlroles/nvim-config/tasks/main.ymlroles/nvim-config/templates/init.vim.j2roles/windows-dev/defaults/main.ymlroles/windows-dev/meta/main.ymlroles/windows-dev/tasks/main.ymlroles/windows-wsl2-setup/defaults/main.ymlroles/windows-wsl2-setup/handlers/main.ymlroles/windows-wsl2-setup/meta/main.ymlroles/windows-wsl2-setup/tasks/main.ymlscripts/vpn.sh
💤 Files with no reviewable changes (41)
- roles/windows-wsl2-setup/handlers/main.yml
- roles/nvim-config/templates/init.vim.j2
- roles/common/tasks/main.yml
- roles/mednafen-gaming/meta/main.yml
- roles/linux-dev/tasks/main.yml
- playbooks/gaming-setup.yml
- roles/common/handlers/main.yml
- README-Windows.md
- roles/windows-dev/defaults/main.yml
- roles/windows-dev/meta/main.yml
- playbooks/development.yml
- roles/mednafen-gaming/templates/select-controller.sh.j2
- playbooks/site.yml
- roles/linux-dev/meta/main.yml
- roles/git-config/meta/main.yml
- ansible.cfg
- group_vars/windows_dev.yml
- roles/nvim-config/handlers/main.yml
- roles/common/defaults/main.yml
- roles/nvim-config/tasks/main.yml
- roles/linux-dev/defaults/main.yml
- playbooks/production.yml
- playbooks/windows-only.yml
- roles/windows-dev/tasks/main.yml
- roles/windows-wsl2-setup/meta/main.yml
- roles/mednafen-gaming/defaults/main.yml
- group_vars/linux_dev.yml
- roles/git-config/handlers/main.yml
- roles/common/meta/main.yml
- roles/git-config/defaults/main.yml
- roles/nvim-config/defaults/main.yml
- playbooks/windows-wsl2.yml
- roles/windows-wsl2-setup/defaults/main.yml
- roles/git-config/tasks/main.yml
- requirements.yml
- roles/nvim-config/meta/main.yml
- roles/windows-wsl2-setup/tasks/main.yml
- inventories/local.yml
- playbooks/dev-setup.yml
- roles/mednafen-gaming/tasks/main.yml
- roles/common/templates/tmux.conf.j2
- rename modules/digitalocean-wireguard -> modules/do-wireguard to follow the repo's modules/<provider>-<thing> convention (update env source + docs) - security: ssh_allowed_cidrs now defaults to closed; the SSH firewall rule is only created when CIDRs are provided (module + env root) - droplet: enable ipv6 so the dual-stack full-tunnel client config works - cloud-init: derive the server Address prefix from vpn_subnet_cidr instead of hardcoding /24 - Makefile: guard-env now rejects placeholder envs with no .tf files - gitignore: drop the broad *.conf ignore (generated/ already covers it) - CLAUDE.md: add text language hint to the layout fence (MD040) Co-authored-by: Cursor <cursoragent@cursor.com>
Aligns with foundry's `list` target naming. Updates the target, .PHONY, the help invocation, guard-env hints, and the README reference. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Repurposes this repo from Ansible into Terraform infrastructure-as-code for multiple cloud providers. The Ansible roles that lived here have been consolidated into the
ansiblerepo (separate PR).environments/<provider>/<project>/Terraform roots (each its own state) + reusablemodules/<provider>-<thing>. Starts withenvironments/do/vpnand a blankenvironments/gcp.modules/digitalocean-wireguard: provisions the cheapest DigitalOcean droplet (~$4/mo), a firewall (SSH + WireGuard UDP), and a dedicated DigitalOcean Project ("space") holding only the VPN. WireGuard is installed/configured via cloud-init, and a ready-to-import Mac client config is generated (keys via theOJFord/wireguardprovider).Makefile: drives Terraform per environment, e.g.make tf-init tf-plan tf-apply env=do/vpn(with avpnalias). Self-documentinghelptarget.CLAUDE.md: conventions for adding new environments and infra.scripts/vpn.sh: connect/disconnect helper usingwg-quick.Usage
Test plan
terraform fmt -recursive -checkcleanterraform init -backend=false+terraform validatepass inenvironments/do/vpnterraform applyagainst a real DO account to confirm the VPN comes upMade with Cursor
Summary by CodeRabbit
New Features
Documentation
Breaking Changes
Chores