Overview
The starter kit includes GitHub Actions workflows that validate and deploy CloudFormation templates when you push to main. Workflows use OIDC authentication, run security scans, and deploy with Rain.
Workflow structure
The starter kit includes three workflow files:
| Workflow | Purpose |
|---|---|
cfn-lint-scan.yml | Template syntax and best practices validation |
checkov-scan.yml | Security and compliance scanning |
cloudformation-deploy-<env>.yml | Environment-specific deployment |
Sample workflow
name: Deploy CloudFormation Templates to Test Account
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
security-events: write
actions: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ vars.TEST_AWS_ACCOUNT_ID }}:role/GitHubActionsServiceRole
aws-region: ${{ vars.AWS_REGION }}
- name: Install Rain
run: |
RAIN_VERSION=$(curl -s https://api.github.com/repos/aws-cloudformation/rain/releases/latest | jq -r .tag_name)
curl -L -o rain.zip "https://github.com/aws-cloudformation/rain/releases/download/${RAIN_VERSION}/rain-${RAIN_VERSION}_linux-amd64.zip"
unzip rain.zip
chmod +x rain-${RAIN_VERSION}_linux-amd64/rain
sudo mv rain-${RAIN_VERSION}_linux-amd64/rain /usr/local/bin/
rm -rf rain-${RAIN_VERSION}_linux-amd64 rain.zip
rain --version
- name: Setup cfn-lint
uses: scottbrenner/cfn-lint-action@v2
- name: Run cfn-lint
run: cfn-lint
- name: Run Checkov
uses: bridgecrewio/checkov-action@v12
with:
config_file: .checkov.yml
- name: Deploy templates
run: ./scripts/deploy-templates.sh -e test
Note: Replace
testwith your environment name (e.g.,staging,production) and update the corresponding GitHub variable (e.g.,STAGING_AWS_ACCOUNT_ID).
Job steps explained
1. Configure AWS credentials
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ vars.TEST_AWS_ACCOUNT_ID }}:role/GitHubActionsServiceRole
aws-region: ${{ vars.AWS_REGION }}
Uses OIDC to assume an IAM role without storing credentials:
TEST_AWS_ACCOUNT_ID- GitHub variable with your account IDAWS_REGION- GitHub variable for your default region
2. Install Rain
Downloads and installs the latest Rain CLI for CloudFormation deployments.
3. Run cfn-lint
Validates templates against AWS resource specifications and best practices. Uses .cfnlintrc for configuration.
4. Run Checkov
Scans templates for security misconfigurations. Uses .checkov.yml for configuration.
5. Deploy templates
Runs ./scripts/deploy-templates.sh to deploy all templates with Rain.
Validation gates
The workflow implements fail-fast validation:
| Gate | Description |
|---|---|
| Template syntax | cfn-lint catches structural errors |
| Security compliance | Checkov blocks insecure configurations |
| Deployment validation | Rain validates against AWS APIs |
| Stack creation | CloudFormation validates final deployment |
If any gate fails, the workflow stops before changes reach AWS.
OIDC authentication
Workflows use OpenID Connect for secure, keyless AWS authentication:
permissions:
id-token: write # Request OIDC token
contents: read # Read repository files
security-events: write # Write Checkov findings
Benefits:
- No AWS credentials in GitHub Secrets
- Temporary credentials with automatic expiration
- Repository-scoped access control
- Full audit trail via CloudTrail
Multi-environment deployments
Create separate workflow files per environment:
.github/workflows/
├── cloudformation-deploy-test.yml # TEST_AWS_ACCOUNT_ID
├── cloudformation-deploy-staging.yml # STAGING_AWS_ACCOUNT_ID
└── cloudformation-deploy-production.yml # PRODUCTION_AWS_ACCOUNT_ID
Each workflow uses different:
- IAM role ARNs (different account IDs)
- GitHub variables
- Parameter files
Customization
Pull request validation
Add a validation-only workflow for PRs:
name: Validate CloudFormation Templates
on:
pull_request:
branches: [main]
permissions:
contents: read
security-events: write
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: scottbrenner/cfn-lint-action@v2
- run: cfn-lint
- uses: bridgecrewio/checkov-action@v12
with:
config_file: .checkov.yml
Notifications
Add Slack notifications:
- name: Notify on failure
if: failure()
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} \
-H 'Content-Type: application/json' \
-d '{"text":"CloudFormation deployment failed"}'
Observability
Workflow logs
Rain logs stack events directly to workflow output:
- Detailed deployment progress
- Real-time CloudFormation events
- Resource create/update/delete visibility
CloudFormation console
For deeper troubleshooting:
- Open CloudFormation console in your target account
- Navigate to the stack matching your template name
- Review Events and Resources tabs
GitHub Security tab
Checkov findings appear under Security → Code scanning alerts.
Next steps
- Linting and Code Analysis - Configure validation tools
- Scripts Reference - Deployment script details
- Local Development - Run validation locally