The AWS Cost Analysis feature provides comprehensive cost estimation and optimization recommendations for your Terraform and CloudFormation infrastructure.
The cost analysis check examines your tfplan.json files and CloudFormation templates and provides:
ThothCTL provides confidence levels for cost estimates:
Note on Real-Time Pricing: AWS’s bulk pricing files are very large (100MB+ per service/region), making real-time parsing impractical for a CLI tool. ThothCTL uses carefully maintained offline estimates that are regularly updated to match AWS pricing.
# Basic cost analysis (supports both Terraform and CloudFormation)
thothctl check iac -type cost-analysis
# Recursive analysis across multiple directories
thothctl check iac --recursive -type cost-analysis
# With specific directory
thothctl check iac -type cost-analysis -d /path/to/infrastructure
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
# CloudFormation templates (.yaml, .yml, .json)
# Must contain AWSTemplateFormatVersion or Resources section
No AWS credentials or internet required! ThothCTL uses offline pricing estimates that are regularly updated.
================================================================================
💰 AWS COST ANALYSIS
================================================================================
📊 Total Monthly Cost: $247.50
📅 Total Annual Cost: $2,970.00
🏗️ Cost by Service:
• EC2: $72.00/month
• RDS: $124.00/month
• ELB: $16.20/month
• EBS: $8.00/month
• Bedrock: $25.00/month
• Secrets Manager: $2.30/month
⚡ Cost by Action:
• create: $235.50/month
• update: $12.00/month
• delete: $0.00/month
📋 Resource Details:
• aws_instance.web_server
Type: aws_instance | Cost: $72.00/month | Confidence: high
• aws_db_instance.main_db
Type: aws_db_instance | Cost: $124.00/month | Confidence: medium
💡 Recommendations:
💰 Consider Reserved Instances for 1-3 year commitments
📊 Review instance sizing - right-size resources
🔍 Set up AWS Cost Explorer and billing alerts
🤖 Optimize Bedrock model usage and consider batch processing
🔐 Review secret rotation frequency and consolidate secrets where possible
📈 Analysis Info: Region: us-east-1 | API: ✅ Online
================================================================================
The JSON report is saved to Reports/cost-analysis/cost_analysis_<stack>_<timestamp>.json with the following schema:
{
"summary": {
"total_monthly_cost": 247.50,
"total_annual_cost": 2970.00,
"region": "us-east-1",
"api_available": false,
"plan_file": "path/to/tfplan.json"
},
"cost_by_service": {
"EC2": 72.00,
"RDS": 124.00,
"ELB": 16.20
},
"cost_by_action": {
"create": 235.50,
"update": 12.00,
"delete": 0.00
},
"resources": [
{
"address": "aws_instance.web_server",
"type": "aws_instance",
"service": "EC2",
"region": "us-east-1",
"action": "create",
"hourly_cost": 0.0100,
"monthly_cost": 72.00,
"annual_cost": 864.00,
"confidence": "medium",
"details": {
"instance_type": "t3.micro"
}
}
],
"recommendations": [
"💰 Consider Reserved Instances for 1-3 year commitments (up to 72% savings)"
],
"warnings": [
"No pricing data for aws_new_service.example"
]
}
| Field | Type | Description |
|---|---|---|
summary.total_monthly_cost |
float |
Estimated total monthly cost (USD). Creates and updates add cost; deletes subtract. |
summary.total_annual_cost |
float |
total_monthly_cost × 12 |
summary.region |
string |
Default AWS region used for pricing |
summary.api_available |
boolean |
Whether the AWS public pricing API was reachable |
summary.plan_file |
string |
Path to the analyzed plan or template file |
cost_by_service |
object |
Monthly cost (USD) grouped by AWS service name (e.g. EC2, RDS, Lambda) |
cost_by_action |
object |
Monthly cost (USD) grouped by action: create, update, delete |
resources |
array |
Per-resource cost details (see below) |
recommendations |
array[string] |
Cost optimization suggestions based on detected resources and thresholds |
warnings |
array[string] |
Resources that could not be priced |
| Field | Type | Description |
|---|---|---|
address |
string |
Terraform resource address (e.g. module.vpc.aws_nat_gateway.main) or CloudFormation resource name |
type |
string |
Terraform resource type (e.g. aws_instance, aws_db_instance) |
service |
string |
AWS service name (e.g. EC2, RDS, S3, Lambda, Bedrock) |
region |
string |
AWS region for this resource |
action |
string |
One of: create, update, delete, no-change |
hourly_cost |
float |
Estimated hourly cost (USD), rounded to 4 decimal places |
monthly_cost |
float |
Estimated monthly cost (USD, 720 hours), rounded to 2 decimal places |
annual_cost |
float |
Estimated annual cost (USD, 8760 hours), rounded to 2 decimal places |
confidence |
string |
Estimate confidence: high (API pricing), medium (offline estimates), low (fallback) |
details |
object |
Service-specific pricing parameters (e.g. instance_type, engine, volume_type) |
The analyzer uses the following region detection order:
us-east-1a → us-east-1)us-east-1)The analyzer provides intelligent recommendations based on your infrastructure:
# For Terraform: Generate plan files first
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
# For CloudFormation: Ensure templates are present
# Templates must be .yaml, .yml, or .json files
# Must contain AWSTemplateFormatVersion or Resources section
# Then run cost analysis
thothctl check iac -type cost-analysis
The analyzer automatically falls back to offline estimates when:
Resources not yet supported will show in warnings:
⚠️ Warnings:
• No pricing data for aws_new_service.example
name: Infrastructure Cost Analysis
on: [pull_request]
jobs:
cost-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Terraform Plan
run: |
terraform init
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
- name: Install ThothCTL
run: pip install thothctl
- name: Cost Analysis
run: thothctl check iac -type cost-analysis
cost-analysis:
stage: validate
script:
- terraform plan -out=tfplan
- terraform show -json tfplan > tfplan.json
- thothctl check iac -type cost-analysis
artifacts:
reports:
junit: cost-analysis-report.xml
# Analyze costs for specific region
AWS_DEFAULT_REGION=eu-west-1 thothctl check iac -type cost-analysis
# Analyze multiple Terraform directories
find . -name "tfplan.json" -execdir thothctl check iac -type cost-analysis \;
The cost analysis integrates with existing ThothCTL check command:
thothctl check iac [OPTIONS]
Options:
-type, --check_type [tfplan|module|deps|blast-radius|cost-analysis]
Check type to perform (default: tfplan)
--recursive Search for tfplan files recursively
-d, --code-directory PATH
Directory to analyze
In addition to cost estimation, you can enforce cost governance rules using OPA/Conftest policies in the scan command. This enables automated budget gates, instance type restrictions, and required cost tags in your CI/CD pipeline.
See Cost Governance Policies with OPA for complete Rego policy examples.
# Combine cost analysis with cost policy enforcement
thothctl check iac -type cost-analysis --recursive
thothctl scan iac -t opa -o "mode=opa,decision=terraform/cost/allow" --enforcement hard
Problem: Cost analysis shows “medium confidence” or offline estimates
Solutions:
curl -I https://pricing.us-east-1.amazonaws.com
aws sts get-caller-identity
thothctl --debug check iac -type cost-analysis
Problem: “API pricing failed” warnings in logs
Common Causes:
Solution: The tool automatically falls back to offline estimates. Check logs for specific error messages.
Problem: YAML files not recognized as CloudFormation templates
Solution: Ensure templates contain one of these indicators:
AWSTemplateFormatVersion: '2010-09-09'Resources: sectionAWS::EC2::Instance)To add support for new AWS services:
pricing/providers/BasePricingProvider interfaceCostAnalyzer._initialize_providers()Example:
class NewServicePricingProvider(BasePricingProvider):
def get_service_code(self) -> str:
return 'AmazonNewService'
def get_supported_resources(self) -> List[str]:
return ['aws_new_service_resource']
def calculate_cost(self, resource_change: Dict[str, Any],
region: str) -> Optional[ResourceCost]:
"""Calculate cost using AWS Pricing API"""
if not self.pricing_client.is_available():
return self.get_offline_estimate(resource_change, region)
try:
filters = (
('TERM_MATCH', 'location', self._region_to_location(region)),
# Add service-specific filters
)
products = self.pricing_client.get_products(
self.get_service_code(), filters
)
if products:
hourly_cost = self._extract_hourly_cost(products[0])
return self._create_resource_cost(
resource_change, config_param, region,
hourly_cost, 'high' # high confidence for API pricing
)
except Exception as e:
logger.warning(f"API pricing failed: {e}")
return self.get_offline_estimate(resource_change, region)
# Implement other required methods...