Advanced Cloud Cost Optimization Strategy Teams Overlook
Why a proactive idle‑resource strategy matters
Most cloud‑native teams focus on rightsizing instances or deleting obvious orphaned volumes. The hidden cost that slips past most audits is idle capacity that never triggers a warning – for example, an EBS volume attached to a stopped instance, a NAT gateway that routes no traffic, or a Lambda function with a provisioned concurrency that never fires. Those resources accrue charges every hour or every gigabyte, and because they are technically "in use" they do not appear in simple unused‑resource reports.
A proactive strategy catches the waste before it appears on the bill. By continuously monitoring configuration changes, usage patterns, and cost allocation tags, you can trigger automated remediation actions that keep the environment lean without manual hunting.
Building an automated idle detection pipeline with AWS Config
AWS Config provides a history of configuration changes and can evaluate resources against custom rules in near real time. Coupling Config with a Lambda function creates a closed‑loop system that detects idle resources and either notifies owners or deletes the resource automatically.
Enable AWS Config and create rules
- Open the AWS Management Console, navigate to Services → Config.
- Click Settings → Enable. Choose All resources for the resource types you want to monitor (EC2, EBS, NAT Gateways, Lambda, etc.).
- In the Rules tab, click Add rule.
- Select Custom rule and give it a name, e.g.,
idle-nat-gateway. - Set the Trigger type to Configuration changes.
- For the Lambda function ARN, you will create a function in the next step.
- Save the rule.
Repeat the process for other resource types, using descriptive names such as idle-ebs-volume, idle-provisioned-concurrency, and idle-elastic-ip.
Write custom Lambda for remediation
Create a Lambda function that receives the Config event, evaluates usage metrics, and takes action. Below is a minimal Python example for a NAT gateway:
import boto3, json, os
def lambda_handler(event, context):
# Extract the resource ID from the Config event
invoking_event = json.loads(event['invokingEvent'])
configuration_item = invoking_event['configurationItem']
nat_id = configuration_item['resourceId']
region = configuration_item['awsRegion']
# Check CloudWatch metric for BytesOutPerSecond over the last 7 days
cw = boto3.client('cloudwatch', region_name=region)
metric = cw.get_metric_statistics(
Namespace='AWS/NATGateway',
MetricName='BytesOutPerSecond',
Dimensions=[{'Name': 'NatGatewayId', 'Value': nat_id}],
StartTime=datetime.utcnow() - timedelta(days=7),
EndTime=datetime.utcnow(),
Period=86400,
Statistics=['Average']
)
avg_out = metric['Datapoints'][0]['Average'] if metric['Datapoints'] else 0
# If average outbound traffic is 0, delete the NAT gateway
if avg_out == 0:
ec2 = boto3.client('ec2', region_name=region)
ec2.delete_nat_gateway(NatGatewayId=nat_id)
print(f"Deleted idle NAT gateway {nat_id}")
else:
print(f"NAT gateway {nat_id} is active (avg {avg_out} Bps)")
Deploy the function:
aws lambda create-function \
--function-name idle-nat-gateway-remediate \
--runtime python3.9 \
--role arn:aws:iam::123456789012:role/ConfigLambdaRole \
--handler lambda_function.lambda_handler \
--zip-file fileb://idle-nat-gateway.zip
Give the Lambda role permission to read CloudWatch metrics and delete the target resource:
{
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Action": ["cloudwatch:GetMetricStatistics"], "Resource": "*"},
{"Effect": "Allow", "Action": ["ec2:DeleteNatGateway"], "Resource": "*"}
]
}
Repeat similar logic for other resources, adjusting the metric namespace and deletion API call.
Integrating Compute Optimizer and Trusted Advisor data
AWS Compute Optimizer analyzes historical utilization and recommends instance types, EBS volume types, and Auto Scaling group configurations. Trusted Advisor provides checks for under‑utilized resources. By pulling both data sets into a single dashboard you get a holistic view of idle capacity.
- Enable Compute Optimizer via the console (Services → Compute Optimizer → Get started). Choose All recommendation types.
- Export recommendations to an S3 bucket using the Export recommendations button. This creates a CSV file you can query with Athena.
- Enable Trusted Advisor checks for Low Utilization Amazon EC2 Instances, Underutilized Amazon EBS Volumes, and Idle Load Balancers.
- Use the AWS CLI to pull the latest Trusted Advisor JSON:
aws support describe-trusted-advisor-check-result \
--check-id eW7HH7k2T9 \
--output json > ta-ec2-idle.json
- Load both CSV and JSON into a temporary Athena table and run a query that flags resources appearing in both lists. Those are high‑confidence idle candidates.
Cost allocation tags and chargeback: turning data into action
Even with automated detection, you need a governance layer that holds teams accountable. Cost allocation tags let you attribute spend to owners, projects, or environments.
- In the console, go to Billing → Cost Allocation Tags.
- Activate both aws:createdBy (automatically added by many services) and a custom Team tag.
- Enforce tag compliance with an AWS Config rule called
required-tags. - Export the Cost Explorer report for the last month, group by Team tag, and share the CSV with engineering leads.
- Combine the tag report with the idle‑resource list generated by your Config‑Lambda pipeline. When a resource is flagged as idle, the report automatically shows the owning team, making it easy to open a ticket or send a Slack notification.
Comparison of idle‑resource detection approaches
| Approach | Setup effort | Real‑time detection | Automated remediation | Visibility across accounts |
|---|---|---|---|---|
| Manual console audit | Low | No | No | Low |
| Cost Explorer filters | Medium | No | No | Medium |
| AWS Trusted Advisor | Medium | Yes (daily) | No | Medium |
| AWS Config + Lambda (custom) | High | Yes (minutes) | Yes | High (supports Organization‑wide aggregation) |
| Third‑party SaaS tool | Variable | Yes | Yes | High |
The table shows why most teams settle for manual or Trusted Advisor checks: they require less engineering time. The Config‑Lambda pipeline demands more initial work but delivers near‑real‑time remediation and organization‑wide visibility.
Embedding the pipeline into CI/CD and governance
Treat the idle‑resource pipeline as infrastructure code. Store the Config rule definitions, Lambda source, and IAM policies in a Git repository and deploy with AWS CloudFormation or Terraform.
resource "aws_config_config_rule" "idle_nat" {
name = "idle-nat-gateway"
source {
owner = "CUSTOM_LAMBDA"
source_identifier = aws_lambda_function.idle_nat.arn
}
scope {
compliance_resource_types = ["AWS::EC2::NatGateway"]
}
}
Add a pipeline stage that runs terraform plan and apply on every merge to main. Tag the Lambda version with the commit SHA so you can roll back if a rule produces false positives.
Governance teams can enforce the pipeline by requiring a pull request approval from a FinOps lead before any rule change is merged. This creates an audit trail and ensures that cost‑saving automation does not accidentally delete critical resources.
Frequently asked questions
How often does AWS Config evaluate custom rules?
AWS Config evaluates a rule when the resource changes state and then at a configurable periodic interval (default is 24 hours). For idle‑resource detection you typically set the interval to 1 hour to catch resources that become idle quickly.
Can the Lambda function delete resources without human approval?
Yes, but it is recommended to start with a notification‑only mode. Change the Lambda code to publish to an SNS topic instead of calling the delete API. Once confidence is high, switch the flag to enable deletion.
What if a resource is idle only during off‑peak hours?
Include a time‑window check in the Lambda logic. For example, only consider a resource idle if the average metric over the last 7 days is zero and the current hour is within the defined off‑peak window (e.g., 22:00‑06:00 UTC).
Does this strategy work for multi‑account organizations?
Yes. Enable AWS Config Organization‑wide in the master account, then create an aggregation source for each member account. The Config rules run in each account, but you can centralize the Lambda functions in a security‑orchestrator account and grant cross‑account permissions.
Key takeaways
- Idle resources can exist even when they appear attached or provisioned.
- AWS Config combined with a custom Lambda provides near‑real‑time detection and automated remediation.
- Pulling Compute Optimizer and Trusted Advisor data into a single query surface high‑confidence waste.
- Cost allocation tags turn raw data into actionable chargeback reports.
- Treat the detection pipeline as code, embed it in CI/CD, and enforce governance approvals.
- Start with notification‑only mode, then graduate to automatic deletion once you trust the logic.
Closing note
CloudBudgetMaster automates this. It scans AWS read‑only today and reports the dollar impact of idle and wasted resources; GCP, Azure and Snowflake support is coming soon.
CloudBudgetMaster