github-workflows-dojo360-infrastructure-promotion
Multi-environment infrastructure promotion workflow with deployment path validation and approval gates
Infrastructure Promotion Workflow Skill
Overview
The Infrastructure Promotion workflow automates multi-environment infrastructure deployments using Terraform, following a prescribed deployment path with approval gates between environments. This workflow orchestrates the deployment of infrastructure resources across multiple environments (dev → qa → cert → prod) by reusing the individual Infrastructure workflow for each stage.
Key Concept: The Promotion workflow validates that your requested deployment-path matches the promotion-path defined in your team's metadata, then executes sequential deployments to each environment with approval gates in between.
Workflow Reference
Repository: dojo360/pipelines-workflows
Workflow: .github/workflows/infrastructure-promotion.yml
Version: v2.0.0 (stable) or @beta (latest)
Documentation: Infrastructure Promotion Index
Key Features
Deployment Path Management
- Promotion Path Validation: Compares
deployment-pathwithpromotion-pathin metadata - EFIX Support: Allows user-defined stages for emergency fixes (deployment from non-default branches)
- Dynamic Job Creation: Automatically creates jobs for each environment in the deployment path
Approval & Gating
- Environment-Specific Approvals: Approval gates between each environment
- Trigger Jobs:
trigger_environment_Xjobs act as approval gateways - Protection Rules: Integrates with GitHub environment protection rules
Infrastructure Reusability
- Infrastructure Workflow Reuse: Calls
infrastructure.yml@betafor each environment - Automatic Input Injection: Injects
aide-id,cloud-type,ref,team-name,environment - Consistent Git Reference: Uses the same
ref(tag/branch) across all environments
Continuous Integration
- Non-Disruptive CI: Feature branch builds don't affect in-flight promotion workflows
- Tag & Default Branch Support: Restricted to default branch and tag-triggered pipelines
- E2E Testing: Optional end-to-end testing after each stage deployment
Prerequisites
Dojo360 Metadata Configuration
- Team metadata must be configured with
promotion-pathdefining valid environment progression deployment-pathmust match or be a subset ofpromotion-path- GitHub environments must be created matching deployment stages
GitHub Environment Setup
- Create GitHub environments for each stage (e.g.,
dev,qa,cert,prod) - Configure protection rules and approval requirements per environment
- Set environment-specific secrets (if needed)
Authentication Requirements
- OIDC Setup: For
awsOptumorazureOptumcloud types - Instance Profile: For
awsChc20cloud type - GH_TOKEN: Personal Access Token with repo permissions
Terraform Prerequisites
- Terraform code must be organized in a consistent directory structure
- Remote state backend must be configured (Azure, S3, or GCS)
- Terraform ~> 1.9.x required
Requirements
Terraform & Provider Versions
- Terraform: ~> 1.9.x
- AWS Provider: ~> 5.xx (for AWS operations)
- AzureRM Provider: ~> 3.xx (for Azure operations)
- GCP Provider: ~> 6.xx (for GCP operations)
GitHub Actions Permissions
permissions:
id-token: write # Required for OIDC authentication
contents: write # Required for checking out code
actions: read # Required for workflow execution
pull-requests: write # Required for PR comments (if enabled)
security-events: write # Required for security scanning
checks: write # Required for status checks
issues: read # Required for issue operations
Required Inputs
| Input | Type | Description |
|---|---|---|
aide-id | String | REQUIRED. The Aide ID used to fetch metadata |
cloud-type | String | REQUIRED. Cloud provider type. Valid values: awsOptum, awsChc20, azureOptum, gcp |
domain | String | REQUIRED. Domain used to fetch metadata |
deployment-path | String | REQUIRED. Deployment path as hyphen-separated environments (e.g., dev-qa-cert-prod) |
team-name | String | REQUIRED. Team name used to fetch metadata |
Common Optional Inputs
| Input | Type | Default | Description |
|---|---|---|---|
backend-type | String | azurerm | Backend type for Terraform state. Options: azurerm, s3, gcs |
pcam-role | String | contributor | Azure PCAM role for Service Principal |
terraform-directory | String | . | Directory path relative to repository root containing Terraform code |
terraform-vars-files | String | "" | Comma-separated list of tfvars files |
terraform-vars-values | String | "" | JSON string of tfvars variables |
terraform-prm-secrets | String | "" | Comma-separated list of PRM secrets to map to tfvars |
terraform-provider-network-mirror | String | https://repo1.uhc.com/artifactory/api/terraform/terraform-virtual/providers/ | Terraform provider mirror URL |
ref | String | "" | Git branch, tag, or SHA to checkout. Defaults to triggering reference |
remote-state-file-name | String | "" | Fully qualified remote state filename |
remote-state-folder-name | String | "" | Remote state folder name |
runner-labels | String | "" | Comma-separated custom runner labels |
E2E Testing Inputs
| Input | Type | Default | Description |
|---|---|---|---|
e2e-tests-enabled-stages | String | "" | Stages where E2E tests should run (hyphen-separated, e.g., qa-prod) |
e2e-workflow-file | String | "" | Workflow file name for E2E tests |
e2e-workflow-inputs | String | "" | JSON data with E2E workflow input overrides |
Secrets Management
| Input | Type | Default | Description |
|---|---|---|---|
prm-base-url | String | https://prm.optum.com | PRM instance base URL for secret retrieval |
Required Secrets
| Secret | Description |
|---|---|
GH_TOKEN | GitHub Personal Access Token with repo permissions |
Workflow Job Structure
The promotion workflow creates the following jobs automatically based on your deployment-path:
Core Jobs
parse_deployment_path- Validates deployment path against promotion path in metadataenvironment_1- Deploys to first environment (e.g., dev)trigger_environment_2- Approval gateway to second environmentenvironment_2- Deploys to second environment (e.g., qa)trigger_environment_3- Approval gateway to third environmentenvironment_3- Deploys to third environment (e.g., cert)trigger_environment_4- Approval gateway to fourth environmentenvironment_4- Deploys to fourth environment (e.g., prod)trigger_environment_5- Approval gateway (if 5th environment exists)environment_5- Deploys to fifth environment (if applicable)
Job Dependencies
- Each
environment_Xjob depends on successful completion of previoustrigger_environment_Xjob trigger_environment_Xjobs act as manual approval gates when GitHub environment protection is enabled- All jobs depend on successful
parse_deployment_pathvalidation
Usage Examples
Example 1: Basic Multi-Environment Promotion
name: Infrastructure Promotion
on:
push:
branches:
- main
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
deployment-path:
description: 'Deployment path (e.g., dev-qa-cert-prod)'
required: true
default: 'dev-qa-cert-prod'
permissions:
id-token: write
contents: write
actions: read
pull-requests: write
security-events: write
checks: write
issues: read
jobs:
promote:
uses: dojo360/pipelines-workflows/.github/workflows/infrastructure-promotion.yml@beta
with:
# Required inputs
aide-id: "<change me>"
cloud-type: "awsOptum"
domain: "<change me>"
deployment-path: "dev-qa-cert-prod"
team-name: "<change me>"
# Optional Terraform configuration
terraform-directory: "./terraform"
terraform-vars-files: "common.tfvars,prod.tfvars"
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
Example 2: Azure Infrastructure Promotion with PCAM
name: Azure Infrastructure Promotion
on:
workflow_dispatch:
inputs:
deployment-path:
description: 'Deployment path'
required: true
type: choice
options:
- dev-qa-cert-prod
- dev-qa
- cert-prod
permissions:
id-token: write
contents: write
actions: read
security-events: write
jobs:
azure-promote:
uses: dojo360/pipelines-workflows/.github/workflows/infrastructure-promotion.yml@beta
with:
aide-id: "<change me>"
cloud-type: "azureOptum"
domain: "<change me>"
deployment-path: ${{ inputs.deployment-path }}
team-name: "<change me>"
# Azure-specific configuration
backend-type: "azurerm"
pcam-role: "contributor"
terraform-directory: "./infrastructure"
# Azure state management
remote-state-folder-name: "terraform-state"
remote-state-file-name: "azure-infra.tfstate"
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
Example 3: AWS Promotion with PRM Secrets
name: AWS Infrastructure with Secrets
on:
push:
branches:
- main
paths:
- 'terraform/**'
- '.github/workflows/infra-promotion.yml'
permissions:
id-token: write
contents: write
actions: read
security-events: write
jobs:
aws-promote-with-secrets:
uses: dojo360/pipelines-workflows/.github/workflows/infrastructure-promotion.yml@beta
with:
aide-id: "<change me>"
cloud-type: "awsOptum"
domain: "<change me>"
deployment-path: "dev-qa-prod"
team-name: "<change me>"
# Terraform configuration
terraform-directory: "./terraform"
terraform-vars-files: "common.tfvars"
# PRM Secrets Management
prm-base-url: "https://prm.optum.com"
terraform-prm-secrets: "database-password,api-key,ssl-cert"
# AWS S3 backend
backend-type: "s3"
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
Example 4: Promotion with E2E Testing
name: Infrastructure Promotion with E2E Tests
on:
workflow_dispatch:
inputs:
deployment-path:
description: 'Environments to deploy'
required: true
permissions:
id-token: write
contents: write
actions: read
pull-requests: write
security-events: write
checks: write
jobs:
promote-with-tests:
uses: dojo360/pipelines-workflows/.github/workflows/infrastructure-promotion.yml@beta
with:
aide-id: "<change me>"
cloud-type: "awsOptum"
domain: "<change me>"
deployment-path: ${{ inputs.deployment-path }}
team-name: "<change me>"
terraform-directory: "./terraform"
# E2E Testing Configuration
e2e-tests-enabled-stages: "qa-prod" # Run tests after qa and prod deployments
e2e-workflow-file: "e2e-infrastructure-tests.yml"
e2e-workflow-inputs: |
{
"environment": "{{ environment }}",
"test-suite": "infrastructure-smoke-tests"
}
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
Example 5: EFIX Emergency Deployment
name: Emergency Fix Promotion
on:
push:
branches:
- 'efix-*' # Emergency fix branches
permissions:
id-token: write
contents: write
actions: read
security-events: write
jobs:
efix-promote:
uses: dojo360/pipelines-workflows/.github/workflows/infrastructure-promotion.yml@beta
with:
aide-id: "<change me>"
cloud-type: "awsOptum"
domain: "<change me>"
deployment-path: "cert-prod" # Skip dev/qa for emergency
team-name: "<change me>"
terraform-directory: "./terraform"
ref: ${{ github.ref }} # Use the efix branch reference
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
Example 6: GCS Backend with Custom Terraform Variables
name: GCP Infrastructure Promotion
on:
workflow_dispatch:
permissions:
id-token: write
contents: write
actions: read
security-events: write
jobs:
gcp-promote:
uses: dojo360/pipelines-workflows/.github/workflows/infrastructure-promotion.yml@beta
with:
aide-id: "<change me>"
cloud-type: "gcp"
domain: "<change me>"
deployment-path: "dev-qa-prod"
team-name: "<change me>"
# GCS Backend
backend-type: "gcs"
# Terraform configuration
terraform-directory: "./gcp-infra"
terraform-vars-files: "common.tfvars,gcp.tfvars"
terraform-vars-values: |
{
"project_id": "my-gcp-project",
"region": "us-central1",
"enable_monitoring": true
}
# Custom Terraform provider mirror
terraform-provider-network-mirror: "https://custom-mirror.company.com/terraform/providers/"
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
Best Practices
Deployment Path Design
- Match Team Metadata: Ensure
deployment-pathaligns with your team's configuredpromotion-path - Progressive Rollout: Use full path (
dev-qa-cert-prod) for maximum safety - Emergency Procedures: Define EFIX patterns in team metadata for critical fixes
- Environment Consistency: Use same environment names across all teams
Approval Strategy
- GitHub Environment Protection: Enable protection rules for production environments
- Required Reviewers: Assign appropriate reviewers for each environment
- Approval Timeouts: Configure reasonable wait times for approval gates
- Auto-Deployment for Lower: Consider auto-approval for dev/qa environments
Terraform State Management
- Consistent Backend: Use same backend type across all environments
- Environment Isolation: Use separate state files per environment
- State Locking: Ensure backend supports state locking (Azure/S3/GCS do)
- Backup Strategy: Implement state backup procedures
Secrets & Security
- PRM Integration: Use PRM for centralized secret management
- Environment Secrets: Store environment-specific secrets in GitHub Environments
- OIDC Preferred: Use OIDC authentication over static credentials
- Least Privilege: Grant minimum necessary permissions to service principals
Troubleshooting
Common Issues
1. Deployment Path Validation Failure
Symptom: parse_deployment_path job fails with path mismatch error
Solutions:
# Verify metadata configuration
# Check team metadata for promotion-path definition
# Ensure deployment-path is subset of or matches promotion-path
# Correct format examples:
deployment-path: "dev-qa-cert-prod" # ✅ Correct
deployment-path: "dev,qa,cert,prod" # ❌ Wrong separator
deployment-path: "dev-qa-prd" # ❌ Wrong environment name
2. OIDC Authentication Failures
Symptom: Terraform plan/apply fails with authentication errors
Solutions:
# Ensure permissions block includes id-token
permissions:
id-token: write # Required!
contents: write
# Verify cloud-type matches OIDC setup
with:
cloud-type: "awsOptum" # Use awsOptum for AWS OIDC
Support & Documentation
- Workflow Documentation: Infrastructure Promotion Guide
- Sample Applications: Infrastructure Samples
- Deployment Guide: Beyond Dev - Deployment & Promotion
- CloudBricks Documentation: Dojo360 CloudBricks
Note: This promotion workflow is designed for enterprise-scale infrastructure deployments with multiple environments and approval requirements. For single-environment deployments, use the Infrastructure Deployment workflow instead.
Related Assets
github-workflows-dojo360-azure-infrastructure
Deploy Azure infrastructure using Terraform with PCAM vaulted access and native Azure authentication through Dojo360 Azure Infrastructure workflow
Owner: pcorazao
github-workflows-dojo360-container-cd
Deploy containerized applications to AWS ECS/Azure ACS using Dojo360 Container CD workflow with blue-green and rolling update strategies
Owner: pcorazao
github-workflows-dojo360-container-promotion
Multi-environment container deployment promotion through prescribed deployment paths with automated approval gates and E2E testing
Owner: pcorazao
github-workflows-dojo360-database
Automate database schema updates using Liquibase via the Dojo360 database workflow (with rollback and validation patterns)
Owner: pcorazao
github-workflows-dojo360-database-promotion
Promote Liquibase database changes across environments (dev→qa→cert→prod) with deployment-path validation and approval gates
Owner: pcorazao
github-workflows-dojo360-dockerfile-ci
Build and scan container images from a Dockerfile using Optum golden images and the recommended UHG reusable workflow
Owner: pcorazao

