multi-env-promotion
Skill0 starsChanged 5 months agoMITView on GitHub
Multi-environment promotion: dev→test→staging→prod, trunk-based development with per-environment directories, build-once-promote-one-immutable-artifact, CODEOWNERS on prod, environment-scoped variables, rollback strategies. Triggers on: promotion, dev test staging prod, environment directory, trunk-based, build once, immutable artifact, CODEOWNERS prod, rollback, promote release.
In this repository24 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ansible-patternsSkill
- ansible-testingSkill
- change-documentationSkill
- ci-pipeline-debuggingSkill
- drift-detectionSkill
- gitlab-cicd-pipelineSkill
- hsa-infrastructureSkill
- iac-sast-scanningSkill
- iac-tooling-selectionSkill
- incident-responseSkill
- instinct-promotionSkill
- instinct-rollbackSkill
- knowledge-curationSkill
- octopus-releaseSkill
- pci-cp-complianceSkill
- pci-dss-complianceSkill
- pci-pin-awarenessSkill
- perso-change-controlSkill
- perso-complianceSkill
- pre-commit-and-secret-scanningSkill
- rollback-and-runbooksSkill
- secrets-vaultSkill
- supply-chain-and-sbomSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 3 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 135
When Octopus is in use: re-deploy a previous Octopus release via the UI — same artifact, instant rollback.
- Distinctive: line 189
Never rebuild for higher environments — it introduces environmental variation.
- Distinctive: line 209
Never store prod configuration in the artifact or source control
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Multi-Environment Promotion Skill
When to Use
Load this skill when designing or reviewing the promotion flow for an Ansible change,
configuring GitLab environments, setting up environment: job keywords, or reasoning
about rollback. Also load when working with CODEOWNERS, protected-environment
approvals, or artifact tagging across environments.
How It Works
Branching Model: Trunk-Based + Per-Environment Directories
Single main branch (trunk). Feature branches merge to main via MR. Per-environment
configuration lives in inventories/ subdirectories — not in separate long-lived
branches. Promotion is pipeline-driven, not branch-driven.
repo/
inventories/
dev/
hosts.yml
group_vars/
all/env_specific.yml
test/
staging/
prod/ ← CODEOWNERS: @ops-team; protected-env approval gate
roles/
collections/requirements.yml # pinned SemVer
site.ymlThe same site.yml playbook runs in every environment; only the inventory (-i
inventories/<env>) changes. Env-specific differences live in group_vars/<env>,
never in when: env == 'prod' conditionals in the playbook.
(multi-env-versioning.md §3.3; Liatrio trunk-based GitOps; DigitalOcean multi-stage)
CODEOWNERS Enforcement
# .gitlab/CODEOWNERS
/inventories/prod/** @your-org/ops-team
/inventories/staging/** @your-org/platform-team
/collections/requirements.yml @your-org/platform-team
/roles/** @your-org/platform-teamAny MR touching inventories/prod/ requires @ops-team approval before it can
merge to main. Combined with GitLab deployment approval, this gives two-person
integrity for all production changes. (multi-env-versioning.md §3.4; pci-dss-devops.md §8)
Build Once, Promote One Immutable Artifact
"Artifacts, not Git commits, should travel within a pipeline." (Octopus enterprise CI/CD best practices) Build the artifact once; promote the same artifact through all environments:
- On merge to
main:ansible-galaxy collection install -r requirements.yml, bundle intoansible-bundle-${CI_COMMIT_SHA}.tar.gz, store in GitLab Package Registry. - Across environments: dev, test, staging, prod all extract the same tarball;
only the
-i inventories/<env>flag changes. - On release tag (
vX.Y.Z): retag the artifact; do not reinstall or rebuild.
Path convention: this plugin uses
inventories/<env>/(one directory per environment), consistent with theansible-patternsandgitlab-cicd-pipelineskills. Authored repos must not mixinventories/andenvironments/.
Verifiable same-artifact (provenance/attestation): "promote the same artifact"
must be cryptographically the same, not just the same filename. Attach a signed
checksum or build attestation (e.g. cosign / SLSA provenance, or at minimum a signed
SHA-256) at build, and verify it before each promotion. This satisfies the supply-chain
expectation in PCI DSS 6.3.2. See the supply-chain-and-sbom skill.
Referencing Execution Environments by digest (sha256:…) ensures the Ansible toolchain
is also pinned — not just the playbooks. (multi-env-versioning.md §4.3; DESIGN.md §10)
Promotion Flow
feature branch → MR (CI: lint+syntax+check+molecule) → merge to main
→ build artifact ($CI_COMMIT_SHA)
→ deploy-dev (auto; environment: development)
→ smoke tests pass
→ deploy-test (auto; environment: test; same artifact)
→ integration tests + security scan pass
→ [deploy-staging] (auto or manual; optional)
→ GATE: GitLab deployment approval (protected env, @ops-team, non-self-approve)
→ deploy-prod (manual trigger; environment: production; SAME artifact; tag v*.*.*rule)
→ git tag vX.Y.Z pinned to commit SHASource: multi-env-versioning.md §5.1; gitlab-octopus-cicd.md §1.5.
Environment-Scoped Variables
Scope all sensitive CI/CD variables to their specific environment — never wildcard *:
PROD_VAULT_TOKEN → environment scope: "production", protected: true
TEST_VAULT_TOKEN → environment scope: "test", protected: falseProtected variables (checkbox in Settings > CI/CD > Variables) are only exposed to pipelines on protected branches/tags — a feature branch cannot read prod secrets. (multi-env-versioning.md §6.2)
For secrets, use HashiCorp Vault with JWT/OIDC bound claims: production Vault role
authenticates only jobs on protected tags matching v*.*.*.
(multi-env-versioning.md §6.3; secrets-vault skill)
Rollback
Two mechanisms:
- Re-run previous pipeline: navigate to last known-good deployment in GitLab Environments UI and re-run. The previous artifact (still stored) is re-deployed.
- Git revert + new pipeline:
git revert <sha>→ normal promotion flow.
Disable automatic pipeline retries in production — manual re-run is safer.
resource_group prevents concurrent deploys to the same environment.
(multi-env-versioning.md §5.4; gitlab-octopus-cicd.md §1.1)
When Octopus is in use: re-deploy a previous Octopus release via the UI — same artifact, instant rollback. (octopus-multitentacle.md §5.2)
Versioning Summary
| Component | Scheme | Pinning rule |
| Collections / roles | SemVer (exact pin ==) | requirements.yml |
| Playbook suite / IaC repo | Git tag vX.Y.Z | Artifact name = $CI_COMMIT_SHA |
| Execution Environment image | SemVer + digest | sha256:… in pipeline vars |
| Python deps | PEP 440 ==X.Y.Z | requirements.txt in EE definition |
Golden rule: pin exact versions; never use latest or floating ranges in production.
(multi-env-versioning.md §4.2; modular-ansible-repos.md §3)
Trust Boundary
inventories/prod/**is CODEOWNERS-gated; only@ops-teamcan approve MRs.- Protected-env approval gate (GitLab Premium) or Octopus manual-intervention gate blocks prod deploy until a human with the right role clicks Proceed.
- The agent never holds prod deploy rights. (SPEC.md §2; DESIGN.md §10)
Examples
# .gitlab-ci.yml (promotion skeleton)
deploy_dev:
stage: deploy-dev
environment: { name: development }
resource_group: dev
tags: [linux, deploy, ansible]
script: [tar xzf "$ARTIFACT", ansible-playbook -i inventories/dev site.yml]
deploy_prod:
stage: deploy-prod
environment: { name: production }
resource_group: production
tags: [linux, deploy, ansible]
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual
script: [tar xzf "$ARTIFACT", ansible-playbook -i inventories/prod site.yml]TODO: Confirm staging environment name(s) from CMDB/environment discovery. TODO: Add deploy freeze window config once the change-freeze calendar is ingested. TODO: Confirm GitLab tier (Premium vs CE) to finalise approval-gate mechanism (DESIGN.md §17 Q4).
Deep Reference
Build-Once-Promote-One-Artifact
The artifact built in the pipeline must be the same artifact deployed to all environments. Never rebuild for higher environments — it introduces environmental variation.
CI Build → artifact (tagged with git SHA) → pushed to artifact store
↓
Octopus: Dev deploy (auto, from CI)
↓ manual gate
Octopus: Test deploy (same artifact, new config)
↓ manual gate + 2 approvals
Octopus: Staging deploy
↓ manual gate + change window
Octopus: Prod deployEnvironment-Specific Configuration Injection
Configuration differences between environments are injected at deploy time, not baked into the artifact:
- Octopus variables (environment-scoped) for endpoints, feature flags, resource sizes
- Vault secrets fetched at runtime per environment
- Never store prod configuration in the artifact or source control
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

