Skip to content

github-workflows-dojo360-infrastructure-promotion

Multi-environment infrastructure promotion workflow with deployment path validation and approval gates

active
IDE:
claude
codex
vscode
Version:
1.0.0
Owner:pcorazao
github-actions
workflow
dojo360

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-path with promotion-path in 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_X jobs act as approval gateways
  • Protection Rules: Integrates with GitHub environment protection rules

Infrastructure Reusability

  • Infrastructure Workflow Reuse: Calls infrastructure.yml@beta for 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-path defining valid environment progression
  • deployment-path must match or be a subset of promotion-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 awsOptum or azureOptum cloud types
  • Instance Profile: For awsChc20 cloud 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

InputTypeDescription
aide-idStringREQUIRED. The Aide ID used to fetch metadata
cloud-typeStringREQUIRED. Cloud provider type. Valid values: awsOptum, awsChc20, azureOptum, gcp
domainStringREQUIRED. Domain used to fetch metadata
deployment-pathStringREQUIRED. Deployment path as hyphen-separated environments (e.g., dev-qa-cert-prod)
team-nameStringREQUIRED. Team name used to fetch metadata

Common Optional Inputs

InputTypeDefaultDescription
backend-typeStringazurermBackend type for Terraform state. Options: azurerm, s3, gcs
pcam-roleStringcontributorAzure PCAM role for Service Principal
terraform-directoryString.Directory path relative to repository root containing Terraform code
terraform-vars-filesString""Comma-separated list of tfvars files
terraform-vars-valuesString""JSON string of tfvars variables
terraform-prm-secretsString""Comma-separated list of PRM secrets to map to tfvars
terraform-provider-network-mirrorStringhttps://repo1.uhc.com/artifactory/api/terraform/terraform-virtual/providers/Terraform provider mirror URL
refString""Git branch, tag, or SHA to checkout. Defaults to triggering reference
remote-state-file-nameString""Fully qualified remote state filename
remote-state-folder-nameString""Remote state folder name
runner-labelsString""Comma-separated custom runner labels

E2E Testing Inputs

InputTypeDefaultDescription
e2e-tests-enabled-stagesString""Stages where E2E tests should run (hyphen-separated, e.g., qa-prod)
e2e-workflow-fileString""Workflow file name for E2E tests
e2e-workflow-inputsString""JSON data with E2E workflow input overrides

Secrets Management

InputTypeDefaultDescription
prm-base-urlStringhttps://prm.optum.comPRM instance base URL for secret retrieval

Required Secrets

SecretDescription
GH_TOKENGitHub Personal Access Token with repo permissions

Workflow Job Structure

The promotion workflow creates the following jobs automatically based on your deployment-path:

Core Jobs

  1. parse_deployment_path - Validates deployment path against promotion path in metadata
  2. environment_1 - Deploys to first environment (e.g., dev)
  3. trigger_environment_2 - Approval gateway to second environment
  4. environment_2 - Deploys to second environment (e.g., qa)
  5. trigger_environment_3 - Approval gateway to third environment
  6. environment_3 - Deploys to third environment (e.g., cert)
  7. trigger_environment_4 - Approval gateway to fourth environment
  8. environment_4 - Deploys to fourth environment (e.g., prod)
  9. trigger_environment_5 - Approval gateway (if 5th environment exists)
  10. environment_5 - Deploys to fifth environment (if applicable)

Job Dependencies

  • Each environment_X job depends on successful completion of previous trigger_environment_X job
  • trigger_environment_X jobs act as manual approval gates when GitHub environment protection is enabled
  • All jobs depend on successful parse_deployment_path validation

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

  1. Match Team Metadata: Ensure deployment-path aligns with your team's configured promotion-path
  2. Progressive Rollout: Use full path (dev-qa-cert-prod) for maximum safety
  3. Emergency Procedures: Define EFIX patterns in team metadata for critical fixes
  4. Environment Consistency: Use same environment names across all teams

Approval Strategy

  1. GitHub Environment Protection: Enable protection rules for production environments
  2. Required Reviewers: Assign appropriate reviewers for each environment
  3. Approval Timeouts: Configure reasonable wait times for approval gates
  4. Auto-Deployment for Lower: Consider auto-approval for dev/qa environments

Terraform State Management

  1. Consistent Backend: Use same backend type across all environments
  2. Environment Isolation: Use separate state files per environment
  3. State Locking: Ensure backend supports state locking (Azure/S3/GCS do)
  4. Backup Strategy: Implement state backup procedures

Secrets & Security

  1. PRM Integration: Use PRM for centralized secret management
  2. Environment Secrets: Store environment-specific secrets in GitHub Environments
  3. OIDC Preferred: Use OIDC authentication over static credentials
  4. 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


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