---
description: "DevOps and infrastructure: Docker, Kubernetes, Terraform, CI/CD. Load when editing Dockerfiles, compose, k8s manifests, Terraform, or workflow YAML — not for application code."
globs: ["**/Dockerfile*", "**/*.tf", "**/docker-compose*.yml", "**/docker-compose*.yaml", "**/k8s/**", "**/.github/workflows/**", "**/.gitlab-ci.yml", "**/Jenkinsfile", "**/cloudbuild.yaml", "**/terraform/**", "**/helm/**"]
alwaysApply: false
---

# DevOps & Infrastructure Patterns

Mechanical reference for containerization, orchestration, IaC, and CI/CD. For general coding workflow (read-before-edit, minimal diff, verification labels), the always-on core **Code Discipline** and **App And Scaffold Discipline** sections are canonical.

Load this rule when touching infrastructure files matched by globs. For unfamiliar provider APIs or version-sensitive changes, verify against current official docs (or use the `deep-research` skill) — do not invent flags, resource names, or provider syntax.

---

## Before Changing Infrastructure

1. Read existing Docker, compose, k8s, Terraform, Helm, and CI workflow files in this repo first.
2. Note pinned base images, provider versions, and environment naming — match them unless the task requires a deliberate upgrade.
3. Identify blast radius: prod deploy, secrets, stateful resources, and rollback path.
4. Prefer **plan / dry-run / validate** before **apply / deploy / push**.

---

## Validate Before Apply

| Tool | Smallest useful check |
|------|------------------------|
| Docker | `docker build -t test:local .` |
| Compose | `docker compose config` |
| Kubernetes | `kubectl apply --dry-run=client -f …` or `kubectl diff -f …` |
| Terraform | `terraform fmt -check`, `terraform validate`, `terraform plan` |
| Helm | `helm lint`, `helm template` (render locally) |
| GitHub Actions | YAML syntax + action pin review; run workflow on a branch when safe |

Never recommend `terraform apply`, `kubectl apply`, or production deploy without a plan/dry-run step unless the user explicitly skips it.

---

## Decision Quick Reference

| Need | Prefer |
|------|--------|
| Local dev stack | Docker Compose when sufficient; k8s only when repo already uses it |
| Secrets | Platform secret stores / CI secrets — never commit plaintext |
| CI | Extend existing workflow patterns in `.github/workflows/` rather than inventing a parallel pipeline |
| Image tags | Pin major.minor (or digest); avoid `:latest` in anything that ships |
| Terraform state | Remote backend + locking when team/shared; do not hand-edit state |

---

## Common Traps

- **YAML tabs** — spaces only (2-space indent is standard).
- **Unquoted YAML scalars** — quote version strings and booleans when they must stay strings (`"1.0"`, `"true"`).
- **Secrets in repo** — no passwords, tokens, or keys in Dockerfile `ENV`, compose, or workflow YAML; use `${{ secrets.* }}`, K8s `secretKeyRef`, or TF variables from a vault.
- **`:latest` base images** — pin `node:20-alpine`, `python:3.12-slim`, etc.; verify current tags against official registries.
- **Blind apply** — skipping `plan` / dry-run on shared or production infra.
- **Drift from repo conventions** — new services that ignore existing naming, networks, labels, or backend config.

---

## CI/CD Discipline

- Reuse job names, runner labels, cache keys, and artifact patterns already in the repo.
- Pin third-party GitHub Actions to a commit SHA or semver tag — not `@main`.
- Scope secrets to the minimum job that needs them.
- For deploy workflows: require manual approval or environment gates when the repo already uses them; do not remove safety rails opportunistically.

---

## Security (infra-specific)

- Least-privilege IAM / service accounts; no admin credentials in CI logs.
- Scan images when the repo already has Trivy/Snyk/similar — do not add heavy tooling unprompted.
- Network policies / security groups: default deny between services unless the architecture requires otherwise.
- Treat `.env`, kubeconfig, and TF state as sensitive — never paste contents into chat or commits.

---

## Verification After Changes

Match proof to the claim (see always-on status-verification rule):

| Change | Minimum proof |
|--------|----------------|
| Dockerfile / compose | `docker build` or `docker compose config` succeeds |
| k8s manifest | dry-run or schema validation passes |
| Terraform | `validate` + `plan` with expected diff |
| CI workflow | YAML valid; optional dry-run on branch if user allows |

Label deploy/runtime behavior as `unverified` until exercised in the target environment.

---

## When NOT to Load This File

- Application logic, API handlers, or UI — use core **Code Discipline** instead.
- Full cloud architecture from scratch — inspect the repo and ask on real forks (provider, region, existing VPC/cluster).
