GitHub Actions Automation
GitHub Actions Automation
Overview
GitHub Actions serves as our primary CI/CD platform for automating Epic on Azure deployments, testing, and operations. This document covers GitHub Actions workflows, best practices, and integration patterns specific to our Epic workloads.
Why GitHub Actions for Epic on Azure?
Key Advantages
- Native Integration: Seamless integration with our GitHub repositories
- Scalable Runners: Self-hosted and GitHub-hosted runners for different needs
- Security: Built-in secrets management and OIDC authentication
- Ecosystem: Rich marketplace of actions and integrations
- Cost Effective: Generous free tier and competitive pricing
Epic-Specific Benefits
- Compliance: Audit trails and approval workflows for healthcare regulations
- Environment Promotion: Automated deployment pipelines across Epic environments
- Infrastructure Integration: Works seamlessly with Terraform and Ansible
- Monitoring: Built-in deployment tracking and notifications
Architecture
graph TB
A[GitHub Repository] --> B[GitHub Actions]
B --> C[Epic Production Workflow]
B --> D[Epic Non-Production Workflow]
B --> E[Infrastructure Workflow]
C --> F[Self-Hosted Runners]
D --> F
E --> F
F --> G[Terraform Apply]
F --> H[Ansible Playbook]
F --> I[Epic Deployment]
G --> J[Azure Resources]
H --> J
I --> J
J --> K[Epic Applications]
J --> L[Monitoring Setup]
J --> M[Compliance Validation]
Workflow Categories
1. Infrastructure Workflows
Automated provisioning and management of Azure resources:
name: Epic Infrastructure Deployment
on:
push:
branches: [main]
paths: ["infrastructure/**"]
pull_request:
branches: [main]
paths: ["infrastructure/**"]
env:
TF_VERSION: "1.5.0"
EPIC_ENVIRONMENT: ${{ github.ref_name }}
jobs:
terraform:
name: Terraform Epic Infrastructure
runs-on: [self-hosted, epic-terraform]
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
- name: Terraform Format Check
run: terraform fmt -check -recursive
- name: Terraform Security Scan
uses: aquasecurity/[email protected]
with:
soft_fail: false
- name: Terraform Plan
run: |
terraform init
terraform plan -out=tfplan \
-var="epic_environment=${{ env.EPIC_ENVIRONMENT }}" \
-var="epic_region=${{ vars.EPIC_REGION }}"
- name: Upload Plan Artifact
uses: actions/upload-artifact@v4
with:
name: terraform-plan
path: tfplan
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply tfplan
2. Application Deployment Workflows
Automated Epic application deployments:
name: Epic Application Deployment
on:
workflow_dispatch:
inputs:
epic_application:
description: "Epic Application"
required: true
type: choice
options:
- hyperspace
- chronicles
- clarity
- epic-reporting
environment:
description: "Target Environment"
required: true
type: choice
options:
- development
- testing
- staging
- production
jobs:
deploy:
name: Deploy Epic Application
runs-on: [self-hosted, epic-ansible]
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
- name: Setup Ansible
uses: ansible/ansible-action@v1
with:
ansible-version: "8.5.0"
- name: Configure AWX Credentials
env:
AWX_HOST: ${{ secrets.AWX_HOST }}
AWX_TOKEN: ${{ secrets.AWX_TOKEN }}
run: |
awx config set host $AWX_HOST
awx config set token $AWX_TOKEN
- name: Launch Epic Deployment Job
run: |
awx job_templates launch \
--name "Epic ${{ inputs.epic_application }} Deployment" \
--extra_vars "{
\"epic_application\": \"${{ inputs.epic_application }}\",
\"epic_environment\": \"${{ inputs.environment }}\",
\"deployment_version\": \"${{ github.sha }}\"
}" \
--monitor
3. Configuration Management Workflows
Automated server configuration and maintenance:
name: Epic Configuration Management
on:
schedule:
- cron: "0 2 * * 1-5" # Weekdays at 2 AM
workflow_dispatch:
inputs:
target_environment:
description: "Target Environment"
required: true
type: choice
options:
- development
- testing
- staging
- production
jobs:
configuration-drift:
name: Configuration Drift Detection
runs-on: [self-hosted, epic-ansible]
steps:
- uses: actions/checkout@v4
- name: Run Configuration Drift Check
run: |
ansible-playbook \
-i inventory/epic-${{ inputs.target_environment || 'development' }}.yml \
playbooks/epic-drift-detection.yml \
--check \
--diff
- name: Generate Drift Report
if: failure()
run: |
ansible-playbook \
-i inventory/epic-${{ inputs.target_environment || 'development' }}.yml \
playbooks/epic-drift-report.yml
- name: Upload Drift Report
if: failure()
uses: actions/upload-artifact@v4
with:
name: configuration-drift-report
path: reports/drift-report-*.html
remediation:
name: Configuration Remediation
runs-on: [self-hosted, epic-ansible]
needs: configuration-drift
if: failure()
environment: ${{ inputs.target_environment || 'development' }}
steps:
- uses: actions/checkout@v4
- name: Apply Configuration Remediation
run: |
ansible-playbook \
-i inventory/epic-${{ inputs.target_environment || 'development' }}.yml \
playbooks/epic-configuration-remediation.yml
4. Security and Compliance Workflows
Automated security scanning and compliance validation:
name: Epic Security and Compliance
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: "0 6 * * *" # Daily at 6 AM
jobs:
security-scan:
name: Security Scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Secrets Detection
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: main
head: HEAD
- name: Run SAST Analysis
uses: github/super-linter@v5
env:
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_ANSIBLE: true
VALIDATE_TERRAFORM: true
VALIDATE_YAML: true
- name: Run Infrastructure Security Scan
uses: aquasecurity/[email protected]
with:
working_directory: infrastructure/
- name: Run Container Security Scan
if: contains(github.event.head_commit.modified, 'docker/')
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "./docker"
compliance-check:
name: Epic Compliance Validation
runs-on: [self-hosted, epic-compliance]
steps:
- uses: actions/checkout@v4
- name: HIPAA Compliance Check
run: |
ansible-playbook \
playbooks/epic-hipaa-compliance.yml \
--check \
--extra-vars "compliance_standard=hipaa"
- name: SOC2 Compliance Check
run: |
ansible-playbook \
playbooks/epic-soc2-compliance.yml \
--check \
--extra-vars "compliance_standard=soc2"
- name: Generate Compliance Report
run: |
ansible-playbook \
playbooks/epic-compliance-report.yml \
--extra-vars "report_date=$(date +%Y-%m-%d)"
- name: Upload Compliance Report
uses: actions/upload-artifact@v4
with:
name: compliance-report-${{ github.sha }}
path: reports/compliance-*.pdf
Self-Hosted Runners
Epic-Specific Runner Configuration
Our self-hosted runners are configured for Epic workloads:
# .github/workflows/setup-epic-runner.yml
name: Setup Epic Runner
on:
workflow_dispatch:
inputs:
runner_type:
description: "Runner Type"
required: true
type: choice
options:
- epic-terraform
- epic-ansible
- epic-compliance
jobs:
setup-runner:
name: Setup Epic Runner
runs-on: ubuntu-latest
steps:
- name: Launch Azure VM
uses: azure/CLI@v1
with:
azcliversion: 2.30.0
inlineScript: |
az vm create \
--resource-group rg-epic-runners \
--name "runner-${{ inputs.runner_type }}-$(date +%s)" \
--image "Epic-Runner-Golden-Image" \
--size "Standard_D4s_v3" \
--admin-username "epic-runner" \
--ssh-key-values "${{ secrets.EPIC_RUNNER_SSH_KEY }}" \
--tags "runner-type=${{ inputs.runner_type }}" \
"auto-shutdown=true" \
"max-idle-time=30m"
- name: Configure Runner
run: |
# Runner configuration script
./scripts/configure-epic-runner.sh \
--type "${{ inputs.runner_type }}" \
--token "${{ secrets.GITHUB_RUNNER_TOKEN }}"
Runner Security
- Isolated Networks: Runners operate in dedicated subnets
- Just-in-Time Access: Temporary credentials for each job
- Image Hardening: Custom golden images with security baselines
- Audit Logging: Comprehensive logging of all runner activities
Advanced Patterns
1. Matrix Deployments
Deploy across multiple Epic environments simultaneously:
strategy:
matrix:
environment: [development, testing, staging]
epic_application: [hyperspace, chronicles, clarity]
fail-fast: false
max-parallel: 3
runs-on: [self-hosted, epic-${{ matrix.environment }}]
environment: ${{ matrix.environment }}
steps:
- name: Deploy ${{ matrix.epic_application }} to ${{ matrix.environment }}
run: |
awx job_templates launch \
--name "Epic ${{ matrix.epic_application }} Deployment" \
--extra_vars "{
\"epic_application\": \"${{ matrix.epic_application }}\",
\"epic_environment\": \"${{ matrix.environment }}\"
}"
2. Conditional Epic Deployments
Smart deployment logic based on changes:
- name: Detect Epic Application Changes
id: changes
uses: dorny/paths-filter@v2
with:
filters: |
hyperspace:
- 'applications/hyperspace/**'
chronicles:
- 'applications/chronicles/**'
clarity:
- 'applications/clarity/**'
infrastructure:
- 'infrastructure/**'
- name: Deploy Hyperspace
if: steps.changes.outputs.hyperspace == 'true'
run: ansible-playbook playbooks/epic-hyperspace-deploy.yml
- name: Deploy Chronicles
if: steps.changes.outputs.chronicles == 'true'
run: ansible-playbook playbooks/epic-chronicles-deploy.yml
- name: Update Infrastructure
if: steps.changes.outputs.infrastructure == 'true'
run: terraform apply -auto-approve
3. Epic Environment Promotion
Automated promotion between environments:
name: Epic Environment Promotion
on:
workflow_dispatch:
inputs:
source_environment:
description: "Source Environment"
required: true
type: choice
options: [development, testing, staging]
target_environment:
description: "Target Environment"
required: true
type: choice
options: [testing, staging, production]
jobs:
validate-promotion:
name: Validate Promotion
runs-on: [self-hosted, epic-validation]
steps:
- name: Validate Source Environment Health
run: |
ansible-playbook \
playbooks/epic-health-check.yml \
--extra-vars "epic_environment=${{ inputs.source_environment }}"
- name: Run Promotion Tests
run: |
ansible-playbook \
playbooks/epic-promotion-tests.yml \
--extra-vars "source=${{ inputs.source_environment }}" \
--extra-vars "target=${{ inputs.target_environment }}"
promote:
name: Promote Configuration
runs-on: [self-hosted, epic-ansible]
needs: validate-promotion
environment: ${{ inputs.target_environment }}
steps:
- name: Backup Target Environment
run: |
ansible-playbook \
playbooks/epic-environment-backup.yml \
--extra-vars "epic_environment=${{ inputs.target_environment }}"
- name: Promote Configuration
run: |
ansible-playbook \
playbooks/epic-environment-promotion.yml \
--extra-vars "source=${{ inputs.source_environment }}" \
--extra-vars "target=${{ inputs.target_environment }}"
- name: Validate Promotion
run: |
ansible-playbook \
playbooks/epic-post-promotion-validation.yml \
--extra-vars "epic_environment=${{ inputs.target_environment }}"
Integration with Epic Tools
1. AWX Integration
- name: Trigger AWX Job Template
uses: ansible/awx-action@v1
with:
awx-host: ${{ secrets.AWX_HOST }}
awx-token: ${{ secrets.AWX_TOKEN }}
job-template: "Epic Hyperspace Deployment"
extra-vars: |
{
"epic_environment": "${{ github.event.inputs.environment }}",
"epic_version": "${{ github.sha }}",
"deployment_type": "rolling"
}
wait: true
timeout: 3600
2. Azure DevOps Integration
- name: Trigger Azure DevOps Pipeline
uses: Azure/pipelines@v1
with:
azure-devops-project-url: ${{ secrets.AZDO_PROJECT_URL }}
azure-pipeline-name: "Epic-Database-Deployment"
azure-devops-token: ${{ secrets.AZDO_TOKEN }}
azure-pipeline-variables: |
{
"epicEnvironment": "${{ inputs.environment }}",
"epicApplication": "${{ inputs.epic_application }}"
}
3. Monitoring Integration
- name: Create Deployment Marker
uses: DataDog/deployment-marker-action@v1
with:
api-key: ${{ secrets.DATADOG_API_KEY }}
app-key: ${{ secrets.DATADOG_APP_KEY }}
service: "epic-${{ inputs.epic_application }}"
env: ${{ inputs.environment }}
version: ${{ github.sha }}
tags: |
team:epic-platform
deployment-method:github-actions
Best Practices
Security
- Secrets Management: Use GitHub secrets and environment-specific variables
- OIDC Authentication: Passwordless authentication to Azure
- Least Privilege: Minimal permissions for each workflow
- Audit Logging: Comprehensive logging of all activities
Reliability
- Timeout Handling: Set appropriate timeouts for long-running jobs
- Retry Logic: Implement retry mechanisms for transient failures
- Rollback Procedures: Automated rollback on deployment failures
- Health Checks: Validate deployments before marking as successful
Performance
- Caching: Cache dependencies and artifacts between runs
- Parallel Execution: Use matrix strategies for parallel deployments
- Resource Optimization: Right-size runner resources for workloads
- Workflow Optimization: Minimize workflow execution time
Troubleshooting
Common Issues
-
Runner Connectivity: Check network configuration and firewall rules
-
Secret Access: Verify secret scope and permissions
-
Resource Limits: Monitor runner resource utilization
-
Workflow Timeouts: Adjust timeout values for long-running operations
Debugging Tips
- Workflow Logs: Enable debug logging with
ACTIONS_STEP_DEBUG - Runner Diagnostics: Use runner diagnostic scripts
- Job Artifacts: Capture logs and reports as artifacts
- Workflow Visualization: Use workflow visualization tools
Monitoring and Observability
Workflow Metrics
- Success/Failure Rates: Track deployment success rates
- Duration Metrics: Monitor workflow execution times
- Resource Utilization: Track runner resource usage
- Error Patterns: Identify common failure modes
Integration with Epic Monitoring
- name: Send Deployment Metrics
run: |
curl -X POST "${{ secrets.EPIC_METRICS_ENDPOINT }}" \
-H "Content-Type: application/json" \
-d "{
\"metric\": \"epic.deployment.completed\",
\"value\": 1,
\"tags\": [
\"application:${{ inputs.epic_application }}\",
\"environment:${{ inputs.environment }}\",
\"status:success\"
]
}"
Related Documentation
Support
- GitHub Actions: Enterprise support through GitHub
- Runner Infrastructure: Internal platform team
- Workflow Development: DevOps engineering team
- Training: Regular workshops and certification programs