cloudformationawssamcdkcost-estimation

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.

The C3X Team··9 min read

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.yaml

Or 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.16

What 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.VpcId

Running 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.yaml

For 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.json

Or 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: ./templates

The 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:

  1. Install c3x and run an estimate against your largest production template. Compare to recent monthly bills to validate accuracy.
  2. Add the CI action to one repository. Watch a few PRs to see the cost diff comments in action.
  3. After two weeks of data, add the budget gate. Start with --budget-increase 25 in warning-only mode.
  4. 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.yaml

For 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.

Try C3X on your own Terraform

Free and open source. No API key required. One command to install, one command to estimate.