aws-cost-optimization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS Cost Optimization

AWS成本优化

Apply practical FinOps controls to reduce AWS spend without sacrificing reliability or performance.
应用实用的FinOps管控措施,在不牺牲可靠性或性能的前提下降低AWS支出。

When to Use This Skill

何时使用此技能

  • Monthly AWS bill spikes unexpectedly or exceeds budget thresholds
  • Preparing cost reviews with engineering and finance teams
  • Rightsizing EC2, RDS, EKS, or Lambda workloads after load testing
  • Choosing between Savings Plans, Reserved Instances, or on-demand pricing
  • Setting up automated budget alerts and anomaly detection
  • Cleaning up unused resources (unattached EBS, idle load balancers, old snapshots)
  • Optimizing data transfer costs across regions and AZs
  • AWS月度账单意外激增或超出预算阈值
  • 准备与工程和财务团队的成本审查会议
  • 负载测试后对EC2、RDS、EKS或Lambda工作负载进行规格优化
  • 在Savings Plans、预留实例(Reserved Instances)或按需定价之间做选择
  • 设置自动化预算告警和异常检测
  • 清理未使用资源(未挂载的EBS卷、闲置负载均衡器、旧快照)
  • 跨区域和可用区(AZ)优化数据传输成本

Prerequisites

