autojanet/skills/terrashark/references/ci-delivery-patterns.md
Zoë cfec11bb46
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: convert skill submodules to plain directories
stop-slop, taste-skill, terrashark had embedded .git dirs causing
Woodpecker clone to fail on submodule update.
2026-05-30 15:44:44 -07:00

220 lines
5 KiB
Markdown

# CI Delivery Patterns
Use this guide to implement auditable Terraform/OpenTofu delivery pipelines.
## Delivery principles
- plan and apply are separate concerns
- apply must consume reviewed plan artifact when architecture permits
- policy and security checks run on every apply path
- production applies require environment protection and approvals
## Baseline stages
1. `fmt` + `validate`
2. lint + security scan
3. plan creation
4. policy checks against plan JSON
5. approval gate
6. apply from trusted branch/runner
7. post-apply drift and evidence capture
## GitHub Actions (production-oriented template)
```yaml
name: terraform-delivery
on:
pull_request:
paths:
- '**/*.tf'
- '**/*.tfvars'
workflow_dispatch:
push:
branches: [main]
paths:
- '**/*.tf'
- '**/*.tfvars'
permissions:
contents: read
id-token: write
pull-requests: write
concurrency:
group: terraform-${{ github.ref }}
cancel-in-progress: false
env:
TF_IN_AUTOMATION: "true"
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform fmt -check
- run: terraform init -backend=false
- run: terraform validate
plan:
if: github.event_name == 'pull_request'
needs: [validate]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan -out=plan.bin
- run: terraform show -json plan.bin > plan.json
- run: conftest test plan.json --policy policy/
- uses: actions/upload-artifact@v4
with:
name: reviewed-plan
path: |
plan.bin
plan.json
apply:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
needs: [validate]
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan -out=plan.bin
- run: terraform apply -auto-approve plan.bin
```
Notes:
- configure provider auth with OIDC (avoid static cloud keys)
- if you require strict “apply reviewed PR plan” semantics, keep plan/apply in same workflow run or externalize signed plan storage
## GitLab CI (production-oriented template)
```yaml
stages:
- validate
- plan
- policy
- apply
- verify
variables:
TF_IN_AUTOMATION: "true"
validate:
stage: validate
image: hashicorp/terraform:1.7
script:
- terraform fmt -check
- terraform init -backend=false
- terraform validate
plan:
stage: plan
image: hashicorp/terraform:1.7
script:
- terraform init
- terraform plan -out=plan.bin
- terraform show -json plan.bin > plan.json
artifacts:
paths: [plan.bin, plan.json]
expire_in: 24h
policy:
stage: policy
image: openpolicyagent/conftest:latest
dependencies: [plan]
script:
- conftest test plan.json --policy policy/
apply:
stage: apply
image: hashicorp/terraform:1.7
dependencies: [plan]
when: manual
allow_failure: false
script:
- terraform init
- terraform apply -auto-approve plan.bin
verify:
stage: verify
image: hashicorp/terraform:1.7
script:
- terraform plan -detailed-exitcode
```
## Pipeline hardening checklist
- enforce branch protection on default branch
- require CODEOWNERS review for prod-impacting paths
- restrict apply jobs to protected runners
- set artifact retention + access policies
- preserve audit trail (approver, actor, commit, runtime version)
## Cost and speed controls
- run expensive integration suites only for IaC path changes
- serialize shared-foundation applies
- use provider plugin cache where supported
- schedule cleanup for ephemeral test environments
## Atlantis (PR-driven delivery template)
Use Atlantis when you want chat-driven, PR-scoped plan/apply with locking.
Example `atlantis.yaml`:
```yaml
version: 3
projects:
- name: platform
dir: .
workspace: default
autoplan:
enabled: true
when_modified: ["**/*.tf", "**/*.tfvars"]
workflow: default
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply
```
Hardening notes:
- restrict apply to approved PRs and protected branches
- enable Atlantis server-side locking
- use custom workflows to add policy checks and cost steps
- keep CI auth in OIDC where supported; avoid static secrets
## Infracost (cost visibility template)
Use Infracost to surface cost deltas from plan JSON in PRs.
Pattern:
1. run plan and export plan JSON
2. generate Infracost breakdown
3. publish result as PR comment or artifact
Example commands:
```bash
terraform plan -out=plan.bin
terraform show -json plan.bin > plan.json
infracost breakdown --path plan.json --format json --out-file infracost.json
```
Notes:
- store `plan.json` and `infracost.json` as artifacts for auditability
- treat cost checks like policy checks for high-risk environments