Overview
The starter kit includes GitHub Actions workflows that automatically validate and deploy CloudFormation templates when you push to the main branch. The workflow uses OIDC authentication, runs security scans, and deploys templates with Rain.
Sample workflow
Here's a complete example workflow for deploying to a test environment:
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 Cloud Formation Linter with Latest Version
uses: scottbrenner/cfn-lint-action@v2
- name: Run Cloud Formation Linter
run: cfn-lint
- name: Checkov GitHub Action
uses: bridgecrewio/checkov-action@v12
with:
config_file: .checkov.yml
- name: Deploy CloudFormation templates
run: ./scripts/deploy-templates.sh
Workflow breakdown
Trigger
on:
push:
branches: [main]
The workflow triggers automatically on every push to the main branch. This ensures that all changes merged to main are immediately validated and deployed.
Customization options:
- Add pull request triggers for validation-only runs
- Add manual workflow dispatch for on-demand deployments
- Add scheduled triggers for periodic reconciliation
Permissions
permissions:
id-token: write # Required for OIDC authentication
contents: read # Read repository contents
security-events: write # Write security scan results
actions: read # Read workflow run information
These permissions enable:
- id-token: write — Allows the workflow to request an OIDC token for AWS authentication
- contents: read — Grants access to repository files (templates, scripts, configuration)
- security-events: write — Enables Checkov to write security findings to GitHub Security tab
- actions: read — Allows reading workflow run metadata
Job steps
1. Checkout repository
- uses: actions/checkout@v4
Clones the repository so subsequent steps can access templates, scripts, and configuration files.
2. 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 in your AWS account without storing long-lived credentials:
- role-to-assume — IAM role created by the OIDC provider template
- TEST_AWS_ACCOUNT_ID — GitHub variable containing your AWS account ID
- AWS_REGION — GitHub variable for your default region
This step sets AWS credentials in the environment for all subsequent steps.
3. Install Rain
- 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
Installs the latest version of Rain from GitHub releases:
- Fetches the latest release tag from the Rain repository
- Downloads the Linux AMD64 binary
- Extracts and installs to
/usr/local/bin - Verifies installation by printing the version
Rain is used for deploying CloudFormation templates with enhanced features like better error messages and automatic parameter inference.
4. Setup cfn-lint
- name: Setup Cloud Formation Linter with Latest Version
uses: scottbrenner/cfn-lint-action@v2
Installs cfn-lint, the CloudFormation template validator. This action automatically installs Python and the latest version of cfn-lint.
5. Run cfn-lint
- name: Run Cloud Formation Linter
run: cfn-lint
Validates all CloudFormation templates against:
- AWS resource specifications
- Template syntax and structure
- Best practices and common errors
Uses the .cfnlintrc configuration file for template selection and rule configuration. The workflow fails if any errors are detected.
For more details, see the cfn-lint reference.
6. Run Checkov
- name: Checkov GitHub Action
uses: bridgecrewio/checkov-action@v12
with:
config_file: .checkov.yml
Scans templates for security misconfigurations and compliance violations:
- Uses the
.checkov.ymlconfiguration file - Checks for security best practices (encryption, access controls, logging)
- Validates compliance frameworks (PCI-DSS, HIPAA, CIS)
- Reports findings to GitHub Security tab
The workflow fails if critical security issues are detected.
For more details, see the Checkov reference.
7. Deploy templates
- name: Deploy CloudFormation templates
run: ./scripts/deploy-templates.sh
Deploys all CloudFormation templates using Rain:
- Iterates through templates in the
templates/directory - Matches each template with its corresponding parameter file
- Deploys stacks with
rain deploy --yes - Fails the workflow if any deployment fails
For more details, see the Scripts reference.
Validation gates
The workflow implements a fail-fast approach with multiple validation gates:
- Template syntax — cfn-lint catches structural errors before deployment
- Security compliance — Checkov blocks insecure configurations
- Deployment validation — Rain validates templates against AWS APIs
- Stack creation — CloudFormation service validates the final deployment
If any gate fails, the workflow stops and no changes reach AWS.
Multi-environment deployments
To deploy to multiple environments (test, staging, production), create separate workflow files:
.github/workflows/
├── deploy-test.yml # Deploys to TEST_AWS_ACCOUNT_ID
├── deploy-staging.yml # Deploys to STAGING_AWS_ACCOUNT_ID
└── deploy-production.yml # Deploys to PRODUCTION_AWS_ACCOUNT_ID
Each workflow uses different:
- IAM role ARNs (different account IDs)
- GitHub variables (per-environment account IDs)
- Environment-specific parameter files
Customizing the pipeline
Selective deployments
To limit deployments to a subset of templates:
# Edit the deploy script to filter templates
./scripts/deploy-templates.sh --filter "network,security"
# Or wrap the script with custom logic
Notifications
Add Slack or Teams notifications after deployment:
- name: Notify on success
if: success()
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} \
-H 'Content-Type: application/json' \
-d '{"text":"CloudFormation deployment succeeded"}'
- name: Notify on failure
if: failure()
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} \
-H 'Content-Type: application/json' \
-d '{"text":"CloudFormation deployment failed"}'
Pull request validation
Add a separate workflow for PR validation (no deployment):
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
- 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
This validates templates on every pull request without deploying to AWS.
Observability
Workflow logs
Rain logs stack events directly to the workflow output:
- View detailed deployment progress
- See CloudFormation events in real-time
- Identify which resources are being created/updated/deleted
CloudFormation console
For deeper troubleshooting:
- Open the CloudFormation console in your target AWS account
- Navigate to the stack matching your template name
- Review the Events tab for detailed resource-level information
- Check the Resources tab to see the state of all stack resources
GitHub Security tab
Checkov security findings appear in the GitHub Security tab:
- Navigate to your repository's Security tab
- Click "Code scanning alerts"
- Review Checkov findings with severity levels and remediation guidance
Related documentation
- Linting and Code Analysis — Configure cfn-lint and Checkov
- cfn-lint reference — Detailed cfn-lint documentation
- Checkov reference — Detailed Checkov documentation
- Scripts reference — Deployment script documentation
- Local Development guide — Run validation and deployment locally