A GitHub Action that processes CloudFormation deployment configurations, merges parameter files with environment-specific overrides, and generates outputs for CloudFormation stack deployment including parameter arrays, stack names, and CI build identifiers.
- 📁 Flexible Configuration: Reads CloudFormation configurations from customizable folder structures
- 🔄 Parameter Merging: Automatically merges default parameters with environment-specific overrides
- 🏷️ Dynamic Stack Naming: Generates appropriate stack names for both CI builds and environment deployments
- 🎲 CI Build Identifiers: Creates unique identifiers for CI builds to enable parallel deployments
- ✅ Comprehensive Validation: Validates JSON files and required fields with clear error messages
- 🧪 Well Tested: Extensive unit and integration test coverage
- name: Process CloudFormation Configuration
uses: subhamay-bhattacharyya-gha/cfn-stack-params-action@main
with:
cfn-directory: 'infrastructure'
ci-build: 'false'
environment: 'sb-prod-us-east-1'
id: cfn-config
- name: Deploy CloudFormation Stack
uses: subhamay-bhattacharyya/cfn-create-stack-action@main
with:
name: ${{ steps.cfn-config.outputs.stack-name }}
template: infrastructure/template.yaml
parameter-overrides: ${{ steps.cfn-config.outputs.parameters }}
- Inputs
- Outputs
- Configuration Structure
- Usage Examples
- Error Scenarios
- Troubleshooting
- Workflow Examples
- Contributing
- License
Name | Description | Required | Default | Example |
---|---|---|---|---|
cfn-directory |
Folder containing CloudFormation configuration files | No | cfn |
infrastructure |
ci-build |
Whether this is a CI build (true/false) | No | false |
true |
environment |
Target environment name | No | '' |
sb-prod-us-east-1 |
Specifies the folder path (relative to repository root) containing your CloudFormation configuration files. The folder must contain:
cloudformation.json
- Main configuration fileparams/
- Subfolder with parameter files
Boolean flag that determines the stack naming strategy:
true
: Uses current Git branch name in stack name (for feature branch deployments)false
: Uses environment name in stack name (for environment deployments)
Environment identifier used for:
- Loading environment-specific parameter files (
params/{environment}.json
) - Stack naming when
ci-build
isfalse
Name | Description | Type | Example |
---|---|---|---|
parameters |
CloudFormation parameters in JSON array format | String | [{"ParameterName":"VpcId","ParameterValue":"vpc-123"}] |
stack-name |
Generated CloudFormation stack name | String | myproject-api-sb-prod-us-east-1 |
ci-build-id |
CI build identifier (random string for CI builds, empty otherwise) | String | abcdefgh |
JSON string containing an array of CloudFormation parameters in the format:
[
{
"ParameterName": "ParameterKey",
"ParameterValue": "ParameterValue"
}
]
Generated stack name following these patterns:
- CI Build:
{project}-{stack-prefix}-{sanitized-branch-name}
- Environment:
{project}-{stack-prefix}-{environment}
- CI Build: Random 6-10 character lowercase string (e.g.,
abcdefgh
) - Environment: Empty string
Your CloudFormation configuration should follow this directory structure:
{cfn-directory}/
├── cloudformation.json # Main configuration
└── params/
├── default.json # Default parameters (required)
├── sb-devl-us-east-1.json # Environment-specific parameters
├── sb-test-us-east-1.json # Environment-specific parameters
└── sb-prod-us-east-1.json # Environment-specific parameters
Main configuration file with required fields:
{
"project": "my-application",
"template": "infrastructure.yaml",
"stack-prefix": "api"
}
Field | Description | Required | Example |
---|---|---|---|
project |
Project identifier used in stack naming | Yes | my-application |
template |
CloudFormation template filename | Yes | infrastructure.yaml |
stack-prefix |
Stack prefix used in stack naming | Yes | api |
Contains default parameter values that apply to all environments:
{
"VpcId": "vpc-default",
"InstanceType": "t3.micro",
"Environment": "default",
"EnableLogging": true,
"BackupRetention": 7
}
Environment-specific parameters that override defaults:
{
"VpcId": "vpc-prod-123456",
"InstanceType": "t3.large",
"Environment": "sb-prod-us-east-1",
"BackupRetention": 30,
"AlarmEmail": "alerts@company.com"
}
Parameter Merging Rules:
- Default parameters are loaded first
- Environment-specific parameters override matching keys
- Environment-specific parameters can add new keys
- Final output contains merged parameters in CloudFormation format
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Process CloudFormation Configuration
uses: subhamay-bhattacharyya-gha/cfn-stack-params-action@main
with:
cfn-directory: 'infrastructure'
ci-build: 'false'
environment: 'sb-prod-us-east-1'
id: cfn-config
- name: Deploy Stack
run: |
aws cloudformation deploy \
--stack-name ${{ steps.cfn-config.outputs.stack-name }} \
--template-file infrastructure/template.yaml \
--parameter-overrides '${{ steps.cfn-config.outputs.parameters }}'
name: Feature Branch Deployment
on:
pull_request:
branches: [main]
jobs:
deploy-feature:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Process CloudFormation Configuration
uses: subhamay-bhattacharyya-gha/cfn-stack-params-action@main
with:
cfn-directory: 'cfn'
ci-build: 'true'
environment: 'sb-devl-us-east-1'
id: cfn-config
- name: Deploy Feature Stack
run: |
echo "Stack Name: ${{ steps.cfn-config.outputs.stack-name }}"
echo "CI Build ID: ${{ steps.cfn-config.outputs.ci-build-id }}"
echo "Parameters: ${{ steps.cfn-config.outputs.parameters }}"
name: Multi-Environment Deployment
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
environment:
- sb-devl-us-east-1
- sb-test-us-east-1
- sb-prod-us-east-1
steps:
- uses: actions/checkout@v4
- name: Process CloudFormation Configuration
uses: subhamay-bhattacharyya-gha/cfn-stack-params-action@main
with:
cfn-directory: 'infrastructure'
ci-build: 'false'
environment: ${{ matrix.environment }}
id: cfn-config
- name: Deploy to ${{ matrix.environment }}
run: |
aws cloudformation deploy \
--stack-name ${{ steps.cfn-config.outputs.stack-name }} \
--template-file infrastructure/template.yaml \
--parameter-overrides '${{ steps.cfn-config.outputs.parameters }}'
- name: Process CloudFormation Configuration
uses: subhamay-bhattacharyya-gha/cfn-stack-params-action@main
with:
cfn-directory: 'aws/cloudformation'
ci-build: 'false'
environment: 'production'
id: cfn-config
The action provides clear error messages for common issues:
Error: Configuration directory not found
Error: Configuration directory 'cfn' does not exist
Error: Missing cloudformation.json
Error: cloudformation.json not found in cfn directory
Error: Missing default parameters
Error: default.json not found in cfn/params directory
Error: Malformed JSON
Error: Invalid JSON in cloudformation.json: Unexpected token } in JSON at position 45
Error: Missing required fields
Error: Missing required field 'project' in cloudformation.json
Error: Unable to determine branch
Error: Unable to determine current branch name for CI build
Error: Not a Git repository
Error: Current directory is not a Git repository
Warning: Missing environment parameters (non-fatal)
Warning: Environment parameter file 'sb-test-us-east-1.json' not found, using default parameters only
Error: Invalid parameter JSON
Error: Invalid JSON in params/default.json: Unexpected token ] in JSON at position 23
Cause: The specified cfn-directory
path doesn't exist in your repository.
Solutions:
- Verify the directory path is correct relative to repository root
- Ensure the directory is committed to your repository
- Check for typos in the
cfn-directory
input
# Correct
cfn-directory: 'infrastructure' # Directory exists at repo root
# Incorrect
cfn-directory: 'infrastucture' # Typo in directory name
Cause: The cloudformation.json
file is missing required fields.
Solution: Ensure your cloudformation.json
contains all required fields:
{
"project": "your-project-name", // Required
"template": "template.yaml", // Required
"stack-prefix": "api" // Required
}
Cause: Git operations failed when ci-build
is set to true
.
Solutions:
- Ensure you're using
actions/checkout@v4
before this action - Verify the repository has Git history
- Check that the workflow has proper Git access
steps:
- uses: actions/checkout@v4 # Required for Git operations
- name: Process CloudFormation Configuration
uses: subhamay-bhattacharyya-gha/cfn-stack-params-action@main
with:
ci-build: 'true'
Cause: Parameter files have incorrect structure or naming.
Solutions:
- Verify
default.json
exists in theparams/
subdirectory - Ensure environment parameter files are named exactly
{environment}.json
- Check that all JSON files have valid syntax
cfn/
├── cloudformation.json
└── params/
├── default.json ✅ Correct
├── sb-prod-us-east-1.json ✅ Correct
├── prod.json ❌ Won't match environment 'sb-prod-us-east-1'
└── sb-prod-us-east-1.JSON ❌ Wrong file extension case
Cause: Branch names or environment names contain characters not allowed in CloudFormation stack names.
Solution: The action automatically sanitizes branch names, but ensure environment names follow CloudFormation naming rules:
- Only alphanumeric characters and hyphens
- Must start with a letter
- Maximum 128 characters
Cause: Insufficient permissions to read files or execute Git commands.
Solutions:
- Ensure the workflow has proper repository permissions
- Check that files are not in
.gitignore
- Verify file permissions in the repository
Enable debug logging by setting the ACTIONS_STEP_DEBUG
secret to true
in your repository settings. This will provide detailed logs of the action's execution.
For detailed troubleshooting information, see the Troubleshooting Guide.
If you encounter issues not covered in the guides:
- Check the Issues page for similar problems
- Review the action logs for detailed error messages
- Ensure your configuration follows the documented structure
- Test your JSON files with a JSON validator
When using this action in production environments:
- Parameter Encryption: Store sensitive parameters in AWS Systems Manager Parameter Store or AWS Secrets Manager
- IAM Permissions: Use least-privilege IAM roles for CloudFormation deployments
- Environment Isolation: Keep environment-specific configurations in separate branches or repositories
- Secrets Management: Never commit sensitive values to parameter files
- Parameter File Size: Keep parameter files small and focused to reduce processing time
- CI Build Strategy: Use
ci-build: true
for feature branches to enable parallel deployments - Caching: Consider caching CloudFormation configuration files in multi-step workflows
- Stack Drift Detection: Regularly check for configuration drift between your parameter files and deployed stacks
- Deployment Tracking: Use the generated
ci-build-id
for correlating logs across deployment steps - Error Handling: Implement proper error handling in your workflows to catch configuration issues early
This action maintains backward compatibility. No changes required for existing workflows.
If you're migrating from custom parameter processing scripts:
- Create Configuration Structure: Set up the required
cloudformation.json
andparams/
directory - Update Workflow: Replace custom scripts with this action
- Test Environment Mapping: Verify environment parameter files are correctly named
- Validate Outputs: Ensure the generated parameters work with your CloudFormation deployment actions
We welcome contributions! Please see our Contributing Guide for details.
- Clone the repository
- Install dependencies:
npm install
- Run tests:
npm test
- Run linting:
npm run lint
# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests only
npm run test:integration
# Run with coverage
npm run test:coverage
This project is licensed under the MIT License - see the LICENSE file for details.