TF: Team Readiness Assessment
Terraform Team Readiness Assessment
Question: Can a second developer safely run tofu apply today?
Answer: No. Here's what's missing.
Blockers for Team Development
| Blocker | Why It Matters | Fix |
|---|---|---|
| <strong>Secrets distribution</strong> | k3s.tfvars contains all secrets. New dev needs them. No secure handoff. | Move secrets to a vault (HashiCorp Vault, SOPS, or even Woodpecker secrets for CI-only) |
| <strong>Kubeconfig distribution</strong> | New dev needs cluster access. Currently one kubeconfig on one laptop. | RBAC: create per-developer service accounts with scoped permissions. Or Tailscale SSH + shared kubeconfig. |
| <strong>No CI pipeline</strong> | Without CI, every developer runs apply from their laptop. No review gate. | See <code>tf-pipeline-design</code>. PR-based plan/apply is the minimum. |
| <strong>No state locking documentation</strong> | Kubernetes backend has locking, but two devs running <code>tofu apply</code> simultaneously could race. | Document: only CI runs apply. Devs run plan locally. Apply is merge-gated. |
| <strong>No dev environment</strong> | New dev testing changes goes straight to prod. | See <code>tf-environment-strategy</code>. Namespace-level separation as minimum. |
| <strong>Monolithic state</strong> | Any change to pal-e-platform could touch 25 resources. Hard to scope. | Modularization helps but doesn't fully solve. Consider state splitting later. |
| <strong>Missing onboarding docs</strong> | No runbook for "how to set up your dev environment for TF work" | Write it: install tofu, get kubeconfig, create k3s.tfvars, run plan. |
Parallel Development Workflow (Target)
- Developer creates branch (worktree pattern already documented)
- Makes TF changes in branch
- Pushes to Forgejo, PR opens
- Woodpecker runs
tofu plan, posts output as PR comment - Team reviews plan output + code diff
- Merge triggers
tofu apply(serialized, one at a time via state lock) - If apply fails, pipeline alerts. Revert PR to rollback.
State Locking Details
The Kubernetes backend uses ConfigMap-based leases for locking. When one apply is running:
- A lease ConfigMap is created in
tofu-statenamespace - Concurrent
tofu applywill fail with "state locked" error - Stale locks can be force-unlocked:
tofu force-unlock <lock-id>
This is adequate for a small team. For larger teams, consider state splitting (separate state per module/component).
Minimum Viable Team Setup
To safely onboard one more developer:
- CI pipeline with plan-on-PR + apply-on-merge (eliminates laptop-only risk)
- Secrets in Woodpecker (not in tfvars files passed around)
- Per-developer kubeconfig with RBAC (read-only for plan, CI has write)
- Developer onboarding doc (how to clone, init, plan locally)
- Agreement: nobody runs
tofu applyfrom their laptop once CI is live