Last updated on 26th February 2026

Deploy with AWS CloudFormation

This guide walks you through deploying AWS CloudFormation stacks using DeployHQ's Custom Action protocol. Custom Actions run CLI tools inside Docker containers during your deployment pipeline, letting you manage AWS infrastructure directly from DeployHQ.

Prerequisites

Before you begin, ensure you have:

  • Beta Features Enabled: Custom Actions require beta features to be enabled in your account settings
  • A Repository with CloudFormation Templates: Your .yaml or .json CloudFormation template files stored in your repository
  • AWS IAM Credentials: An access key and secret key for an IAM user with permissions to manage CloudFormation stacks

Setting Up the Server

  1. Open your project in DeployHQ and navigate to Servers.
  2. Click New Server and select Custom Action as the protocol.
  3. Under Image Source, select Curated Template.
  4. Choose AWS CLI from the template dropdown. This sets the Docker image to amazon/aws-cli:latest.
  5. Enter your deployment commands in the Commands field:
   aws cloudformation deploy \
     --template-file /data/cloudformation/template.yaml \
     --stack-name my-app-stack \
     --capabilities CAPABILITY_IAM \
     --no-fail-on-empty-changeset
  1. Set Halt on error to stop the deployment if the stack update fails.
  2. Click Create Server.

Configuring Credentials

Add the following environment variables to your DeployHQ server:

Variable Value
AWS_ACCESS_KEY_ID Your AWS access key
AWS_SECRET_ACCESS_KEY Your AWS secret key
AWS_DEFAULT_REGION Target region (e.g., us-east-1)

IAM Permissions

The IAM user needs at minimum the following permissions:

  • cloudformation:CreateStack
  • cloudformation:UpdateStack
  • cloudformation:DeleteStack
  • cloudformation:DescribeStacks
  • cloudformation:DescribeStackEvents
  • cloudformation:CreateChangeSet
  • cloudformation:ExecuteChangeSet
  • cloudformation:DeleteChangeSet
  • cloudformation:DescribeChangeSet

Additionally, the user needs permissions for whatever resources your CloudFormation templates create (e.g., EC2, S3, RDS, Lambda).

Example Commands

Basic Stack Deploy

The aws cloudformation deploy command handles both creation and updates:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-stack \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset

The --no-fail-on-empty-changeset flag prevents the command from failing when there are no changes to deploy.

Deploy with Parameters

Pass parameters to your CloudFormation template:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-stack \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset \
  --parameter-overrides \
    Environment=production \
    InstanceType=t3.medium \
    ImageTag=%revision%

You can use DeployHQ text variables like %revision% and %branch% in your parameter values.

Deploy with Parameter File

For complex parameter sets, use a parameters file stored in your repository:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-stack \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset \
  --parameter-overrides file:///data/cloudformation/params/production.json

Using Change Sets for Review

If you want to preview changes before applying, create a change set and then execute it:

aws cloudformation create-change-set \
  --template-body file:///data/cloudformation/template.yaml \
  --stack-name my-app-stack \
  --change-set-name deploy-%revision% \
  --capabilities CAPABILITY_IAM

aws cloudformation wait change-set-create-complete \
  --stack-name my-app-stack \
  --change-set-name deploy-%revision%

aws cloudformation describe-change-set \
  --stack-name my-app-stack \
  --change-set-name deploy-%revision%

aws cloudformation execute-change-set \
  --stack-name my-app-stack \
  --change-set-name deploy-%revision%

aws cloudformation wait stack-update-complete \
  --stack-name my-app-stack

Retrieve Stack Outputs

After deployment, you can display stack outputs in the deployment log:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-stack \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset

aws cloudformation describe-stacks \
  --stack-name my-app-stack \
  --query "Stacks[0].Outputs" \
  --output table

Multi-Environment Usage

Separate Stacks per Environment

Use different stack names and parameter files for each environment. Create separate DeployHQ servers for staging and production:

Staging server commands:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-staging \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset \
  --parameter-overrides file:///data/cloudformation/params/staging.json

Production server commands:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-production \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset \
  --parameter-overrides file:///data/cloudformation/params/production.json

Dynamic Stack Names

Use DeployHQ text variables for dynamic stack names:

aws cloudformation deploy \
  --template-file /data/cloudformation/template.yaml \
  --stack-name my-app-%server% \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset

Troubleshooting

"No updates are to be performed":

  • This means your stack is already up to date. Using --no-fail-on-empty-changeset with deploy prevents this from being treated as an error.

"InsufficientCapabilitiesException":

  • Add --capabilities CAPABILITY_IAM or --capabilities CAPABILITY_NAMED_IAM if your template creates IAM resources

"Stack is in ROLLBACK_COMPLETE state":

  • The stack failed to create and cannot be updated. Delete the stack manually in the AWS Console and retry the deployment.

"Template format error":

  • Validate your template locally with aws cloudformation validate-template --template-body file://template.yaml
  • Ensure your YAML or JSON syntax is correct

Credential errors:

  • Verify the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION environment variables are set correctly on your DeployHQ server
  • Ensure the IAM user has the required permissions listed above

Timeout errors:

  • CloudFormation stack operations can take a long time. Custom Actions have a 30-minute timeout per command.
  • For stacks that take longer, consider splitting your infrastructure into nested stacks or separate deployments