Perplexity ‐ Packer and HashiCorp Vault - sathishkpr/ptactions GitHub Wiki
Automating AWS Infrastructure with HashiCorp Packer, GitHub Actions, and Vault for Secure Auto-Scaling
This report provides a technical blueprint for implementing a secure infrastructure automation pipeline that combines HashiCorp Packer for machine image creation, GitHub Actions for workflow orchestration, HashiCorp Vault for credential management, and AWS Auto Scaling for dynamic resource provisioning. The solution addresses the challenge of securely deploying auto-scaled EC2 instances while maintaining strict control over sensitive credentials. Key innovations include the integration of Vault-managed AWS keys into GitHub Actions workflows and the automated propagation of Packer-generated AMIs to Terraform-managed auto-scaling groups.
Architecture Overview
GitHub Actions as the Orchestration Engine
GitHub Actions serves as the central workflow controller, coordinating the image-building process with Packer, credential retrieval from Vault, and infrastructure updates via Terraform. The hashicorp/setup-packer
Action ensures proper CLI versioning and execution environment configuration[1]. Workflows are triggered by code changes to Packer templates or infrastructure definitions, enabling continuous integration of both application and infrastructure components.
The pipeline structure follows a phased approach:
- Image Construction: Packer executes provisioning scripts against a base AWS AMI
- Secret Injection: Vault provides temporary AWS credentials via authenticated API calls
- Validation & Publishing: Built images undergo automated testing before registration in AWS
- Infrastructure Synchronization: Terraform applies updated launch templates referencing new AMIs
Secure Credential Management with Vault
Vault-GitHub Actions Integration
The hashicorp/vault-action
enables secure retrieval of AWS credentials without persistent secrets in GitHub repositories[8]. A dedicated Vault authentication path for GitHub workflows uses JWT tokens from GitHub's OIDC provider to generate short-lived AWS credentials:
- name: Retrieve AWS Credentials
uses: hashicorp/vault-action@v2
with:
url: https://vault.prod.example.com
method: jwt
role: github-actions-packer
secrets: |
aws/creds/packer-role access_key | AWS_ACCESS_KEY_ID
aws/creds/packer-role secret_key | AWS_SECRET_ACCESS_KEY
This configuration maps Vault-generated AWS credentials to environment variables used by subsequent workflow steps. The AWS credentials are automatically revoked after 15 minutes, complying with zero-trust security principles[9].
Packer Image Build Automation
Template Configuration with Dynamic Credentials
Packer templates consume AWS credentials from environment variables set by the GitHub Actions workflow:
source "amazon-ebs" "web-server" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = "us-west-2"
ami_name = "web-server-${local.timestamp}"
instance_type = "t3.micro"
}
build {
sources = ["source.amazon-ebs.web-server"]
provisioner "shell" {
script = "scripts/configure-nginx.sh"
}
}
The workflow securely injects credentials using Vault-derived environment variables:
- name: Build AMI
run: packer build -var aws_access_key=${{ env.AWS_ACCESS_KEY_ID }} -var aws_secret_key=${{ env.AWS_SECRET_ACCESS_KEY }} web-server.pkr.hcl
Critical security practices include:
- Ephemeral Credentials: AWS keys are valid only for the workflow duration
- Least Privilege: Vault role restricts Packer to specific EC2 and AMI operations
- Audit Trail: Vault logs all credential issuance events
Auto-Scaling Integration
Terraform Infrastructure as Code
The Terraform configuration manages auto-scaling groups and launch templates referencing Packer-built AMIs:
data "aws_ami" "web_server" {
most_recent = true
owners = ["self"]
filter {
name = "name"
values = ["web-server-*"]
}
}
resource "aws_launch_template" "web" {
name_prefix = "web-"
image_id = data.aws_ami.web_server.id
instance_type = "t3.micro"
}
resource "aws_autoscaling_group" "web" {
availability_zones = ["us-west-2a"]
desired_capacity = 2
max_size = 5
min_size = 1
launch_template {
id = aws_launch_template.web.id
version = "$Latest"
}
}
End-to-End Workflow Implementation
Phase 1: Image Build Pipeline
name: Packer Build
on:
push:
paths:
- 'packer/*.pkr.hcl'
- 'scripts/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Packer
uses: hashicorp/setup-packer@main
- name: Get AWS Credentials
uses: hashicorp/vault-action@v2
id: vault
with:
url: https://vault.example.com
method: jwt
role: packer-builder
exportEnv: true
secrets: |
aws/creds/packer access_key | AWS_ACCESS_KEY_ID
aws/creds/packer secret_key | AWS_SECRET_ACCESS_KEY
- name: Build Image
run: packer build web-server.pkr.hcl
- name: Output AMI ID
id: ami
run: echo "AMI_ID=$(jq -r '.builds[-1].artifact_id' manifest.json | cut -d':' -f2)" >> $GITHUB_OUTPUT
Phase 2: Infrastructure Update
name: Terraform Deploy
on:
workflow_run:
workflows: ["Packer Build"]
types:
- completed
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v3
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
- name: Terraform Apply
run: terraform apply -auto-approve
Security Architecture
Credential Lifecycle Management
- Vault Authentication: GitHub Actions authenticates via OIDC JWT tokens
- Dynamic Secrets: AWS credentials generated per-run with 15-minute TTL
- Automatic Rotation: Vault's AWS secrets engine rotates underlying IAM keys
- Network Security: Vault communication over TLS with IP whitelisting
# Vault AWS Secrets Engine Configuration
resource "vault_aws_secret_backend" "aws" {
access_key = var.vault_aws_access_key
secret_key = var.vault_aws_secret_key
}
resource "vault_aws_secret_backend_role" "packer" {
backend = vault_aws_secret_backend.aws.path
name = "packer"
credential_type = "iam_user"
policy_document = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["ec2:*", "iam:*"]
Resource = "*"
}]
})
}
Auto-Scaling Pattern Implementation
Dynamic Instance Configuration
New auto-scaled instances retrieve runtime configuration from Vault using IAM instance profiles:
#!/bin/bash
VAULT_ADDR="https://vault.example.com"
# Retrieve instance identity document
PKCS7=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 | tr -d '\n')
# Get Vault token using AWS auth method
VAULT_TOKEN=$(curl -s -X POST $VAULT_ADDR/v1/auth/aws/login \
-d "{\"role\":\"web-server\", \"pkcs7\":\"$PKCS7\"}" | jq -r .auth.client_token)
# Retrieve application secrets
APP_CONFIG=$(curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/secret/data/web/config | jq -r .data.data)
This pattern enables:
- Zero Hardcoded Secrets: Credentials never persist on disk
- Automatic Secret Rotation: Vault manages credential lifecycle
- Instance-Specific Permissions: IAM roles restrict Vault access per ASG
Operational Monitoring
Cross-Tool Observability
- Vault Audit Logs: Track all credential access attempts
- AWS CloudTrail: Monitor API calls from Packer and Terraform
- GitHub Actions Logging: Centralized workflow execution history
- Prometheus Metrics:
- Packer build durations
- AMI deployment velocity
- Auto-scaling group fluctuation rates
resource "aws_cloudtrail" "packer" {
name = "packer-ami-creation"
s3_bucket_name = aws_s3_bucket.audit_logs.id
event_selector {
read_write_type = "WriteOnly"
include_management_events = true
data_resource {
type = "AWS::EC2::Image"
values = ["arn:aws:ec2:::image/*"]
}
}
}
Conclusion
This implementation establishes a secure, automated pipeline for AWS infrastructure management that addresses key cloud security challenges. By integrating Vault's dynamic credential management with GitHub Actions' workflow automation and Packer's image-building capabilities, organizations achieve:
- Auditable Secret Lifecycle: All AWS credential usage tracked in Vault logs
- Immutable Infrastructure: Packer-built AMIs enable consistent deployments
- Elastic Scaling: Terraform-managed ASGs automatically adjust to load
- Developer Velocity: Full CI/CD pipeline for infrastructure changes
Future enhancements could incorporate HashiCorp Consul for service mesh integration and Nomad for workload orchestration, creating a complete HashiStack solution. The architecture demonstrates how modern DevOps tools combine to create secure, self-healing cloud infrastructure.
Citations: [1] https://github.com/hashicorp/setup-packer [2] https://serverfault.com/questions/1085387/run-github-actions-workflow-ec2-auto-scaled-servers [3] https://github.com/hashicorp-modules/hashistack-aws [4] https://developer.hashicorp.com/packer/tutorials/cloud-production/github-actions [5] https://www.ingeniumcode.io/cicd-github-actions-separate-workflows/ [6] https://www.ivobeerens.nl/blog/2024/06/pass-github-variable-to-packer-powershell-provisioner/ [7] https://github.com/hashicorp/terraform-aws-vault [8] https://developer.hashicorp.com/vault/tutorials/app-integration/github-actions [9] https://austincloud.guru/2021/03/01/secrets-in-aws-user_data-via-hashicorp's-vault/ [10] https://dev.to/aws-builders/using-github-actions-to-build-packer-ami-on-aws-3p12 [11] https://github.com/aws-samples/ec2-auto-scaling-instance-refresh-sample [12] https://www.infralovers.com/blog/2024-10-17-hashicorp-packer-github-actions/ [13] https://repost.aws/questions/QUIPP5MKaNRpmpQNhiAFFh5g/create-new-ami-only-on-updates [14] https://developer.hashicorp.com/vault/docs/platform/github-actions [15] https://github.com/hashicorp/vault-action [16] https://www.reddit.com/r/hashicorp/comments/1hzz3r4/access_secrets_from_hashicorp_vault_in_github/ [17] https://codemyworld.hashnode.dev/packer-to-create-ami-golden-image-in-aws [18] https://www.reddit.com/r/hashicorp/comments/17s5auo/vaultaction_in_github_actions/ [19] https://www.youtube.com/watch?v=Vl5dO3EzNJ0 [20] https://github.com/hashicorp/packer/blob/master/website/content/docs/templates/hcl_templates/functions/contextual/vault.mdx [21] https://github.com/daveshepherd/packer-vault [22] https://github.com/giuliocalzolari/terraform-aws-vault-raft [23] https://www.youtube.com/watch?v=eN8QQCLrpyE [24] https://registry.terraform.io/modules/giuliocalzolari/vault-raft/aws/latest [25] https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/automatically-rotate-iam-user-access-keys-at-scale-with-aws-organizations-and-aws-secrets-manager.html [26] https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/create-a-pipeline-and-ami-using-codepipeline-and-hashicorp-packer.html [27] https://faun.pub/serverless-packer-ami-build-ci-cd-and-asg-instance-refresh-9851c211310e [28] https://aws.amazon.com/blogs/devops/best-practices-working-with-self-hosted-github-action-runners-at-scale-on-aws/ [29] https://github.com/hashicorp-modules/vault-aws [30] https://github.com/hashicorp/terraform-aws-vault/blob/master/modules/vault-cluster/README.md [31] https://stackoverflow.com/questions/61455092/terraform-autoscaling-listen-for-new-ami-and-deploy-automatically [32] https://www.reddit.com/r/aws/comments/zukahi/ec2_auto_scaling_deployment_options/ [33] https://github.com/jonico/auto-scaling-github-runners-ec2-issueops/blob/master/README.md