Skip to main content

CloudFormation Workflows

Three workflows cover the CloudFormation lifecycle: template linting, single-stack deployment with Lambda packaging, and multi-account StackSet deployment.


cf-lint

Validate CloudFormation templates using cfn-lint and cfn-nag — catches syntax errors, type mismatches, and security anti-patterns before deployment.

View workflow →

When to use: On every pull request that touches a CloudFormation template.

jobs:
lint:
uses: clouddrove/github-shared-workflows/.github/workflows/cf-lint.yml@master
with:
cf_file_path: ./templates/stack.yaml # required
InputRequiredDescription
cf_file_pathYesPath to the CloudFormation template file

cf-deploy

Deploy CloudFormation stacks with Lambda code packaging and S3 upload — packages Lambda source code as a ZIP, uploads it to S3 alongside the CloudFormation template, then creates or updates the stack.

View workflow →

When to use: Deploying CloudFormation stacks that include Lambda functions where the code is stored separately in S3.

jobs:
deploy:
uses: clouddrove/github-shared-workflows/.github/workflows/cf-deploy.yml@master
with:
s3-bucket: my-deployment-bucket
bucket-prefix: cloudformation/
stack-name: my-app-stack
template-path: ./templates/app.yaml
GitHub-repo-name: my-org/my-repo
GitHub-branch: main
code-folder: ./src/lambda
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
ROLE-TO-ASSUME: ${{ secrets.DEPLOY_ROLE_ARN }}
GITHUB: ${{ secrets.GITHUB_TOKEN }}
InputRequiredDescription
s3-bucketYesS3 bucket for the template and Lambda zip
bucket-prefixNoS3 key prefix (folder)
stack-nameYesCloudFormation stack name
template-pathYesPath to the CloudFormation template
GitHub-repo-nameYesorg/repo for the source repo
GitHub-branchNoBranch to deploy from
code-folderNoDirectory containing Lambda source code

S3 layout after deployment:

s3://my-deployment-bucket/cloudformation/
├── app.yaml ← CloudFormation template
└── lambda/
└── function.zip ← Lambda source code

See S3 Bucket Structure → for more on organizing deployment artifacts.


cf-deploy-stackset

Deploy CloudFormation StackSets across multiple AWS accounts and regions — creates or updates a StackSet and manages stack instances across the target accounts and regions you specify.

View workflow →

When to use: When you need to deploy the same CloudFormation template to multiple AWS accounts simultaneously (e.g., enabling GuardDuty or Security Hub across an AWS Organization).

jobs:
deploy-stackset:
uses: clouddrove/github-shared-workflows/.github/workflows/cf-deploy-stackset.yml@master
with:
stack-set-name: my-org-baseline
template-url: https://s3.amazonaws.com/my-bucket/template.yaml
account-ids: "123456789012,234567890123,345678901234"
permission-model: SERVICE_MANAGED # or SELF_MANAGED
auto-deployment-enabled: true
RetainStacksOnAccountRemoval: false
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_ROLE_TO_ASSUME: ${{ secrets.STACKSET_ROLE_ARN }}
GITHUB: ${{ secrets.GITHUB_TOKEN }}
InputRequiredDescription
stack-set-nameYesName for the StackSet
template-urlYesS3 URL of the CloudFormation template
account-idsYesComma-separated target AWS account IDs
permission-modelNoSERVICE_MANAGED (AWS Organizations) or SELF_MANAGED
auto-deployment-enabledNoAuto-deploy to new accounts in the org
RetainStacksOnAccountRemovalNoKeep stacks when accounts leave org
Organizations-managed StackSets

Use permission-model: SERVICE_MANAGED when your accounts are managed by AWS Organizations — this lets the StackSet automatically deploy to new member accounts without manual configuration.