前置条件

  • AWS CLI v2 installed and configured (
    aws configure
    )
  • IAM permissions:
    ce:*
    ,
    budgets:*
    ,
    ec2:Describe*
    ,
    cloudwatch:PutMetricAlarm
    ,
    s3:PutLifecycleConfiguration
  • Cost Explorer enabled in the AWS billing console (takes 24 hours to populate)
  • Cost allocation tags activated in the Billing console
  • 已安装并配置AWS CLI v2(执行
    aws configure
  • IAM权限:
    ce:*
    ,
    budgets:*
    ,
    ec2:Describe*
    ,
    cloudwatch:PutMetricAlarm
    ,
    s3:PutLifecycleConfiguration
  • AWS账单控制台中已启用Cost Explorer(需24小时完成数据填充)
  • 账单控制台中已激活成本分配标签

Cost Review Workflow

成本审查工作流

  1. Tag every resource by team, service, environment, and cost center.
  2. Enable Cost Explorer and activate Cost and Usage Reports (CUR) to S3.
  3. Identify top spend drivers by service, account, and tag.
  4. Rightsize underutilized compute and storage based on CloudWatch metrics.
  5. Apply commitment discounts (Savings Plans or RIs) for stable baseline usage.
  6. Set budgets, anomaly alerts, and build KPI dashboards.
  7. Review monthly and iterate.
  1. 按团队、服务、环境和成本中心为所有资源打标签。
  2. 启用Cost Explorer并激活成本与使用报告(CUR)存储至S3。
  3. 按服务、账户和标签识别主要支出驱动因素。
  4. 根据CloudWatch指标对利用率不足的计算和存储资源进行规格优化。
  5. 为稳定的基线使用量应用承诺型折扣(Savings Plans或预留实例)。
  6. 设置预算、异常告警并构建KPI仪表盘。
  7. 每月审查并迭代优化。

Cost Explorer CLI Commands

Cost Explorer CLI命令

bash
undefined
bash
undefined

Get cost and usage for the last 30 days grouped by service

获取过去30天按服务分组的成本和使用情况

aws ce get-cost-and-usage
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
--metrics "BlendedCost" "UnblendedCost" "UsageQuantity"
--group-by Type=DIMENSION,Key=SERVICE
aws ce get-cost-and-usage
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
--metrics "BlendedCost" "UnblendedCost" "UsageQuantity"
--group-by Type=DIMENSION,Key=SERVICE

Get cost forecast for the next 30 days

获取未来30天的成本预测

aws ce get-cost-forecast
--time-period Start=2026-03-24,End=2026-04-24
--metric UNBLENDED_COST
--granularity MONTHLY
aws ce get-cost-forecast
--time-period Start=2026-03-24,End=2026-04-24
--metric UNBLENDED_COST
--granularity MONTHLY

Get cost grouped by a specific tag (e.g., team)

获取按特定标签(如team)分组的成本

aws ce get-cost-and-usage
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
--metrics "UnblendedCost"
--group-by Type=TAG,Key=team
aws ce get-cost-and-usage
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
--metrics "UnblendedCost"
--group-by Type=TAG,Key=team

Get rightsizing recommendations for EC2

获取EC2的规格优化建议

aws ce get-rightsizing-recommendation
--service "AmazonEC2"
--configuration '{"RecommendationTarget":"SAME_INSTANCE_FAMILY","BenefitsConsidered":true}'
aws ce get-rightsizing-recommendation
--service "AmazonEC2"
--configuration '{"RecommendationTarget":"SAME_INSTANCE_FAMILY","BenefitsConsidered":true}'

Get Savings Plans purchase recommendation

获取Savings Plans购买建议

aws ce get-savings-plans-purchase-recommendation
--savings-plans-type COMPUTE_SP
--term-in-years ONE_YEAR
--payment-option NO_UPFRONT
--lookback-period-in-days SIXTY_DAYS
aws ce get-savings-plans-purchase-recommendation
--savings-plans-type COMPUTE_SP
--term-in-years ONE_YEAR
--payment-option NO_UPFRONT
--lookback-period-in-days SIXTY_DAYS

Get Savings Plans utilization

获取Savings Plans利用率

aws ce get-savings-plans-utilization
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
aws ce get-savings-plans-utilization
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY

Get Reserved Instance utilization

获取预留实例利用率

aws ce get-reservation-utilization
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
undefined
aws ce get-reservation-utilization
--time-period Start=2026-02-01,End=2026-03-01
--granularity MONTHLY
undefined

Budget Alerts

预算告警

bash
undefined
bash
undefined

Create a monthly cost budget with email alert at 80% and 100%

创建月度成本预算,在达到80%和100%阈值时发送邮件告警

aws budgets create-budget
--account-id 123456789012
--budget '{ "BudgetName": "monthly-total", "BudgetLimit": {"Amount": "5000", "Unit": "USD"}, "TimeUnit": "MONTHLY", "BudgetType": "COST", "CostFilters": {}, "CostTypes": { "IncludeTax": true, "IncludeSubscription": true, "UseBlended": false } }'
--notifications-with-subscribers '[ { "Notification": { "NotificationType": "ACTUAL", "ComparisonOperator": "GREATER_THAN", "Threshold": 80, "ThresholdType": "PERCENTAGE" }, "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "finops@example.com"}] }, { "Notification": { "NotificationType": "ACTUAL", "ComparisonOperator": "GREATER_THAN", "Threshold": 100, "ThresholdType": "PERCENTAGE" }, "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "finops@example.com"}] } ]'
aws budgets create-budget
--account-id 123456789012
--budget '{ "BudgetName": "monthly-total", "BudgetLimit": {"Amount": "5000", "Unit": "USD"}, "TimeUnit": "MONTHLY", "BudgetType": "COST", "CostFilters": {}, "CostTypes": { "IncludeTax": true, "IncludeSubscription": true, "UseBlended": false } }'
--notifications-with-subscribers '[ { "Notification": { "NotificationType": "ACTUAL", "ComparisonOperator": "GREATER_THAN", "Threshold": 80, "ThresholdType": "PERCENTAGE" }, "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "finops@example.com"}] }, { "Notification": { "NotificationType": "ACTUAL", "ComparisonOperator": "GREATER_THAN", "Threshold": 100, "ThresholdType": "PERCENTAGE" }, "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "finops@example.com"}] } ]'

List all budgets

列出所有预算

aws budgets describe-budgets --account-id 123456789012
aws budgets describe-budgets --account-id 123456789012

Enable Cost Anomaly Detection monitor for all services

为所有服务启用成本异常检测监控

aws ce create-anomaly-monitor
--anomaly-monitor '{ "MonitorName": "all-services", "MonitorType": "DIMENSIONAL", "MonitorDimension": "SERVICE" }'
aws ce create-anomaly-monitor
--anomaly-monitor '{ "MonitorName": "all-services", "MonitorType": "DIMENSIONAL", "MonitorDimension": "SERVICE" }'

Create anomaly subscription (alert when impact > $50)

创建异常订阅(影响金额超过50美元时告警)

aws ce create-anomaly-subscription
--anomaly-subscription '{ "SubscriptionName": "cost-alerts", "MonitorArnList": ["arn:aws:ce::123456789012:anomalymonitor/monitor-id"], "Subscribers": [{"Type": "EMAIL", "Address": "finops@example.com"}], "Threshold": 50, "Frequency": "DAILY" }'
undefined
aws ce create-anomaly-subscription
--anomaly-subscription '{ "SubscriptionName": "cost-alerts", "MonitorArnList": ["arn:aws:ce::123456789012:anomalymonitor/monitor-id"], "Subscribers": [{"Type": "EMAIL", "Address": "finops@example.com"}], "Threshold": 50, "Frequency": "DAILY" }'
undefined

CloudWatch Cost Alarm

CloudWatch成本告警

bash
undefined
bash
undefined

Create alarm for estimated charges exceeding $4000

创建预估费用超过4000美元的告警

aws cloudwatch put-metric-alarm
--alarm-name "billing-alarm-4000"
--alarm-description "Alert when estimated charges exceed $4000"
--metric-name EstimatedCharges
--namespace AWS/Billing
--statistic Maximum
--period 21600
--threshold 4000
--comparison-operator GreaterThanThreshold
--evaluation-periods 1
--dimensions Name=Currency,Value=USD
--alarm-actions "arn:aws:sns:us-east-1:123456789012:billing-alerts"
--treat-missing-data notBreaching
undefined
aws cloudwatch put-metric-alarm
--alarm-name "billing-alarm-4000"
--alarm-description "Alert when estimated charges exceed $4000"
--metric-name EstimatedCharges
--namespace AWS/Billing
--statistic Maximum
--period 21600
--threshold 4000
--comparison-operator GreaterThanThreshold
--evaluation-periods 1
--dimensions Name=Currency,Value=USD
--alarm-actions "arn:aws:sns:us-east-1:123456789012:billing-alerts"
--treat-missing-data notBreaching
undefined

Find and Clean Unused Resources

查找并清理未使用资源

bash
undefined
bash
undefined

List unattached EBS volumes (wasted storage spend)

列出未挂载的EBS卷(浪费的存储支出)

aws ec2 describe-volumes
--filters Name=status,Values=available
--query "Volumes[].{ID:VolumeId,Size:Size,Created:CreateTime}"
--output table
aws ec2 describe-volumes
--filters Name=status,Values=available
--query "Volumes[].{ID:VolumeId,Size:Size,Created:CreateTime}"
--output table

Find old EBS snapshots (older than 90 days)

查找旧EBS快照(超过90天)

aws ec2 describe-snapshots
--owner-ids self
--query "Snapshots[?StartTime<='2025-12-24'].{ID:SnapshotId,Size:VolumeSize,Date:StartTime}"
--output table
aws ec2 describe-snapshots
--owner-ids self
--query "Snapshots[?StartTime<='2025-12-24'].{ID:SnapshotId,Size:VolumeSize,Date:StartTime}"
--output table

List unused Elastic IPs (charged when not associated)

列出未使用的弹性IP(未关联时会产生费用)

aws ec2 describe-addresses
--query "Addresses[?AssociationId==null].{IP:PublicIp,AllocId:AllocationId}"
--output table
aws ec2 describe-addresses
--query "Addresses[?AssociationId==null].{IP:PublicIp,AllocId:AllocationId}"
--output table

Find idle load balancers (zero healthy targets)

查找闲置负载均衡器(健康目标数为0)

aws elbv2 describe-target-health
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-tg/abc123
aws elbv2 describe-target-health
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-tg/abc123

List RDS instances and their utilization

列出RDS实例及其利用率

aws cloudwatch get-metric-statistics
--namespace AWS/RDS
--metric-name CPUUtilization
--dimensions Name=DBInstanceIdentifier,Value=mydb
--start-time 2026-03-17T00:00:00Z
--end-time 2026-03-24T00:00:00Z
--period 86400
--statistics Average
undefined
aws cloudwatch get-metric-statistics
--namespace AWS/RDS
--metric-name CPUUtilization
--dimensions Name=DBInstanceIdentifier,Value=mydb
--start-time 2026-03-17T00:00:00Z
--end-time 2026-03-24T00:00:00Z
--period 86400
--statistics Average
undefined

S3 Lifecycle Cost Optimization

S3生命周期成本优化

bash
undefined
bash
undefined

Apply tiered lifecycle policy to reduce storage costs

应用分层生命周期策略降低存储成本

aws s3api put-bucket-lifecycle-configuration
--bucket my-data-bucket
--lifecycle-configuration '{ "Rules": [ { "ID": "TierDownOldData", "Status": "Enabled", "Filter": {"Prefix": ""}, "Transitions": [ {"Days": 30, "StorageClass": "STANDARD_IA"}, {"Days": 90, "StorageClass": "GLACIER"}, {"Days": 365, "StorageClass": "DEEP_ARCHIVE"} ], "NoncurrentVersionTransitions": [ {"NoncurrentDays": 30, "StorageClass": "GLACIER"} ], "NoncurrentVersionExpiration": {"NoncurrentDays": 90} }, { "ID": "CleanupIncompleteUploads", "Status": "Enabled", "Filter": {"Prefix": ""}, "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7} } ] }'
undefined
aws s3api put-bucket-lifecycle-configuration
--bucket my-data-bucket
--lifecycle-configuration '{ "Rules": [ { "ID": "TierDownOldData", "Status": "Enabled", "Filter": {"Prefix": ""}, "Transitions": [ {"Days": 30, "StorageClass": "STANDARD_IA"}, {"Days": 90, "StorageClass": "GLACIER"}, {"Days": 365, "StorageClass": "DEEP_ARCHIVE"} ], "NoncurrentVersionTransitions": [ {"NoncurrentDays": 30, "StorageClass": "GLACIER"} ], "NoncurrentVersionExpiration": {"NoncurrentDays": 90} }, { "ID": "CleanupIncompleteUploads", "Status": "Enabled", "Filter": {"Prefix": ""}, "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7} } ] }'
undefined

Terraform Budget and Alarm Example

Terraform预算与告警示例

hcl
resource "aws_budgets_budget" "monthly" {
  name         = "monthly-total"
  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 = ["finops@example.com"]
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["finops@example.com"]
  }
}

