@composurecdk/budgets 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/alarm-config.d.ts.map +1 -0
- package/dist/commonjs/alarm-config.js +3 -0
- package/dist/{alarm-config.js.map → commonjs/alarm-config.js.map} +1 -1
- package/dist/{budget-alarm-builder.d.ts → commonjs/budget-alarm-builder.d.ts} +5 -2
- package/dist/commonjs/budget-alarm-builder.d.ts.map +1 -0
- package/dist/commonjs/budget-alarm-builder.js +149 -0
- package/dist/commonjs/budget-alarm-builder.js.map +1 -0
- package/dist/commonjs/budget-alarms.d.ts.map +1 -0
- package/dist/commonjs/budget-alarms.js +53 -0
- package/dist/commonjs/budget-alarms.js.map +1 -0
- package/dist/{budget-builder.d.ts → commonjs/budget-builder.d.ts} +3 -1
- package/dist/commonjs/budget-builder.d.ts.map +1 -0
- package/dist/commonjs/budget-builder.js +170 -0
- package/dist/commonjs/budget-builder.js.map +1 -0
- package/dist/commonjs/currency.d.ts.map +1 -0
- package/dist/commonjs/currency.js +39 -0
- package/dist/commonjs/currency.js.map +1 -0
- package/dist/commonjs/defaults.d.ts.map +1 -0
- package/dist/commonjs/defaults.js +94 -0
- package/dist/commonjs/defaults.js.map +1 -0
- package/dist/commonjs/email.d.ts.map +1 -0
- package/dist/commonjs/email.js +33 -0
- package/dist/commonjs/email.js.map +1 -0
- package/dist/commonjs/index.d.ts.map +1 -0
- package/dist/commonjs/index.js +18 -0
- package/dist/commonjs/index.js.map +1 -0
- package/dist/commonjs/notifications.d.ts.map +1 -0
- package/dist/commonjs/notifications.js +43 -0
- package/dist/commonjs/notifications.js.map +1 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/commonjs/topic-policy.d.ts.map +1 -0
- package/dist/commonjs/topic-policy.js +45 -0
- package/dist/commonjs/topic-policy.js.map +1 -0
- package/dist/esm/alarm-config.d.ts +61 -0
- package/dist/esm/alarm-config.d.ts.map +1 -0
- package/dist/esm/alarm-config.js.map +1 -0
- package/dist/esm/budget-alarm-builder.d.ts +150 -0
- package/dist/esm/budget-alarm-builder.d.ts.map +1 -0
- package/dist/{budget-alarm-builder.js → esm/budget-alarm-builder.js} +8 -2
- package/dist/esm/budget-alarm-builder.js.map +1 -0
- package/dist/esm/budget-alarms.d.ts +22 -0
- package/dist/esm/budget-alarms.d.ts.map +1 -0
- package/dist/esm/budget-alarms.js.map +1 -0
- package/dist/esm/budget-builder.d.ts +192 -0
- package/dist/esm/budget-builder.d.ts.map +1 -0
- package/dist/{budget-builder.js → esm/budget-builder.js} +7 -1
- package/dist/esm/budget-builder.js.map +1 -0
- package/dist/esm/currency.d.ts +21 -0
- package/dist/esm/currency.d.ts.map +1 -0
- package/dist/esm/currency.js.map +1 -0
- package/dist/esm/defaults.d.ts +57 -0
- package/dist/esm/defaults.d.ts.map +1 -0
- package/dist/esm/defaults.js.map +1 -0
- package/dist/esm/email.d.ts +28 -0
- package/dist/esm/email.d.ts.map +1 -0
- package/dist/esm/email.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/notifications.d.ts +88 -0
- package/dist/esm/notifications.d.ts.map +1 -0
- package/dist/esm/notifications.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/topic-policy.d.ts +20 -0
- package/dist/esm/topic-policy.d.ts.map +1 -0
- package/dist/esm/topic-policy.js.map +1 -0
- package/package.json +35 -16
- package/dist/alarm-config.d.ts.map +0 -1
- package/dist/budget-alarm-builder.d.ts.map +0 -1
- package/dist/budget-alarm-builder.js.map +0 -1
- package/dist/budget-alarms.d.ts.map +0 -1
- package/dist/budget-alarms.js.map +0 -1
- package/dist/budget-builder.d.ts.map +0 -1
- package/dist/budget-builder.js.map +0 -1
- package/dist/currency.d.ts.map +0 -1
- package/dist/currency.js.map +0 -1
- package/dist/defaults.d.ts.map +0 -1
- package/dist/defaults.js.map +0 -1
- package/dist/email.d.ts.map +0 -1
- package/dist/email.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/notifications.d.ts.map +0 -1
- package/dist/notifications.js.map +0 -1
- package/dist/topic-policy.d.ts.map +0 -1
- package/dist/topic-policy.js.map +0 -1
- /package/dist/{alarm-config.d.ts → commonjs/alarm-config.d.ts} +0 -0
- /package/dist/{budget-alarms.d.ts → commonjs/budget-alarms.d.ts} +0 -0
- /package/dist/{currency.d.ts → commonjs/currency.d.ts} +0 -0
- /package/dist/{defaults.d.ts → commonjs/defaults.d.ts} +0 -0
- /package/dist/{email.d.ts → commonjs/email.d.ts} +0 -0
- /package/dist/{index.d.ts → commonjs/index.d.ts} +0 -0
- /package/dist/{notifications.d.ts → commonjs/notifications.d.ts} +0 -0
- /package/dist/{topic-policy.d.ts → commonjs/topic-policy.d.ts} +0 -0
- /package/dist/{alarm-config.js → esm/alarm-config.js} +0 -0
- /package/dist/{budget-alarms.js → esm/budget-alarms.js} +0 -0
- /package/dist/{currency.js → esm/currency.js} +0 -0
- /package/dist/{defaults.js → esm/defaults.js} +0 -0
- /package/dist/{email.js → esm/email.js} +0 -0
- /package/dist/{index.js → esm/index.js} +0 -0
- /package/dist/{notifications.js → esm/notifications.js} +0 -0
- /package/dist/{topic-policy.js → esm/topic-policy.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-config.d.ts","sourceRoot":"","sources":["../../src/alarm-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,2BAA4B,SAAQ,WAAW;IAC9D;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,2BAA2B,GAAG,KAAK,CAAC;CACxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alarm-config.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"alarm-config.js","sourceRoot":"","sources":["../../src/alarm-config.ts"],"names":[],"mappings":""}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type CfnBudget } from "aws-cdk-lib/aws-budgets";
|
|
2
2
|
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
3
3
|
import { type IConstruct } from "constructs";
|
|
4
|
-
import {
|
|
4
|
+
import { COPY_STATE, type Lifecycle, type Resolvable } from "@composurecdk/core";
|
|
5
|
+
import { type ITaggedBuilder } from "@composurecdk/cloudformation";
|
|
5
6
|
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
6
7
|
import type { BudgetAlarmConfig } from "./alarm-config.js";
|
|
7
8
|
import type { BudgetBuilderResult } from "./budget-builder.js";
|
|
@@ -54,7 +55,7 @@ export interface BudgetAlarmBuilderResult {
|
|
|
54
55
|
*
|
|
55
56
|
* @see {@link createBudgetAlarmBuilder}
|
|
56
57
|
*/
|
|
57
|
-
export type IBudgetAlarmBuilder =
|
|
58
|
+
export type IBudgetAlarmBuilder = ITaggedBuilder<BudgetAlarmBuilderProps, BudgetAlarmBuilder>;
|
|
58
59
|
/**
|
|
59
60
|
* Shared alarm-assembly used by both {@link createBudgetBuilder} (in its
|
|
60
61
|
* own stack) and {@link createBudgetAlarmBuilder} (typically in a separate
|
|
@@ -103,6 +104,8 @@ declare class BudgetAlarmBuilder implements Lifecycle<BudgetAlarmBuilderResult>
|
|
|
103
104
|
* live with the recommended one.
|
|
104
105
|
*/
|
|
105
106
|
addAlarm(key: string, configure: (alarm: AlarmDefinitionBuilder<CfnBudget>) => AlarmDefinitionBuilder<CfnBudget>): this;
|
|
107
|
+
/** @internal — see ADR-0005. */
|
|
108
|
+
[COPY_STATE](target: BudgetAlarmBuilder): void;
|
|
106
109
|
build(scope: IConstruct, id: string, context?: Record<string, object>): BudgetAlarmBuilderResult;
|
|
107
110
|
}
|
|
108
111
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-alarm-builder.d.ts","sourceRoot":"","sources":["../../src/budget-alarm-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAW,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,KAAK,cAAc,EAAiB,MAAM,8BAA8B,CAAC;AAElF,OAAO,EAAE,sBAAsB,EAAgB,MAAM,0BAA0B,CAAC;AAChF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;AAsB9F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,GAAG,SAAS,EACvD,OAAO,GAAE;IACP,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;IAC9C,YAAY,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;CAC/C,GACL,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAoBvB;AAED,cAAM,kBAAmB,YAAW,SAAS,CAAC,wBAAwB,CAAC;;IACrE,KAAK,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAM;IAI7C;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAKrD;;;;;;;;;OASG;IACH,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC,SAAS,CAAC,KAAK,sBAAsB,CAAC,SAAS,CAAC,GACzF,IAAI;IAKP,gCAAgC;IAChC,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAK9C,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,wBAAwB;CASjG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,wBAAwB,IAAI,mBAAmB,CAE9D"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildBudgetAlarms = buildBudgetAlarms;
|
|
4
|
+
exports.createBudgetAlarmBuilder = createBudgetAlarmBuilder;
|
|
5
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
6
|
+
const core_1 = require("@composurecdk/core");
|
|
7
|
+
const cloudformation_1 = require("@composurecdk/cloudformation");
|
|
8
|
+
const cloudwatch_1 = require("@composurecdk/cloudwatch");
|
|
9
|
+
const budget_alarms_js_1 = require("./budget-alarms.js");
|
|
10
|
+
/**
|
|
11
|
+
* The `AWS/Billing EstimatedCharges` metric is emitted in `us-east-1`
|
|
12
|
+
* only. CloudWatch alarms are regional, so alarms created in any other
|
|
13
|
+
* region will never receive data. Warn (don't error) when alarms are
|
|
14
|
+
* being created outside `us-east-1`, unless the region is an unresolved
|
|
15
|
+
* token (env-agnostic stack — user knows best).
|
|
16
|
+
*/
|
|
17
|
+
function warnIfNotUsEast1(scope) {
|
|
18
|
+
const region = aws_cdk_lib_1.Stack.of(scope).region;
|
|
19
|
+
if (aws_cdk_lib_1.Token.isUnresolved(region))
|
|
20
|
+
return;
|
|
21
|
+
if (region === "us-east-1")
|
|
22
|
+
return;
|
|
23
|
+
aws_cdk_lib_1.Annotations.of(scope).addWarningV2("@composurecdk/budgets:alarm-region", `AWS/Billing EstimatedCharges is emitted in us-east-1 only, but this stack is ` +
|
|
24
|
+
`deployed in "${region}". CloudWatch alarms created here will not fire. Deploy the ` +
|
|
25
|
+
`stack in us-east-1, or use createBudgetAlarmBuilder() routed to a ` +
|
|
26
|
+
`us-east-1 stack via compose().withStacks().`);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Shared alarm-assembly used by both {@link createBudgetBuilder} (in its
|
|
30
|
+
* own stack) and {@link createBudgetAlarmBuilder} (typically in a separate
|
|
31
|
+
* `us-east-1` stack). Materialises the recommended billing alarm and any
|
|
32
|
+
* user-supplied custom alarms, emits the region warning if the resulting
|
|
33
|
+
* scope is not in `us-east-1`, and creates the alarm constructs.
|
|
34
|
+
*
|
|
35
|
+
* The `target.budget` reference is only needed for custom alarms added
|
|
36
|
+
* via `addAlarm()` — the recommended `EstimatedCharges` alarm is
|
|
37
|
+
* account-level and does not key off the budget itself, so `target` may
|
|
38
|
+
* be omitted when only the recommended alarm is being created.
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
function buildBudgetAlarms(scope, id, target, options = {}) {
|
|
43
|
+
const recommended = options.recommendedAlarms;
|
|
44
|
+
const recommendedDefs = recommended === false ? [] : (0, budget_alarms_js_1.resolveBudgetAlarmDefinitions)(recommended);
|
|
45
|
+
const customAlarms = options.customAlarms ?? [];
|
|
46
|
+
if (customAlarms.length > 0 && !target) {
|
|
47
|
+
throw new Error(`BudgetAlarmBuilder "${id}" was given addAlarm() definitions but no budget. ` +
|
|
48
|
+
`Call .budget() with a BudgetBuilderResult or a Ref to one before adding custom alarms.`);
|
|
49
|
+
}
|
|
50
|
+
const customAlarmDefs = target ? customAlarms.map((b) => b.resolve(target.budget)) : [];
|
|
51
|
+
const allAlarmDefs = [...recommendedDefs, ...customAlarmDefs];
|
|
52
|
+
if (allAlarmDefs.length > 0) {
|
|
53
|
+
warnIfNotUsEast1(scope);
|
|
54
|
+
}
|
|
55
|
+
return (0, cloudwatch_1.createAlarms)(scope, id, allAlarmDefs);
|
|
56
|
+
}
|
|
57
|
+
class BudgetAlarmBuilder {
|
|
58
|
+
props = {};
|
|
59
|
+
#budget;
|
|
60
|
+
#customAlarms = [];
|
|
61
|
+
/**
|
|
62
|
+
* Sets the budget to alarm on. Pass the result of
|
|
63
|
+
* {@link createBudgetBuilder} (or a {@link Ref} to it). The builder
|
|
64
|
+
* reads the underlying `CfnBudget` from the result so custom alarms
|
|
65
|
+
* added via {@link addAlarm} can reference it.
|
|
66
|
+
*
|
|
67
|
+
* Optional when only the recommended `EstimatedCharges` alarm is being
|
|
68
|
+
* created — that alarm is account-level and does not reference any
|
|
69
|
+
* specific budget. Required as soon as you call {@link addAlarm}.
|
|
70
|
+
*
|
|
71
|
+
* Pair with `compose().withStacks()` to route this component into a
|
|
72
|
+
* `us-east-1` stack while the budget itself lives elsewhere — set
|
|
73
|
+
* `crossRegionReferences: true` on both stacks so CDK can wire any
|
|
74
|
+
* cross-stack references automatically.
|
|
75
|
+
*/
|
|
76
|
+
budget(budget) {
|
|
77
|
+
this.#budget = budget;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Adds a custom alarm against the budget. The configure callback
|
|
82
|
+
* receives a fresh {@link AlarmDefinitionBuilder} pre-set with the
|
|
83
|
+
* alarm's key; configure metric, threshold, comparison and any other
|
|
84
|
+
* options.
|
|
85
|
+
*
|
|
86
|
+
* The created alarm is materialised in this builder's stack — useful
|
|
87
|
+
* for cross-region setups where you want all billing-related alarms to
|
|
88
|
+
* live with the recommended one.
|
|
89
|
+
*/
|
|
90
|
+
addAlarm(key, configure) {
|
|
91
|
+
this.#customAlarms.push(configure(new cloudwatch_1.AlarmDefinitionBuilder(key)));
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
/** @internal — see ADR-0005. */
|
|
95
|
+
[core_1.COPY_STATE](target) {
|
|
96
|
+
target.#budget = this.#budget;
|
|
97
|
+
target.#customAlarms.push(...this.#customAlarms);
|
|
98
|
+
}
|
|
99
|
+
build(scope, id, context) {
|
|
100
|
+
const target = this.#budget ? (0, core_1.resolve)(this.#budget, context ?? {}) : undefined;
|
|
101
|
+
return {
|
|
102
|
+
alarms: buildBudgetAlarms(scope, id, target, {
|
|
103
|
+
recommendedAlarms: this.props.recommendedAlarms,
|
|
104
|
+
customAlarms: this.#customAlarms,
|
|
105
|
+
}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Creates a new {@link IBudgetAlarmBuilder} for materialising AWS Budget
|
|
111
|
+
* alarms in a stack separate from the budget itself.
|
|
112
|
+
*
|
|
113
|
+
* The recommended use is multi-region deployments: the budget lives in
|
|
114
|
+
* the application's stack (in any region — `AWS::Budgets::Budget` is a
|
|
115
|
+
* global resource), and the alarms must live in a `us-east-1` stack so
|
|
116
|
+
* they can read the `AWS/Billing EstimatedCharges` metric AWS emits
|
|
117
|
+
* there.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* compose(
|
|
122
|
+
* {
|
|
123
|
+
* account: createBudgetBuilder()
|
|
124
|
+
* .budgetName("Account")
|
|
125
|
+
* .limit({ amount: 1000 })
|
|
126
|
+
* .recommendedAlarms(false), // suppress alarms in the budget's own stack
|
|
127
|
+
*
|
|
128
|
+
* accountAlarms: createBudgetAlarmBuilder()
|
|
129
|
+
* .budget(ref<BudgetBuilderResult>("account"))
|
|
130
|
+
* .recommendedAlarms({
|
|
131
|
+
* estimatedCharges: { threshold: 1000, currency: "USD" },
|
|
132
|
+
* }),
|
|
133
|
+
* },
|
|
134
|
+
* { account: [], accountAlarms: ["account"] },
|
|
135
|
+
* )
|
|
136
|
+
* .withStacks({
|
|
137
|
+
* account: appStack, // any region — Budgets is a global service
|
|
138
|
+
* accountAlarms: monitoringStack, // us-east-1 — where AWS/Billing metrics live
|
|
139
|
+
* })
|
|
140
|
+
* .build(app, "App");
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* Set `crossRegionReferences: true` on both stacks if you reference the
|
|
144
|
+
* budget from custom alarms via `.addAlarm()`.
|
|
145
|
+
*/
|
|
146
|
+
function createBudgetAlarmBuilder() {
|
|
147
|
+
return (0, cloudformation_1.taggedBuilder)(BudgetAlarmBuilder);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=budget-alarm-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-alarm-builder.js","sourceRoot":"","sources":["../../src/budget-alarm-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-alarms.d.ts","sourceRoot":"","sources":["../../src/budget-alarms.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAK3D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACpC,eAAe,EAAE,CA0BnB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveBudgetAlarmDefinitions = resolveBudgetAlarmDefinitions;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
|
|
6
|
+
const currency_js_1 = require("./currency.js");
|
|
7
|
+
const BILLING_METRIC_PERIOD = aws_cdk_lib_1.Duration.hours(6);
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
10
|
+
* {@link AlarmDefinition}s for an AWS Budget.
|
|
11
|
+
*
|
|
12
|
+
* AWS Budgets does not publish per-budget CloudWatch metrics — the only
|
|
13
|
+
* recommended alarm is the account-level `AWS/Billing EstimatedCharges`
|
|
14
|
+
* billing alarm. Off by default: callers must pass an
|
|
15
|
+
* {@link BudgetAlarmConfig.estimatedCharges} config to opt in.
|
|
16
|
+
*
|
|
17
|
+
* Period and statistic are fixed at the AWS-recommended values
|
|
18
|
+
* (6 hours, Maximum) and not exposed as configuration knobs — billing
|
|
19
|
+
* metrics only update every ~6 hours, so a shorter period would
|
|
20
|
+
* oversample. Threshold, currency, evaluation periods, datapoints and
|
|
21
|
+
* missing-data behaviour remain user-configurable via
|
|
22
|
+
* {@link EstimatedChargesAlarmConfig}.
|
|
23
|
+
*
|
|
24
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
|
|
25
|
+
*/
|
|
26
|
+
function resolveBudgetAlarmDefinitions(config) {
|
|
27
|
+
if (config?.enabled === false)
|
|
28
|
+
return [];
|
|
29
|
+
if (!config?.estimatedCharges)
|
|
30
|
+
return [];
|
|
31
|
+
const cfg = config.estimatedCharges;
|
|
32
|
+
const currency = cfg.currency ?? "USD";
|
|
33
|
+
(0, currency_js_1.assertValidBudgetCurrency)(currency, `EstimatedChargesAlarmConfig: currency`);
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
key: "estimatedCharges",
|
|
37
|
+
metric: new aws_cloudwatch_1.Metric({
|
|
38
|
+
namespace: "AWS/Billing",
|
|
39
|
+
metricName: "EstimatedCharges",
|
|
40
|
+
dimensionsMap: { Currency: currency },
|
|
41
|
+
statistic: "Maximum",
|
|
42
|
+
period: BILLING_METRIC_PERIOD,
|
|
43
|
+
}),
|
|
44
|
+
threshold: cfg.threshold,
|
|
45
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
46
|
+
evaluationPeriods: cfg.evaluationPeriods ?? 1,
|
|
47
|
+
datapointsToAlarm: cfg.datapointsToAlarm ?? 1,
|
|
48
|
+
treatMissingData: cfg.treatMissingData ?? aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
|
|
49
|
+
description: `Account-level estimated charges exceeded ${String(cfg.threshold)} ${currency}. Billing metrics are only emitted in us-east-1.`,
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=budget-alarms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-alarms.js","sourceRoot":"","sources":["../../src/budget-alarms.ts"],"names":[],"mappings":";;AA0BA,sEA4BC;AAtDD,6CAAuC;AACvC,+DAA0F;AAG1F,+CAA0D;AAE1D,MAAM,qBAAqB,GAAG,sBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,6BAA6B,CAC3C,MAAqC;IAErC,IAAI,MAAM,EAAE,OAAO,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IACzC,IAAI,CAAC,MAAM,EAAE,gBAAgB;QAAE,OAAO,EAAE,CAAC;IAEzC,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACpC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC;IACvC,IAAA,uCAAyB,EAAC,QAAQ,EAAE,uCAAuC,CAAC,CAAC;IAE7E,OAAO;QACL;YACE,GAAG,EAAE,kBAAkB;YACvB,MAAM,EAAE,IAAI,uBAAM,CAAC;gBACjB,SAAS,EAAE,aAAa;gBACxB,UAAU,EAAE,kBAAkB;gBAC9B,aAAa,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;gBACrC,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,qBAAqB;aAC9B,CAAC;YACF,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,CAAC;YAC7C,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,CAAC;YAC7C,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,IAAI,iCAAgB,CAAC,aAAa;YACxE,WAAW,EAAE,4CAA4C,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,QAAQ,kDAAkD;SAC7I;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { CfnBudget } from "aws-cdk-lib/aws-budgets";
|
|
|
2
2
|
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
3
3
|
import type { TopicPolicy } from "aws-cdk-lib/aws-sns";
|
|
4
4
|
import type { IConstruct } from "constructs";
|
|
5
|
-
import { type IBuilder, type Lifecycle } from "@composurecdk/core";
|
|
5
|
+
import { COPY_STATE, type IBuilder, type Lifecycle } from "@composurecdk/core";
|
|
6
6
|
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
7
7
|
import type { BudgetAlarmConfig } from "./alarm-config.js";
|
|
8
8
|
import { type NotificationEntry, type NotifySubscribers } from "./notifications.js";
|
|
@@ -180,6 +180,8 @@ declare class BudgetBuilder implements Lifecycle<BudgetBuilderResult> {
|
|
|
180
180
|
* {@link createBudgetAlarmBuilder} into a `us-east-1` stack.
|
|
181
181
|
*/
|
|
182
182
|
addAlarm(key: string, configure: (alarm: AlarmDefinitionBuilder<CfnBudget>) => AlarmDefinitionBuilder<CfnBudget>): this;
|
|
183
|
+
/** @internal — see ADR-0005. */
|
|
184
|
+
[COPY_STATE](target: BudgetBuilder): void;
|
|
183
185
|
build(scope: IConstruct, id: string, context?: Record<string, object>): BudgetBuilderResult;
|
|
184
186
|
}
|
|
185
187
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-builder.d.ts","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBudgetBuilder = createBudgetBuilder;
|
|
4
|
+
const aws_budgets_1 = require("aws-cdk-lib/aws-budgets");
|
|
5
|
+
const core_1 = require("@composurecdk/core");
|
|
6
|
+
const cloudwatch_1 = require("@composurecdk/cloudwatch");
|
|
7
|
+
const budget_alarm_builder_js_1 = require("./budget-alarm-builder.js");
|
|
8
|
+
const currency_js_1 = require("./currency.js");
|
|
9
|
+
const defaults_js_1 = require("./defaults.js");
|
|
10
|
+
const notifications_js_1 = require("./notifications.js");
|
|
11
|
+
const topic_policy_js_1 = require("./topic-policy.js");
|
|
12
|
+
const MAX_EMAILS_PER_NOTIFICATION = 10;
|
|
13
|
+
class BudgetBuilder {
|
|
14
|
+
props = {};
|
|
15
|
+
#notifications = [];
|
|
16
|
+
#customAlarms = [];
|
|
17
|
+
/**
|
|
18
|
+
* Add a notification that fires when ACTUAL spend crosses the given
|
|
19
|
+
* percentage of the budget limit.
|
|
20
|
+
*
|
|
21
|
+
* @param thresholdPercent - Percentage of the budget limit (e.g. `80`).
|
|
22
|
+
* For absolute-value thresholds, use {@link addNotification} directly.
|
|
23
|
+
* @param subscribers - Up to one SNS topic plus up to ten validated
|
|
24
|
+
* email addresses. AWS Budgets caps each notification at 1 SNS + up
|
|
25
|
+
* to 10 EMAIL subscribers.
|
|
26
|
+
*/
|
|
27
|
+
notifyOnActual(thresholdPercent, subscribers) {
|
|
28
|
+
return this.#addPercentageNotification("ACTUAL", thresholdPercent, subscribers);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Add a notification that fires when FORECASTED spend crosses the
|
|
32
|
+
* given percentage of the budget limit.
|
|
33
|
+
*
|
|
34
|
+
* @param thresholdPercent - Percentage of the budget limit (e.g. `100`).
|
|
35
|
+
* For absolute-value thresholds, use {@link addNotification} directly.
|
|
36
|
+
* @param subscribers - Up to one SNS topic plus up to ten validated
|
|
37
|
+
* email addresses.
|
|
38
|
+
*/
|
|
39
|
+
notifyOnForecasted(thresholdPercent, subscribers) {
|
|
40
|
+
return this.#addPercentageNotification("FORECASTED", thresholdPercent, subscribers);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Raw notification passthrough for callers that need the full
|
|
44
|
+
* CloudFormation surface (e.g. absolute-value thresholds).
|
|
45
|
+
*/
|
|
46
|
+
addNotification(entry) {
|
|
47
|
+
this.#notifications.push(entry);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Apply the well-architected recommended notification thresholds:
|
|
52
|
+
*
|
|
53
|
+
* - `ACTUAL` at 80% — early warning before breach.
|
|
54
|
+
* - `FORECASTED` at 100% — trending-over-budget alert.
|
|
55
|
+
*
|
|
56
|
+
* Must be called with at least one subscriber; the same subscriber
|
|
57
|
+
* set is used for both thresholds.
|
|
58
|
+
*
|
|
59
|
+
* @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-best-practices.html
|
|
60
|
+
*/
|
|
61
|
+
withRecommendedThresholds(subscribers) {
|
|
62
|
+
if (!hasAnySubscriber(subscribers)) {
|
|
63
|
+
throw new Error(`BudgetBuilder: withRecommendedThresholds(...) must be called with at least one subscriber.`);
|
|
64
|
+
}
|
|
65
|
+
const { actualPercent, forecastedPercent } = defaults_js_1.BUDGET_DEFAULTS.recommendedThresholds;
|
|
66
|
+
this.#notifications.push({ notificationType: "ACTUAL", threshold: actualPercent, subscribers }, { notificationType: "FORECASTED", threshold: forecastedPercent, subscribers });
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Adds a custom CloudWatch alarm against the budget. The configure
|
|
71
|
+
* callback receives a fresh {@link AlarmDefinitionBuilder} pre-set with
|
|
72
|
+
* the alarm's key; configure metric, threshold, comparison and any
|
|
73
|
+
* other options.
|
|
74
|
+
*
|
|
75
|
+
* Custom alarms are materialised in this builder's stack alongside any
|
|
76
|
+
* recommended alarms. Like the recommended `EstimatedCharges` alarm,
|
|
77
|
+
* custom alarms on `AWS/Billing` metrics will only fire when this
|
|
78
|
+
* stack is in `us-east-1` — the builder emits the same synth-time
|
|
79
|
+
* warning (`@composurecdk/budgets:alarm-region`) when used elsewhere.
|
|
80
|
+
* For non-`us-east-1` stacks, route alarms via
|
|
81
|
+
* {@link createBudgetAlarmBuilder} into a `us-east-1` stack.
|
|
82
|
+
*/
|
|
83
|
+
addAlarm(key, configure) {
|
|
84
|
+
this.#customAlarms.push(configure(new cloudwatch_1.AlarmDefinitionBuilder(key)));
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/** @internal — see ADR-0005. */
|
|
88
|
+
[core_1.COPY_STATE](target) {
|
|
89
|
+
target.#notifications.push(...this.#notifications);
|
|
90
|
+
target.#customAlarms.push(...this.#customAlarms);
|
|
91
|
+
}
|
|
92
|
+
build(scope, id, context = {}) {
|
|
93
|
+
const { recommendedAlarms: alarmConfig, ...budgetProps } = this.props;
|
|
94
|
+
const budgetType = budgetProps.budgetType ?? defaults_js_1.BUDGET_DEFAULTS.budgetType;
|
|
95
|
+
const timeUnit = budgetProps.timeUnit ?? defaults_js_1.BUDGET_DEFAULTS.timeUnit;
|
|
96
|
+
const requiresLimit = budgetType === "COST" || budgetType === "USAGE";
|
|
97
|
+
if (requiresLimit && !budgetProps.limit) {
|
|
98
|
+
throw new Error(`BudgetBuilder "${id}": limit({ amount, unit }) must be set for ${budgetType} budgets.`);
|
|
99
|
+
}
|
|
100
|
+
const limitUnit = budgetProps.limit?.unit ?? defaults_js_1.BUDGET_DEFAULTS.limitUnit;
|
|
101
|
+
if (budgetType === "COST" && budgetProps.limit) {
|
|
102
|
+
(0, currency_js_1.assertValidBudgetCurrency)(limitUnit, `BudgetBuilder "${id}": limit unit`);
|
|
103
|
+
(0, currency_js_1.warnIfNonUsdCurrency)(scope, limitUnit, `BudgetBuilder "${id}": limit unit`);
|
|
104
|
+
}
|
|
105
|
+
const { notificationsWithSubscribers, snsTopics } = this.#buildNotifications(id, context);
|
|
106
|
+
const budgetData = {
|
|
107
|
+
budgetName: budgetProps.budgetName,
|
|
108
|
+
budgetType,
|
|
109
|
+
timeUnit,
|
|
110
|
+
...(budgetProps.limit
|
|
111
|
+
? {
|
|
112
|
+
budgetLimit: {
|
|
113
|
+
amount: budgetProps.limit.amount,
|
|
114
|
+
unit: limitUnit,
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
: {}),
|
|
118
|
+
...(budgetProps.costFilters ? { costFilters: budgetProps.costFilters } : {}),
|
|
119
|
+
...(budgetProps.costTypes ? { costTypes: budgetProps.costTypes } : {}),
|
|
120
|
+
};
|
|
121
|
+
const cfnProps = {
|
|
122
|
+
budget: budgetData,
|
|
123
|
+
...(notificationsWithSubscribers.length > 0 ? { notificationsWithSubscribers } : {}),
|
|
124
|
+
};
|
|
125
|
+
const budget = new aws_budgets_1.CfnBudget(scope, id, cfnProps);
|
|
126
|
+
const topicPolicies = (0, topic_policy_js_1.createBudgetsTopicPolicies)(scope, id, snsTopics);
|
|
127
|
+
const alarms = (0, budget_alarm_builder_js_1.buildBudgetAlarms)(scope, id, { budget }, {
|
|
128
|
+
recommendedAlarms: alarmConfig,
|
|
129
|
+
customAlarms: this.#customAlarms,
|
|
130
|
+
});
|
|
131
|
+
return { budget, topicPolicies, alarms };
|
|
132
|
+
}
|
|
133
|
+
#addPercentageNotification(notificationType, thresholdPercent, subscribers) {
|
|
134
|
+
if (!hasAnySubscriber(subscribers)) {
|
|
135
|
+
throw new Error(`BudgetBuilder: ${notificationType} notification at ${String(thresholdPercent)}% requires at least one subscriber.`);
|
|
136
|
+
}
|
|
137
|
+
this.#notifications.push({ notificationType, threshold: thresholdPercent, subscribers });
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
#buildNotifications(id, context) {
|
|
141
|
+
const notificationsWithSubscribers = [];
|
|
142
|
+
const allSnsTopics = [];
|
|
143
|
+
for (const entry of this.#notifications) {
|
|
144
|
+
const emailCount = entry.subscribers.emails?.length ?? 0;
|
|
145
|
+
if (emailCount > MAX_EMAILS_PER_NOTIFICATION) {
|
|
146
|
+
throw new Error(`BudgetBuilder "${id}": ${describeNotification(entry)} has ${String(emailCount)} email subscribers; ` +
|
|
147
|
+
`AWS Budgets allows at most ${String(MAX_EMAILS_PER_NOTIFICATION)} email subscribers per notification (plus up to 1 SNS topic).`);
|
|
148
|
+
}
|
|
149
|
+
const resolved = (0, notifications_js_1.resolveSubscribers)(entry.subscribers, context);
|
|
150
|
+
notificationsWithSubscribers.push((0, notifications_js_1.toCfnNotificationWithSubscribers)(entry, resolved.cfn));
|
|
151
|
+
allSnsTopics.push(...resolved.snsTopics);
|
|
152
|
+
}
|
|
153
|
+
return { notificationsWithSubscribers, snsTopics: allSnsTopics };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function hasAnySubscriber(subscribers) {
|
|
157
|
+
return subscribers.sns !== undefined || (subscribers.emails?.length ?? 0) > 0;
|
|
158
|
+
}
|
|
159
|
+
function describeNotification(entry) {
|
|
160
|
+
const unit = (entry.thresholdType ?? "PERCENTAGE") === "PERCENTAGE" ? "%" : "";
|
|
161
|
+
return `notification ${entry.notificationType} @ ${String(entry.threshold)}${unit}`;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Creates a new {@link IBudgetBuilder} for configuring an AWS Budget.
|
|
165
|
+
*/
|
|
166
|
+
function createBudgetBuilder() {
|
|
167
|
+
// eslint-disable-next-line composurecdk/builder-must-be-tagged -- AWS::Budgets::Budget has no Tags property
|
|
168
|
+
return (0, core_1.Builder)(BudgetBuilder);
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=budget-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget-builder.js","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["../../src/currency.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAM7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAS3F"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertValidBudgetCurrency = assertValidBudgetCurrency;
|
|
4
|
+
exports.warnIfNonUsdCurrency = warnIfNonUsdCurrency;
|
|
5
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
6
|
+
const defaults_js_1 = require("./defaults.js");
|
|
7
|
+
/**
|
|
8
|
+
* Throws if `unit` is not in {@link DEFAULT_BUDGET_CURRENCIES}.
|
|
9
|
+
*
|
|
10
|
+
* `context` is woven into the message (e.g. `BudgetBuilder "X": limit
|
|
11
|
+
* unit ...`) so callers can blame the right field. Catches typos like
|
|
12
|
+
* `"USDD"` or `"ZZZ"` at synth instead of mid-deploy.
|
|
13
|
+
*/
|
|
14
|
+
function assertValidBudgetCurrency(unit, context) {
|
|
15
|
+
if (defaults_js_1.DEFAULT_BUDGET_CURRENCIES.includes(unit))
|
|
16
|
+
return;
|
|
17
|
+
throw new Error(`${context}: "${unit}" is not a recognised AWS Budgets currency code. ` +
|
|
18
|
+
`Expected one of: ${defaults_js_1.DEFAULT_BUDGET_CURRENCIES.join(", ")}.`);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Annotates `scope` with a non-fatal warning when `unit` is anything
|
|
22
|
+
* other than `USD`. The synth context cannot see an account's billing
|
|
23
|
+
* currency, and AWS Budgets rejects `BudgetLimit.Unit` values that
|
|
24
|
+
* don't match it — so a non-USD configuration deserves a "make sure
|
|
25
|
+
* this matches your billing currency" nudge.
|
|
26
|
+
*
|
|
27
|
+
* Short-circuits on unresolved tokens so env-agnostic stacks aren't
|
|
28
|
+
* spammed.
|
|
29
|
+
*/
|
|
30
|
+
function warnIfNonUsdCurrency(scope, unit, context) {
|
|
31
|
+
if (aws_cdk_lib_1.Token.isUnresolved(unit))
|
|
32
|
+
return;
|
|
33
|
+
if (unit === "USD")
|
|
34
|
+
return;
|
|
35
|
+
aws_cdk_lib_1.Annotations.of(scope).addWarningV2("@composurecdk/budgets:limit-currency", `${context}: currency "${unit}" must match the account's billing currency or AWS Budgets ` +
|
|
36
|
+
`will reject the request at deploy time. Most accounts default to USD; verify yours and ` +
|
|
37
|
+
`suppress this warning if intentional.`);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=currency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency.js","sourceRoot":"","sources":["../../src/currency.ts"],"names":[],"mappings":";;AAWA,8DAMC;AAYD,oDASC;AAtCD,6CAAiD;AAEjD,+CAA0D;AAE1D;;;;;;GAMG;AACH,SAAgB,yBAAyB,CAAC,IAAY,EAAE,OAAe;IACrE,IAAI,uCAAyB,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IACrD,MAAM,IAAI,KAAK,CACb,GAAG,OAAO,MAAM,IAAI,mDAAmD;QACrE,oBAAoB,uCAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,oBAAoB,CAAC,KAAiB,EAAE,IAAY,EAAE,OAAe;IACnF,IAAI,mBAAK,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO;IACrC,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO;IAC3B,yBAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAChC,sCAAsC,EACtC,GAAG,OAAO,eAAe,IAAI,6DAA6D;QACxF,yFAAyF;QACzF,uCAAuC,CAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,eAAe;IAC1B;;;;OAIG;;IAGH;;;;;OAKG;;IAGH;;;;;OAKG;;IAGH;;;;;;;;;OASG;;;;;CAKJ,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAkCtD,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_BUDGET_CURRENCIES = exports.BUDGET_DEFAULTS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Well-architected defaults for {@link createBudgetBuilder}. Each can be
|
|
6
|
+
* overridden via the builder's fluent API.
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.aws.amazon.com/wellarchitected/latest/cost-optimization-pillar/welcome.html
|
|
9
|
+
*/
|
|
10
|
+
exports.BUDGET_DEFAULTS = {
|
|
11
|
+
/**
|
|
12
|
+
* Default budget type — most budgets are cost budgets.
|
|
13
|
+
*
|
|
14
|
+
* @see https://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_budgets_Budget.html
|
|
15
|
+
*/
|
|
16
|
+
budgetType: "COST",
|
|
17
|
+
/**
|
|
18
|
+
* Default tracking period — monthly is the most common granularity and
|
|
19
|
+
* aligns with AWS billing cycles.
|
|
20
|
+
*
|
|
21
|
+
* @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-create.html
|
|
22
|
+
*/
|
|
23
|
+
timeUnit: "MONTHLY",
|
|
24
|
+
/**
|
|
25
|
+
* Default spend currency — most customers need to set this; the builder
|
|
26
|
+
* defaults to USD to align with the AWS Billing reporting default.
|
|
27
|
+
*
|
|
28
|
+
* @see https://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_budgets_Spend.html
|
|
29
|
+
*/
|
|
30
|
+
limitUnit: "USD",
|
|
31
|
+
/**
|
|
32
|
+
* Recommended percentage thresholds applied by
|
|
33
|
+
* {@link IBudgetBuilder.withRecommendedThresholds}.
|
|
34
|
+
*
|
|
35
|
+
* - `ACTUAL` at 80% — early warning before you breach the budget.
|
|
36
|
+
* - `FORECASTED` at 100% — notifies when forecasted spend trends over
|
|
37
|
+
* budget for the period.
|
|
38
|
+
*
|
|
39
|
+
* @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-best-practices.html
|
|
40
|
+
*/
|
|
41
|
+
recommendedThresholds: {
|
|
42
|
+
actualPercent: 80,
|
|
43
|
+
forecastedPercent: 100,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* ISO 4217 currency codes accepted by AWS Budgets for `COST` budgets'
|
|
48
|
+
* `BudgetLimit.Unit` and the `EstimatedCharges` alarm's `Currency`
|
|
49
|
+
* dimension. Sourced from the AWS Billing supported-currencies list.
|
|
50
|
+
*
|
|
51
|
+
* The synth context cannot see an account's billing currency, so the
|
|
52
|
+
* builder uses this set for shape validation only — a hard error on
|
|
53
|
+
* anything outside it (catches typos like `"ZZZ"`/`"USDD"`) — and emits
|
|
54
|
+
* a soft warning when the configured unit is anything other than `USD`,
|
|
55
|
+
* since most accounts default to USD billing.
|
|
56
|
+
*
|
|
57
|
+
* @see https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html
|
|
58
|
+
*/
|
|
59
|
+
exports.DEFAULT_BUDGET_CURRENCIES = [
|
|
60
|
+
"AED",
|
|
61
|
+
"ARS",
|
|
62
|
+
"AUD",
|
|
63
|
+
"BRL",
|
|
64
|
+
"CAD",
|
|
65
|
+
"CHF",
|
|
66
|
+
"CLP",
|
|
67
|
+
"CNY",
|
|
68
|
+
"COP",
|
|
69
|
+
"CZK",
|
|
70
|
+
"DKK",
|
|
71
|
+
"EUR",
|
|
72
|
+
"GBP",
|
|
73
|
+
"HKD",
|
|
74
|
+
"IDR",
|
|
75
|
+
"ILS",
|
|
76
|
+
"INR",
|
|
77
|
+
"JPY",
|
|
78
|
+
"KRW",
|
|
79
|
+
"MXN",
|
|
80
|
+
"MYR",
|
|
81
|
+
"NOK",
|
|
82
|
+
"NZD",
|
|
83
|
+
"PLN",
|
|
84
|
+
"RUB",
|
|
85
|
+
"SAR",
|
|
86
|
+
"SEK",
|
|
87
|
+
"SGD",
|
|
88
|
+
"THB",
|
|
89
|
+
"TRY",
|
|
90
|
+
"TWD",
|
|
91
|
+
"USD",
|
|
92
|
+
"ZAR",
|
|
93
|
+
];
|
|
94
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACU,QAAA,eAAe,GAAG;IAC7B;;;;OAIG;IACH,UAAU,EAAE,MAAe;IAE3B;;;;;OAKG;IACH,QAAQ,EAAE,SAAkB;IAE5B;;;;;OAKG;IACH,SAAS,EAAE,KAAK;IAEhB;;;;;;;;;OASG;IACH,qBAAqB,EAAE;QACrB,aAAa,EAAE,EAAE;QACjB,iBAAiB,EAAE,GAAG;KACvB;CACF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACU,QAAA,yBAAyB,GAAsB;IAC1D,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/email.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,UAAU,EAAE,OAAO,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAK7D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAc1C"}
|