This check flags AWS accounts with no budget configured, or budgets that exist but send no notifications. Without one, a runaway service or compromised key can rack up thousands in charges before anyone notices. Fix it by creating an AWS Budget with email and SNS alerts at multiple thresholds.
Cost is a security signal. A sudden spike in your AWS bill is often the first visible symptom of a compromised access key being used to mine crypto, or a misconfigured autoscaling group spinning up hundreds of instances. The No Budget Configured check looks for accounts that have no early warning system for spend, which means the first time you find out about a problem is when the invoice lands.
The Lensix cost_budgets check (module cost_checks) inspects your AWS account for the presence of at least one budget and verifies that the budget actually notifies a human when thresholds are crossed. A budget with no alert subscribers is almost as useless as no budget at all.
What this check detects
The check evaluates two related conditions and fails if either is true:
- No AWS Budget exists in the account. AWS Budgets is the native service for tracking cost and usage against a defined limit.
- A budget exists but has no notification alerts. The budget tracks spend silently with no subscribers configured, so nobody gets paged or emailed when you blow past your threshold.
Both states leave you with zero proactive cost visibility. You are relying on someone remembering to open the Billing console, which never reliably happens.
Note: AWS Budgets is a global, account-level service tied to the management account in an organization. Budgets are not regional, so you configure them once per account rather than per region.
Why it matters
The business and security impact of flying blind on cost is bigger than most teams assume.
Compromised credentials get expensive fast
Leaked AWS access keys are one of the most common cloud incidents. Attackers who get a valid key frequently spin up large GPU or compute instances across every region to mine cryptocurrency. A handful of p4d.24xlarge instances running around the clock can burn through tens of thousands of dollars in days. A budget alert at 50 percent of your normal spend would catch this within hours, not at month end.
Danger: Without budget alerts, a compromised key can run up a five or six figure bill before anyone notices. AWS may grant a one-time courtesy credit for fraud, but they are under no obligation to, and repeated incidents will not be forgiven.
Runaway infrastructure
It does not take an attacker. A bad autoscaling policy, a recursive Lambda invoking itself, an S3 bucket with versioning and no lifecycle rules, or a forgotten test environment left running over a holiday weekend all quietly drain money. Budget alerts turn these slow leaks into something you can act on immediately.
No accountability or forecasting
Engineering teams that cannot see their spend cannot own it. Budgets give each team or environment a number to track against, which shifts cost from a finance afterthought into an engineering responsibility. Forecasted budget alerts also warn you that you are trending over before you actually exceed the limit.
How to fix it
You can create a budget with notifications through the console, the CLI, or infrastructure as code. The key is that the budget must have at least one notification with subscribers attached.
Option 1: AWS Console
- Open the Billing and Cost Management console and select Budgets in the left nav.
- Click Create budget and choose Customize (advanced) for full control, or use the Monthly cost budget template.
- Set a budget amount. A common starting point is your trailing three-month average plus a margin, or a flat ceiling you never expect to hit.
- Under Configure alerts, add thresholds. Set at least three: one actual-cost alert at 80 percent, one at 100 percent, and one forecasted alert at 100 percent.
- Add email recipients, and ideally an SNS topic that fans out to Slack or PagerDuty.
- Review and create.
Option 2: AWS CLI
First, create a JSON file describing the budget:
{
"BudgetName": "monthly-account-budget",
"BudgetLimit": {
"Amount": "5000",
"Unit": "USD"
},
"TimeUnit": "MONTHLY",
"BudgetType": "COST"
}
Then a second file for the notifications and subscribers:
[
{
"Notification": {
"NotificationType": "ACTUAL",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 80,
"ThresholdType": "PERCENTAGE"
},
"Subscribers": [
{ "SubscriptionType": "EMAIL", "Address": "[email protected]" }
]
},
{
"Notification": {
"NotificationType": "FORECASTED",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 100,
"ThresholdType": "PERCENTAGE"
},
"Subscribers": [
{ "SubscriptionType": "EMAIL", "Address": "[email protected]" },
{ "SubscriptionType": "SNS", "Address": "arn:aws:sns:us-east-1:111122223333:budget-alerts" }
]
}
]
Create the budget with both attached:
aws budgets create-budget \
--account-id 111122223333 \
--budget file://budget.json \
--notifications-with-subscribers file://notifications.json
Warning: If you use an SNS topic as a subscriber, the topic's access policy must allow the budgets.amazonaws.com principal to publish to it. Otherwise the notification silently fails to deliver. Verify the topic policy after creating the budget.
The SNS topic policy needs a statement like this:
{
"Sid": "AllowBudgets",
"Effect": "Allow",
"Principal": { "Service": "budgets.amazonaws.com" },
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-1:111122223333:budget-alerts"
}
Option 3: Terraform
resource "aws_budgets_budget" "monthly" {
name = "monthly-account-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 = ["[email protected]"]
}
notification {
comparison_operator = "GREATER_THAN"
threshold = 100
threshold_type = "PERCENTAGE"
notification_type = "FORECASTED"
subscriber_email_addresses = ["[email protected]"]
subscriber_sns_topic_arns = [aws_sns_topic.budget_alerts.arn]
}
}
Tip: Forecasted alerts are the ones that catch problems early. ACTUAL alerts tell you the money is already spent. FORECASTED alerts use AWS trend prediction to warn you mid-month that you are on track to exceed the limit, giving you time to react.
How to prevent it from happening again
A one-off budget is easy to forget, especially when you add new accounts. Bake budget creation into the account provisioning process so it can never be skipped.
Make budgets part of account vending
If you use AWS Control Tower or an account factory, attach a budget to the account baseline. Every new account then ships with a default budget and alert from day one. The Terraform aws_budgets_budget resource above belongs in your landing zone module, not in individual project repos.
Gate it in CI/CD with policy as code
Use a policy engine to fail any Terraform plan that provisions an account or environment without a budget. A simple Open Policy Agent rule with conftest can enforce this:
package main
deny[msg] {
input.resource_changes[_].type == "aws_budgets_budget"
count([n | input.resource_changes[_].type == "aws_budgets_budget"]) == 0
msg := "No aws_budgets_budget defined in this stack"
}
Continuous monitoring
Policy as code only catches what flows through your pipeline. Resources created by hand in the console, or budgets that get deleted later, will slip past. Run the Lensix cost_budgets check on a schedule across every account so a missing or alert-less budget is flagged regardless of how it got that way.
Tip: Pair the account-level budget with per-service or per-tag budgets filtered by a team or environment cost allocation tag. This gives each team its own alert and stops one noisy account from masking another team's overspend.
Best practices
- Always attach notifications. A budget with no subscribers tracks nothing useful. This check fails on exactly that case for a reason.
- Use multiple thresholds. Alert at 50, 80, and 100 percent so you see a problem building rather than only after it breaches.
- Include a forecasted alert. It is the earliest possible warning that spend is trending wrong.
- Route alerts to a channel people watch. Email alone gets ignored. Wire SNS into Slack, Teams, or your on-call tool.
- Set budgets per account and per team. Account-wide budgets catch the big incidents; tagged budgets enforce ownership.
- Review limits quarterly. A budget set two years ago at half your current spend just generates noise everyone learns to ignore.
- Enable cost anomaly detection too. AWS Cost Anomaly Detection uses machine learning to spot unusual spend patterns that a fixed threshold would miss, and complements budgets well.
Budgets are cheap insurance. The first two budgets per account are free, and the visibility they buy you can be the difference between a contained incident and a surprise five figure invoice.

