Golden Image CI/CD Pipeline
Key Components
- GitHub Actions: CI/CD orchestration.
- Terraform: Infrastructure provisioning (VMs, networking, etc.).
- Ansible: Configuration management and post-deployment orchestration.
- Vault: Secrets and credentials management.
- Packer: For creating the golden images.
Workflow/Pipeline Breakdown
Step 1: GitHub Actions - Pipeline Orchestration
-
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: scheduleto run regularly for base image refreshes.
-
Vault Checkout:
- GitHub Actions + Terraform Enterprise integrates with Vault to securely retrieve any secrets or credentials needed during the pipeline. Link:
-
Environment Preparation:
- Define environment variables for the specific build (e.g., region, machine typeapplication role).
- Set environment-specific parameters, including multi-region configurations.
-
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
-
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"] } } -
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
-
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 }}" -
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.
-
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)
-
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.
-
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
-
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.
-
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
-
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.
-
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.