You can use aws cloudformation estimate-template-cost to get a cost estimate for your CloudFormation stack before deploying it.

Here’s a breakdown of how to do it and what you need to know:

First, you need your CloudFormation template file. Let’s say you have a template named my-ec2-stack.yaml.

To get the cost estimate, you’ll run the following AWS CLI command:

aws cloudformation estimate-template-cost --template-body file://my-ec2-stack.yaml

This command will output a JSON object containing the estimated cost. The primary field you’ll be looking for is Url, which is a pre-signed URL to a detailed cost breakdown report on AWS.

{
    "Url": "https://example.com/path/to/your/detailed/cost/report?AWSAccessKeyId=..."
}

You need to visit this Url in your web browser. This report provides a granular view of the estimated costs for each resource defined in your CloudFormation template. You’ll see line items for EC2 instances, RDS databases, S3 storage, Elastic Load Balancers, and more, along with their projected monthly costs.

This is incredibly useful because CloudFormation itself doesn’t inherently know the pricing of AWS resources; it only knows the types and configurations of resources you want. The estimate-template-cost tool queries AWS pricing APIs based on your template’s resource definitions.

What influences the cost estimate?

  • Resource Types: Different EC2 instance types (e.g., t2.micro vs. m5.xlarge) have vastly different hourly rates. Similarly, RDS instance classes and storage types (e.g., gp2 vs. io1) impact cost.
  • Resource Quantities: If you specify InstanceCount: 5 for an EC2 instance, the cost will be five times that of a single instance.
  • Storage Volumes: The size and type of EBS volumes or RDS storage directly contribute to the cost.
  • Data Transfer: While often harder to estimate precisely without knowing traffic patterns, the cost of data transfer in and out of AWS regions or between Availability Zones can be a significant factor. This command will provide estimates based on typical data transfer costs.
  • Region: Resource pricing varies by AWS region. The estimate will be based on the region your AWS CLI is configured for or the region you specify in your estimate-template-cost command if using the --region flag.
  • Purchasing Options: The estimate typically defaults to On-Demand pricing. It won’t automatically factor in Reserved Instances or Savings Plans unless you explicitly configure your template or account for them in your manual analysis.

Example Scenario:

Let’s say your my-ec2-stack.yaml looks like this:

AWSTemplateFormatVersion: '2010-09-09'
Description: A simple EC2 instance stack

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0abcdef1234567890 # Example AMI ID
      InstanceType: t3.medium
      MinCount: '1'
      MaxCount: '1'
      Tags:
        - Key: Name
          Value: MyEstimatingInstance

Running aws cloudformation estimate-template-cost --template-body file://my-ec2-stack.yaml would give you a Url. Visiting that URL might show something like:

  • AWS::EC2::Instance (t3.medium, Linux/Unix, us-east-1): $0.0416 per hour * 730 hours/month = $30.37/month

If you then add an RDS instance to your template:

AWSTemplateFormatVersion: '2010-09-09'
Description: A simple EC2 and RDS stack

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0abcdef1234567890
      InstanceType: t3.medium
      MinCount: '1'
      MaxCount: '1'
      Tags:
        - Key: Name
          Value: MyEstimatingInstance

  MyRDSDatabase:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: db.t3.micro
      AllocatedStorage: 20
      Engine: mysql
      MasterUsername: admin
      MasterUserPassword: password123 # In a real template, use Secrets Manager!
      DBSubnetGroupName: my-db-subnet-group # Assumes this exists
      VPCSecurityGroups:
        - sg-0123456789abcdef0 # Assumes this exists

The estimate-template-cost command would then query pricing for both the EC2 instance and the RDS instance. The detailed report would show costs for both, summing up to a higher total.

Important Considerations:

  • Parameters: If your template uses parameters, estimate-template-cost will use default values. If you want to estimate costs for specific parameter overrides, you need to pass them to the command using the --parameters flag, just like you would for a create-stack operation. For example:
    aws cloudformation estimate-template-cost --template-body file://my-ec2-stack.yaml \
        --parameters ParameterKey=InstanceType,ParameterValue=t3.small \
                   ParameterKey=DesiredCapacity,ParameterValue=2
    
  • Stack Policies and Drift Detection: These are operational features and don’t directly impact resource costs, so they won’t appear in the cost estimate.
  • Managed Services: For services like Lambda, the cost is often based on usage (invocations, duration, memory) rather than just provisioning. The estimate will reflect the pricing for the configured memory and assumed invocation rates if specified in the template.
  • Third-Party AMIs: If your template uses a custom AMI or one from the AWS Marketplace, the cost estimate might not include any associated licensing fees. You’ll need to check the Marketplace listing for those details.
  • Dynamic Pricing: The cost estimate is a snapshot based on current AWS pricing. Prices can change, and your actual costs will depend on actual usage and any AWS promotions or changes.

This command is a crucial step in responsible cloud cost management, allowing you to catch potentially expensive configurations before they are provisioned and start incurring charges.

The next logical step after getting a cost estimate and deciding to proceed is to understand how to manage the lifecycle of the resources you’re about to deploy, which often involves looking into stack update strategies and rollback configurations.

Want structured learning?

Take the full Cloudformation course →