docs(iac): enforce single source of truth for infrastructure
Add IaC practice section to coding-standards.md: - All infrastructure state via Terraform or Helm (never ad-hoc scripts) - Clear division: Terraform owns helm releases/namespaces/storage/state - Anti-pattern: split bucket definitions across multiple files - Bootstrap-only exception: document one-time setup with rationale Rationale: prevents state drift, credential duplication, and unclear ownership.
This commit is contained in:
@@ -70,6 +70,59 @@ set:
|
||||
|
||||
---
|
||||
|
||||
## Infrastructure as Code (IaC) — Single Source of Truth
|
||||
|
||||
**Core principle:** All infrastructure state must be declaratively managed via Terraform or Helm (via helmfile + Terraform). No ad-hoc scripts, manual kubectl, or side-by-side resource definitions.
|
||||
|
||||
### Terraform + Helm Division of Labor
|
||||
|
||||
- **Terraform manages:**
|
||||
- Helm releases (chart + version + values)
|
||||
- Namespaces
|
||||
- StorageClasses
|
||||
- Static Kubernetes resources (RBAC, NetworkPolicies, IngressClasses)
|
||||
- Cloud infrastructure (Vault, S3 backends, secrets)
|
||||
- State persistence (S3 backend in MinIO)
|
||||
|
||||
- **Helmfile manages:**
|
||||
- Chart release ordering via `needs:`
|
||||
- Environment-specific value interpolation (Go templating, not shell)
|
||||
- Hook workflows (pre/post-sync orchestration)
|
||||
- **Never use helmfile for one-off bucket creation, job runs, or manual setup** — those belong in Terraform or a documented bootstrap process
|
||||
|
||||
- **Kubernetes manifests (`k8s/`) manage:**
|
||||
- ArgoCD applications (single source of truth for GitOps)
|
||||
- Service definitions that ArgoCD syncs
|
||||
- **Never manage app objects (Deployments, StatefulSets) directly** — let helm + ArgoCD own them
|
||||
|
||||
### Anti-Pattern: Ad-Hoc Resource Creation
|
||||
|
||||
❌ **Bad:** Separate `minio-buckets.tf` using `aws_s3_bucket` resources + post-deploy scripts
|
||||
- Split responsibility: some buckets in Terraform, others in helmfile, others manual
|
||||
- State drift: unclear what's managed where
|
||||
- Credential duplication: secrets in multiple places
|
||||
|
||||
✅ **Good:** Single source in `minio.tf` helm release:
|
||||
```hcl
|
||||
buckets = [
|
||||
{ name = "terraform-state", policy = "none", purge = false },
|
||||
{ name = "vault", policy = "none", purge = false },
|
||||
...
|
||||
]
|
||||
```
|
||||
- One place to define, one place to audit
|
||||
- Credentials in variables + Vault, not scattered
|
||||
- TF state tracks all changes
|
||||
|
||||
### When to Break the Rule
|
||||
|
||||
Only when **explicitly documented**:
|
||||
- Bootstrap scripts (one-time cluster init) — commit to `scripts/` with clear "run once" warning
|
||||
- Temporary debugging (never leave in git) — stash or delete before committing
|
||||
- Manual steps for constraint (e.g., "create namespace before ArgoCD bootstraps") — document in `TROUBLESHOOTING.md` with rationale
|
||||
|
||||
---
|
||||
|
||||
## YAML & ConfigMap/Secret Patterns
|
||||
|
||||
### Secret Field Naming
|
||||
|
||||
Reference in New Issue
Block a user