Budgets
finOps.budgets creates monthly AWS Budgets in the management account, scoped by tag, with
SNS notifications.
Notifications go through SNS. Two delivery options:
- Email — each address confirms the SNS subscription on first deploy.
- Slack — the workspace must be linked to the management account. See AWS Chatbot and Slack Integration.
Example: a $100 budget for resources tagged Owner: backend, alerting to Slack and email.
import {App} from 'aws-cdk-lib';import { DataLandingZone, SlackChannel } from 'aws-data-landing-zone';
const slackBudgetNotifications: SlackChannel = { slackChannelConfigurationName: 'budget-alerts', slackWorkspaceId: 'YourWorkspaceId:', slackChannelId: 'YourChannelId',};
const app = new App();const dlz = new DataLandingZone(app, { finOps: { budgets: [ { name: 'backend', forTags: { owner: 'backend', }, amount: 100, subscribers: { slacks: [slackBudgetNotifications], }, }, ], }, ...});import aws_cdk as cdkimport aws_data_landing_zone as dlz
slack_budget_notifications = dlz.SlackChannel( slack_channel_configuration_name="budget-alerts", slack_workspace_id="YourWorkspaceId", slack_channel_id="YourChannelId",)
app = cdk.App()dlz.DataLandingZone(app, fin_ops=dlz.DlzFinOpsProps( budgets=[ dlz.DlzBudgetProps( name="backend", for_tags={"owner": "backend"}, amount=100, subscribers=dlz.BudgetSubscribers( slacks=[slack_budget_notifications], ), ), ], ), ...)Reusing the same SNS Topic
By default each budget gets its own SNS topic named ${budget.name}-topic. If several
budgets share the same subscribers, set snsTopicName on BudgetSubscribers to point them at
a single topic — fewer resources, fewer subscription confirmations.
import {App} from 'aws-cdk-lib';import { DataLandingZone, SlackChannel } from 'aws-data-landing-zone';
const subscribers: BudgetSubscribers = { snsTopicName: 'budgets', slacks: [{ slackChannelConfigurationName: 'budget-alerts', slackWorkspaceId: 'YourWorkspaceId', slackChannelId: 'YourChannelId', }],};
const app = new App();const dlz = new DataLandingZone(app, { finOps: { budgets: [ ...Defaults.budgets(100, 20, subscribers), { name: 'budget-high', amount: 1_000, subscribers }, { name: 'budget-high-1', amount: 2_000, subscribers }, ], }, ...});import aws_cdk as cdkimport aws_data_landing_zone as dlz
budget_subscribers = dlz.BudgetSubscribers( sns_topic_name= "budgets", slacks=[ dlz.SlackChannel( slack_channel_configuration_name="budget-alerts", slack_workspace_id="YourWorkspaceId", slack_channel_id="YourChannelId", ) ], emails=[ ])
app = cdk.App()dlz.DataLandingZone(app, fin_ops=dlz.DlzFinOpsProps( budgets=[ *dlz.Defaults.budgets(org_total=500, infra_dlz=20, subscribers=budget_subscribers), dlz.DlzBudgetProps(name="budget-high", amount=1_000, subscribers=budget_subscribers), dlz.DlzBudgetProps(name="budget-high-1", amount=2_000, subscribers=budget_subscribers), ], ), ...)Defaults
Defaults.budgets(orgTotal, dlzTotal, subscribers) returns two budgets:
- An org-wide budget covering every account.
- A DLZ-resources budget filtered to
Owner: 'infra'andProject: 'dlz'.
Below, a $100 org budget and a $20 DLZ budget, both alerting to the same Slack channel and email.
import {App} from 'aws-cdk-lib';import { DataLandingZone, SlackChannel } from 'aws-data-landing-zone';
const slackBudgetNotifications: SlackChannel = { slackChannelConfigurationName: 'budget-alerts', slackWorkspaceId: 'YourWorkspaceId:', slackChannelId: 'YourChannelId',};
const app = new App();const dlz = new DataLandingZone(app, { finOps: { budgets: [ ...Defaults.budgets(100, 20, { slacks: [slackBudgetNotifications], }), ], }, ...});import aws_cdk as cdkimport aws_data_landing_zone as dlz
slack_budget_notifications = dlz.SlackChannel( slack_channel_configuration_name="budget-alerts", slack_workspace_id="YourWorkspaceId", slack_channel_id="YourChannelId",)
app = cdk.App()dlz.DataLandingZone(app, fin_ops=dlz.DlzFinOpsProps( budgets=[ *dlz.Defaults.budgets( 100, 20, dlz.BudgetSubscribers( slacks=[slack_budget_notifications], ), ), ], ), ...)