CloudFormation cost estimation: the missing piece
How to estimate the monthly cost of a CloudFormation template before deploying. SAM templates, CDK output, nested stacks, and the patterns that work for migrating an existing CloudFormation workflow.
Quick answer
Run c3x estimate --path template.yaml on any CloudFormation YAML or JSON template. C3X parses the resources, looks up AWS pricing, and produces a monthly cost breakdown in seconds. No AWS credentials needed. SAM templates work the same way. For CDK, run c3x against the cdk.out directory after cdk synth. Free and open source.
CloudFormation users have been the underserved group of cloud cost estimation. The first generation of tools focused on Terraform, and CloudFormation got either ignored or relegated to a paid tier. C3X parses CloudFormation YAML and JSON natively, in the same free CLI, with the same accuracy as Terraform. This post walks through how it works and what to know if you're moving an existing CloudFormation workflow to include cost estimation.
The basic command
Point c3x at a CloudFormation template:
c3x estimate --path stack.yamlOr at a directory containing multiple templates:
c3x estimate --path ./infrastructure/Output mirrors the Terraform format: per-resource line items with sub-component breakdowns where applicable.
Name Monthly Qty Unit Monthly Cost
ApiServer (AWS::EC2::Instance)
├─ Instance usage (Linux/UNIX, on-demand, m5.xlarge) 730 hours $140.16
├─ root_block_device
│ └─ Storage (general purpose SSD, gp3) 100 GB $8.00
Database (AWS::RDS::DBInstance)
├─ Database instance (on-demand, Multi-AZ, db.r5.large) 730 hours $365.00
└─ Storage (general purpose SSD, gp3) 200 GB $46.00
OVERALL TOTAL $559.16What c3x reads from a CloudFormation template
Three template structures matter for cost estimation:
Resources
Every entry under Resources is examined. C3X maps CloudFormation resource types (AWS::EC2::Instance, AWS::RDS::DBInstance, etc.) to internal resource handlers and reads the resource's properties. Properties like InstanceType, AllocatedStorage, DBInstanceClass, and so on become inputs to the pricing lookup.
Parameters
Template parameters are resolved from either:
- Default values declared in the parameter definition
- A parameter file passed via --parameters
- Direct overrides via --parameter Key=Value command-line args
For accurate estimates, supply parameter values matching what you'd actually deploy. A template with InstanceType defaulting to t3.nano but actually deployed as m5.xlarge needs the override.
Conditions
CloudFormation conditions (Fn::If, Fn::Equals, etc.) are evaluated based on resolved parameter values. Resources whose Condition evaluates to false are excluded from the estimate.
Conditions:
IsProduction: !Equals [!Ref Environment, production]
Resources:
ProdDb:
Type: AWS::RDS::DBInstance
Condition: IsProduction
Properties:
DBInstanceClass: db.r5.xlarge
# ...With Environment defaulting to staging, ProdDb isn't included in the estimate. With --parameter Environment=production passed to c3x, ProdDb becomes part of the cost.
Nested stacks and cross-stack references
Large CloudFormation projects use nested stacks. AWS::CloudFormation::Stack resources reference templates via TemplateURL (S3) or local file paths. C3X walks the nested templates and includes their resources in the parent's estimate.
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ./network.yaml
Parameters:
VpcCidr: 10.0.0.0/16
AppStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ./application.yaml
Parameters:
VpcId: !GetAtt NetworkStack.Outputs.VpcIdRunning c3x estimate --path parent.yaml walks both network.yaml and application.yaml, resolves the cross-stack VpcId reference, and produces a single estimate for the entire application.
For TemplateURLs pointing to S3, c3x downloads them (no AWS credentials needed if the bucket is public; credentials picked up from the standard chain if not).
SAM (Serverless Application Model)
SAM is CloudFormation with extra transforms. The headerTransform: AWS::Serverless-2016-10-31 tells CloudFormation to expand SAM-specific resource types (AWS::Serverless::Function, AWS::Serverless::Api) into vanilla CloudFormation resources at deploy time.
C3X performs the SAM expansion internally so you can estimate SAM templates directly:
c3x estimate --path template.yamlFor a SAM template with three Lambda functions and an API Gateway, c3x produces the same kind of breakdown as if the resources had been declared explicitly:
HelloWorldFunction (AWS::Serverless::Function)
├─ Requests 0 (depends on usage) $0.00
└─ Duration 0 (depends on usage) $0.00
HelloWorldApi (AWS::Serverless::Api)
└─ API requests 0 (depends on usage) $0.00
NOTE: Lambda and API Gateway are usage-based. Add expected volumes to
c3x-usage.yml for accurate estimates.For details on the Lambda side specifically, see our post on Lambda cost estimation. The same patterns apply to SAM-defined Lambda.
CDK (Cloud Development Kit)
CDK synthesizes to CloudFormation. The output lives in cdk.out after running cdk synth. Point c3x at that directory:
cdk synth
c3x estimate --path cdk.out/MyStack.template.jsonOr in CI, combine the two steps:
- run: cdk synth --quiet
- run: c3x estimate --path cdk.out/Caveat: CDK constructs sometimes generate resources with unexpected configurations (e.g., higher default capacity than you intend). Always review the synthesized CloudFormation rather than assuming the construct-level cost matches your mental model.
What's different from Terraform
Three practical differences when estimating CloudFormation vs Terraform:
Implicit resource creation
Some CloudFormation resource types create multiple billable resources implicitly. AWS::EC2::LaunchTemplate doesn't bill, but an Auto Scaling Group using it provisions EC2 instances that do. AWS::ElasticLoadBalancingV2::LoadBalancer creates load balancer infrastructure billed even when no targets are attached.
C3X follows these dependencies through the template and includes them in the estimate. The behavior is the same as Terraform but the conventions differ; expect c3x to show more "free" resources in the CloudFormation output that represent these dependencies.
Default values matter more
Terraform tends toward explicit configuration. CloudFormation templates often rely on parameter defaults. If you estimate a template with default parameter values, you may get a "minimal" estimate that doesn't match your real deployment.
Always pass production parameter values via --parameter or --parameters-file when running estimates for production deployments.
Drift between template and reality
CloudFormation supports manual changes outside the template via the AWS Console. The template doesn't reflect those changes, so the estimate is for the template's state, not the actual stack. For a true production estimate, use aws cloudformation detect-stack-drift first and reconcile.
The CI integration for CloudFormation
The same cost gate pattern from budget guardrails in CI works for CloudFormation. The Terraform-specific c3x diff command also handles CloudFormation:
# .github/workflows/cost-gate.yml
on: pull_request
jobs:
cost-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: c3xdev/setup-c3x@v1
with:
path: ./templatesThe setup-c3x action auto-detects CloudFormation vs Terraform by file extension and content. If your repo has both, you can run separate workflows pointed at each.
Migration: from manual estimates to automated
Most teams using CloudFormation today estimate cost through one of three painful methods: the AWS Pricing Calculator UI (manual, slow, doesn't track template changes), spreadsheets maintained by one person on the team, or post-deployment via CloudTrail and Cost Explorer (too late). Adding c3x is a strict upgrade over any of these.
Recommended adoption order:
- Install c3x and run an estimate against your largest production template. Compare to recent monthly bills to validate accuracy.
- Add the CI action to one repository. Watch a few PRs to see the cost diff comments in action.
- After two weeks of data, add the budget gate. Start with --budget-increase 25 in warning-only mode.
- Roll out across other CloudFormation-managed repos.
FAQ
Can I estimate the cost of a CloudFormation template before deploying?
Yes. C3X parses CloudFormation YAML and JSON templates directly, looks up AWS pricing for each resource, and produces a monthly cost breakdown. The estimate runs against the template file, not against your AWS account, so no credentials are required and no stack is created.
How accurate is CloudFormation cost estimation vs Terraform?
Equally accurate for the same resources. CloudFormation and Terraform both ultimately provision the same AWS resources; c3x uses the same AWS Pricing API for both. Where they differ is in how usage-based resources are configured: CloudFormation often relies on default values where Terraform would have explicit parameters. Provide a c3x-usage.yml file with expected volumes for accurate estimates of Lambda, S3, NAT data, etc.
Does C3X support nested stacks and cross-stack references?
Yes. C3X resolves AWS::CloudFormation::Stack resources by following the TemplateURL or local file reference, walking the nested template, and including its resources in the estimate. Cross-stack references via Fn::ImportValue are resolved when the source stack is in the same project.
What about SAM and CDK?
SAM (Serverless Application Model) templates are CloudFormation under the hood; c3x estimates them the same way as plain CloudFormation. CDK synthesizes to CloudFormation; run c3x against the cdk.out directory after cdk synth. Pulumi has different output formats and isn't currently supported (it's on the roadmap).
Is CloudFormation cost estimation free in C3X?
Yes. C3X is Apache 2.0 open source. Unlike some competitor tools that gate CloudFormation support behind a paid tier, C3X supports it in the free CLI. The public pricing API at pricing.c3x.dev is also free.
How does C3X handle CloudFormation parameters and conditions?
C3X resolves parameters from the template's default values or from a parameters file you provide. Conditions (Fn::If, Fn::And, etc.) are evaluated based on the resolved parameter values, and only resources whose conditions evaluate to true are included in the estimate.
Getting started
Install C3X and run an estimate against any CloudFormation template:
brew install c3xdev/tap/c3x
c3x estimate --path your-template.yamlFor the full workflow including CI integration and budget gates, see the quickstart guide and the CI/CD docs. For per-resource pricing details, the resource catalog covers every supported AWS, Azure, and GCP resource.
If you're comparing tools and CloudFormation support specifically matters, our Infracost alternative comparison covers where each tool's free tier ends.
Share this post
Try C3X on your own Terraform
Free and open source. No API key required. One command to install, one command to estimate.