AWS bills are easy to let grow unchecked. Engineers spin up resources, forget about them, and the account accumulates idle load balancers, forgotten RDS instances, and NAT gateways for VPCs that no longer have anything in them. Meanwhile the workloads that actually matter run at on-demand pricing when they could be covered by Savings Plans at 30 to 40 percent less.
Cost optimization is an ongoing discipline, not a one-time cleanup. In this article I will walk through the foundation: a tagging strategy you can enforce, budget alerts that surface problems before month-end, and the Savings Plans approach that reduces your compute bill without locking you into specific instance types.
Enforced Tagging with AWS Config
Tags are only useful if they are consistent and complete. A voluntary tagging policy produces partial data. An enforced tagging policy produces the data you can actually use to attribute costs to teams, products, and environments.
resource "aws_config_config_rule" "required_tags" {
name = "required-tags"
description = "Checks that required tags are present on all supported resources"
source {
owner = "AWS"
source_identifier = "REQUIRED_TAGS"
}
input_parameters = jsonencode({
tag1Key = "Environment"
tag1Value = "production,staging,development"
tag2Key = "Team"
tag3Key = "CostCenter"
tag4Key = "Project"
})
scope {
compliance_resource_types = [
"AWS::EC2::Instance",
"AWS::RDS::DBInstance",
"AWS::ElastiCache::CacheCluster",
"AWS::Lambda::Function",
"AWS::ECS::Service",
"AWS::S3::Bucket",
"AWS::DynamoDB::Table"
]
}
}
resource "aws_config_remediation_configuration" "required_tags" {
config_rule_name = aws_config_config_rule.required_tags.name
target_type = "SSM_DOCUMENT"
target_id = "AWSConfigRemediation-AddTags"
automatic = false
parameter {
name = "AutomationAssumeRole"
static_value = aws_iam_role.config_remediation.arn
}
}
Start with automatic = false on remediation. You want to review non-compliant resources first and understand why tags are missing before auto-remediating, which could apply incorrect tag values. After a month of manual review and team education, switch to automatic for new resources.
Cost Allocation Tags
Enable your tags as cost allocation tags in the Billing console so they appear in Cost Explorer and your billing reports. Without this step, tags exist on resources but do not appear in cost breakdowns.
resource "aws_ce_cost_allocation_tag" "environment" {
tag_key = "Environment"
status = "Active"
}
resource "aws_ce_cost_allocation_tag" "team" {
tag_key = "Team"
status = "Active"
}
resource "aws_ce_cost_allocation_tag" "cost_center" {
tag_key = "CostCenter"
status = "Active"
}
resource "aws_ce_cost_allocation_tag" "project" {
tag_key = "Project"
status = "Active"
}
AWS Budgets
Budgets alert you when costs exceed or are forecasted to exceed a threshold. Set them at the account level and at the team or environment level using tag filters.
resource "aws_budgets_budget" "monthly_total" {
name = "monthly-total-budget"
budget_type = "COST"
limit_amount = "5000"
limit_unit = "USD"
time_unit = "MONTHLY"
notification {
comparison_operator = "GREATER_THAN"
threshold = 80
threshold_type = "PERCENTAGE"
notification_type = "ACTUAL"
subscriber_email_addresses = [var.finance_email]
}
notification {
comparison_operator = "GREATER_THAN"
threshold = 100
threshold_type = "PERCENTAGE"
notification_type = "FORECASTED"
subscriber_email_addresses = [var.finance_email, var.engineering_lead_email]
}
}
resource "aws_budgets_budget" "production_env" {
name = "production-environment-budget"
budget_type = "COST"
limit_amount = "3000"
limit_unit = "USD"
time_unit = "MONTHLY"
cost_filter {
name = "TagKeyValue"
values = ["user:Environment$production"]
}
notification {
comparison_operator = "GREATER_THAN"
threshold = 90
threshold_type = "PERCENTAGE"
notification_type = "ACTUAL"
subscriber_email_addresses = [var.platform_team_email]
}
}
resource "aws_budgets_budget" "savings_plan_coverage" {
name = "savings-plan-coverage"
budget_type = "SAVINGS_PLANS_COVERAGE"
limit_amount = "80"
limit_unit = "PERCENTAGE"
time_unit = "MONTHLY"
notification {
comparison_operator = "LESS_THAN"
threshold = 80
threshold_type = "PERCENTAGE"
notification_type = "ACTUAL"
subscriber_email_addresses = [var.platform_team_email]
}
}
The Savings Plan coverage budget is the one most teams forget. It alerts you when less than 80 percent of your eligible compute spend is covered by a Savings Plan. If coverage drops, it means you have on-demand compute that a Savings Plan purchase would cover at 30 to 40 percent lower cost.
Compute Savings Plans
Compute Savings Plans give you a discount in exchange for a commitment to a specific dollar amount of compute spend per hour. They apply automatically to EC2, Lambda, and Fargate across any region, instance family, and operating system. This flexibility makes them almost always preferable to EC2 Instance Savings Plans, which are locked to a specific instance family and region.
The right purchase amount is your minimum consistent compute spend. Look at your Cost Explorer data for the past 3 months. Find the lowest hourly compute spend across those months. That is a safe commitment level. You can always buy more Savings Plans as your baseline grows.
resource "aws_savingsplans_savings_plan" "compute" {
savings_plan_type = "Compute"
commitment = "2.00"
term_duration_in_seconds = 94608000
payment_option = "Partial Upfront"
}
Partial Upfront gives a better discount than No Upfront and better flexibility than All Upfront. For 1-year terms at moderate commitment levels, Partial Upfront is the standard choice for most production environments.
Finding Waste with Cost Explorer
Run these Cost Explorer queries monthly as part of a regular cost review. Unattached EBS volumes: filter by service EBS and usage type containing SnapshotUsage or EBS:VolumeUsage with tag filters for resources without an instance ID. Idle load balancers: filter by service ELB and look for low RequestCount metrics in CloudWatch alongside ongoing charges. Oversized RDS instances: compare DBInstanceIdentifier against Performance Insights CPU utilization. Anything running below 10 percent average CPU for 30 days is a candidate for downsizing.
Closing Thoughts
Cost governance does not require complex tooling. Enforced tagging with AWS Config, budgets that alert before overruns, and Savings Plan coverage monitoring are the three practices that catch 80 percent of cost problems before they become significant. Build them into your account setup from the beginning rather than retrofitting them after the bill becomes uncomfortable.
Review Cost Explorer monthly with your engineering leads. Make cost a first-class engineering concern the same way you treat reliability and security. The teams that do this consistently spend 30 to 50 percent less than those who treat AWS billing as a finance problem.
Enjoy the cloud.
Osama
#AWS #CostOptimization #CloudCost #FinOps #AWSBudgets #SavingsPlans #Terraform #InfrastructureAsCode #AmazonWebServices #SolutionsArchitect #CloudComputing #CloudArchitecture #CloudGovernance #TechBlog #CloudInfrastructure #DevOps #Tagging #CostManagement #CloudFinance #Engineering
Leave a comment