Navigation
Best PracticesUpdated July 3, 2026

Golden Image CI/CD Pipeline

best-practicesgolden-imagespackerterraformansiblevaultgithub-actionscicdautomation

Key Components

  1. GitHub Actions: CI/CD orchestration.
  2. Terraform: Infrastructure provisioning (VMs, networking, etc.).
  3. Ansible: Configuration management and post-deployment orchestration.
  4. Vault: Secrets and credentials management.
  5. Packer: For creating the golden images.

Workflow/Pipeline Breakdown

Step 1: GitHub Actions - Pipeline Orchestration

  1. Trigger Event:

    • The pipeline can be triggered manually, on a schedule, or through a new release event, based on updates to the golden image, environment configuration, or application code.
    • Example on: schedule to run regularly for base image refreshes.
  2. Vault Checkout:

    Vault Checkout

    • GitHub Actions + Terraform Enterprise integrates with Vault to securely retrieve any secrets or credentials needed during the pipeline. Link:
  3. Environment Preparation:

    • Define environment variables for the specific build (e.g., region, machine typeapplication role).
    • Set environment-specific parameters, including multi-region configurations.
  4. Packer Build (Golden Image Update):

    • If a new golden image is needed (e.g., for a new application version or security update), the pipeline triggers Packer to create a new base image.
    • Packer retrieves secrets like Windows licensing information or domain credentials from Vault.
    - name: Build Base Image
      run: |
        packer build -var 'vault_token=${{ steps.vault.outputs.token }}' base-image.json
    

Step 2: Terraform - Infrastructure Provisioning

  1. Terraform Plan and Apply:

    • After the golden image is confirmed or built, Terraform provisions the necessary infrastructure. This could be VMs for different Epic roles (VDI, web, app, DB), as well as networking components.
    • Vault Integration: Use Terraform’s Vault provider to retrieve sensitive credentials (e.g., SSH keys, database passwords).
    • Terraform uses these secrets to configure the VMs (e.g., network settings, user access).

    Example Terraform configuration to retrieve secrets:

    provider "vault" {
        address = "
    https://vault.yourdomain.com
    "
    }
    data "vault_generic_secret" "azure_credentials" {
        path = "secret/data/azure-credentials"
    }
    resource "azurerm_virtual_machine" "epic_vm" {
        # VM definition
        os_profile {
        admin_username = "adminuser"
        admin_password = data.vault_generic_secret.azure_credentials.data["password"]
        }
    }
    
  2. Terraform Module Structure:

    • Use Terraform modules to define reusable infrastructure for each Epic role (VDI, web, app, DB).
    • Include region-specific modules for multi-region deployments.
    • Terraform applies these configurations using the output from Vault for credentials (e.g., storage account access keys, database connection strings).

Step 3: Ansible - Post-Deployment Configuration & Orchestration

  1. Post-Deployment Configuration:

    • After Terraform provisions the infrastructure, Ansible performs configuration management for the newly provisioned VMs.
    • Ansible Vault Integration: Use Ansible Vault to securely retrieve credentials and secrets for tasks like domain joining, installing certificates, and configuring application roles (web, app, DB, VDI).
    • Example Ansible playbook to join the domain using credentials stored in Vault
    - hosts: epic-servers
      tasks:
        - name: Retrieve domain join credentials
          hashivault_read:
            secret: "secret/data/domain-join"
          register: domain_creds
        - name: Join the domain
          win_domain_membership:
            name: "{{ ansible_hostname }}"
            domain_name: "corp.contoso.com"
            domain_admin_user: "{{ domain_creds.data.username }}"
            domain_admin_password: "{{ domain_creds.data.password }}"
    
  2. Application-Specific Configuration:

    • Ansible configures the application stack for each role (e.g., VDI, web, app, DB), pulling role-specific configurations from Vault and any central configuration databases.
    • For example, database credentials, certificates, or API keys are retrieved from Vault and applied during the post-deployment process.
  3. Orchestration:

    • Ansible ensures services are started in the correct order, particularly for DB, app, and web servers that depend on one another.
    • Ensure all services are registered correctly with other cluster services (e.g., app servers registering with DB clusters, web servers registering with load balancers).
    • Additional tasks like setting up monitoring and logging (e.g., connecting to Splunk or other log aggregation services) can also be handled by Ansible post-deployment.

Step 4: Final Image Capture (Packer)

  1. Post-Configuration Image Capture:

    • After all configurations are applied by Ansible, a final image capture using Packer or another image tool creates a reusable pre-configured image artifact for each Epic platform role.
    • The final image can be stored in a central image repository (e.g., Azure Shared Image Gallery, AWS AMIs) for reuse in future deployments.
  2. Tagging and Versioning:

    • Ensure each image is tagged and versioned according to the application version, environment, and role.
    • Example Packer build to create a reusable image from a configured VM:
    packer build -var 'source_vm=my-configured-vm' -var 'image_name=epic-web-server-v1' my-image.json
    

Step 5: Deployment to Production and Multi-Region Rollout

  1. Region-Specific Deployment:

    • Using Terraform and Ansible, deploy the pre-configured images to production environments across multiple regions.
    • Multi-region deployments can use different network and storage configurations based on the region-specific modules within Terraform.
  2. Monitoring and Alerting:

    • Integrate with monitoring tools (e.g., Prometheus, Azure Monitor) to ensure that the deployed resources are healthy.
    • Include any Vault secrets needed for connecting to monitoring tools.

Step 6: Pipeline Success and Cleanup

  1. Clean Up Temporary Resources:

    • Once the images are captured and stored, tear down any temporary infrastructure used for testing or validation during the pipeline.
    • Use Terraform destroy commands in GitHub Actions for this purpose.
  2. Logging and Audit:

    • Ensure that all logs from GitHub Actions, Terraform, and Ansible runs are securely stored for auditing purposes.
    • Vault’s audit logs can track secret access and usage during the pipeline.

GitHub Actions Workflow Example

name: Build and Deploy Epic Images
on:
 push:
   branches:
     - main
 schedule:
   - cron: "0 1 * * *"  # Nightly build for updated images
jobs:
 build-and-deploy:
   runs-on: ubuntu-latest
   steps:
     - name: Checkout Repository
       uses: actions/checkout@v2
     - name: Login to Vault
       uses: hashicorp/[email protected]
       with:
         url:
https://vault.yourdomain.com
         method: github
         githubToken: ${{ secrets.GITHUB_TOKEN }}
     - name: Set up Terraform
       uses: hashicorp/setup-terraform@v1
     - name: Terraform Init
       run: terraform init
     - name: Terraform Plan
       run: terraform plan -out=plan.tfplan
     - name: Terraform Apply
       run: terraform apply plan.tfplan
     - name: Ansible Playbook
       run: ansible-playbook -i inventory/epic-servers.yml playbooks/configure-epic.yml
     - name: Finalize Image
       run: packer build -var 'source_vm=epic-vm' packer/image-final.json

This pipeline ties together GitHub Actions for CI/CD orchestration, Terraform for provisioning infrastructure, Ansible for post-deployment configuration and orchestration, Vault for secret management, and Packer for image creation. It’s designed to create pre-configured, reusable images for different Epic platform roles across multiple environments and regions, securely managing credentials and secrets throughout the process.