resource "aws_cloudwatch_metric_alarm" "billing" {
  alarm_name          = "billing-alarm-4000"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 1
  metric_name         = "EstimatedCharges"
  namespace           = "AWS/Billing"
  period              = 21600
  statistic           = "Maximum"
  threshold           = 4000
  alarm_description   = "Billing exceeds $4000"
  alarm_actions       = [aws_sns_topic.billing_alerts.arn]

  dimensions = {
    Currency = "USD"
  }
}
hcl
resource "aws_budgets_budget" "monthly" {
  name         = "monthly-total"
  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 = ["finops@example.com"]
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["finops@example.com"]
  }
}

resource "aws_cloudwatch_metric_alarm" "billing" {
  alarm_name          = "billing-alarm-4000"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 1
  metric_name         = "EstimatedCharges"
  namespace           = "AWS/Billing"
  period              = 21600
  statistic           = "Maximum"
  threshold           = 4000
  alarm_description   = "Billing exceeds $4000"
  alarm_actions       = [aws_sns_topic.billing_alerts.arn]

  dimensions = {
    Currency = "USD"
  }
}

Scheduling Non-Production Shutdowns

调度非生产环境停机

bash
undefined
bash
undefined

Stop all dev instances tagged Environment=dev (run via EventBridge + Lambda)

停止所有标记为Environment=dev的开发实例(通过EventBridge + Lambda运行)

aws ec2 describe-instances
--filters "Name=tag:Environment,Values=dev" "Name=instance-state-name,Values=running"
--query "Reservations[].Instances[].InstanceId"
--output text | xargs -n1 aws ec2 stop-instances --instance-ids
aws ec2 describe-instances
--filters "Name=tag:Environment,Values=dev" "Name=instance-state-name,Values=running"
--query "Reservations[].Instances[].InstanceId"
--output text | xargs -n1 aws ec2 stop-instances --instance-ids

Scale down dev ECS services to zero at night

在夜间将开发ECS服务缩容至0

aws ecs update-service
--cluster dev-cluster
--service dev-api
--desired-count 0
undefined
aws ecs update-service
--cluster dev-cluster
--service dev-api
--desired-count 0
undefined

Troubleshooting

故障排查

ProblemCauseFix
Cost Explorer returns empty dataCE not enabled or < 24h oldEnable in Billing console, wait 24h
Budget alert not firingSNS subscription not confirmedCheck email and confirm subscription
Rightsizing shows no recommendationsNot enough usage dataWait 14 days for sufficient metrics
Savings Plans utilization lowOver-purchased or workload changedReview and adjust SP coverage
Unattached EBS not showingWrong region queriedLoop through all active regions
Billing alarm never triggersBilling metrics only in us-east-1Create alarm in us-east-1 region
CUR data missing in S3Report not configured or bucket policy wrongVerify CUR setup in Billing console
Tag-based cost allocation emptyTags not activatedActivate cost allocation tags in Billing
问题原因解决方法
Cost Explorer返回空数据未启用CE或数据生成不足24小时在账单控制台启用CE,等待24小时
预算告警未触发SNS订阅未确认检查邮箱并确认订阅
规格优化无建议可用使用数据不足等待14天以获取足够指标
Savings Plans利用率低过度购买或工作负载变化审查并调整SP覆盖范围
未显示未挂载的EBS卷查询区域错误遍历所有活跃区域
账单告警从未触发账单指标仅在us-east-1区域可用在us-east-1区域创建告警
S3中缺少CUR数据报告未配置或存储桶策略错误在账单控制台验证CUR设置
基于标签的成本分配为空标签未激活在账单控制台激活成本分配标签

Related Skills

相关技能

  • aws-ec2 - EC2 operations, sizing, and Spot instances
  • aws-s3 - S3 storage classes and lifecycle controls
  • aws-rds - RDS instance sizing and reserved instances
  • aws-lambda - Lambda pricing and concurrency tuning
  • terraform-aws - Codifying cost guardrails in IaC
  • aws-ec2 - EC2操作、规格选型和Spot实例
  • aws-s3 - S3存储类别和生命周期管控
  • aws-rds - RDS实例规格选型和预留实例
  • aws-lambda - Lambda定价和并发调优
  • terraform-aws - 在IaC中编码成本防护规则