@composurecdk/budgets 0.10.2 → 0.10.3

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  AWS Budgets builder for [ComposureCDK](../../README.md).
4
4
 
5
- This package provides a fluent builder for `AWS::Budgets::Budget` with well-architected defaults, percentage-threshold notification helpers, and automatic `AWS::SNS::TopicPolicy` wiring for SNS subscribers. It wraps the CDK L1 [CfnBudget](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_budgets.CfnBudget.html) construct — there is no L2 for Budgets.
5
+ This package provides a fluent builder for `AWS::Budgets::Budget` with well-architected defaults, percentage-threshold notification helpers, and automatic `budgets.amazonaws.com` publish permission on SNS subscriber topics. It wraps the CDK L1 [CfnBudget](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_budgets.CfnBudget.html) construct — there is no L2 for Budgets.
6
6
 
7
7
  ## Budget Builder
8
8
 
@@ -77,14 +77,22 @@ Applies the AWS Cost Optimization pillar defaults: `ACTUAL` at 80% and `FORECAST
77
77
  | `limitUnit` | `"USD"` | Matches the AWS Billing console default. |
78
78
  | `recommendedThresholds.actualPercent` | `80` | Early-warning threshold before breach. |
79
79
  | `recommendedThresholds.forecastedPercent` | `100` | Trending-over-budget alert for the period. |
80
+ | `topicPolicy` | `true` | Budgets cannot deliver to an SNS topic whose policy does not allow it. |
80
81
 
81
82
  Exported as `BUDGET_DEFAULTS`.
82
83
 
83
84
  ## Automatic SNS Topic Policies
84
85
 
85
- When at least one notification subscriber is an SNS topic, the builder creates a matching `AWS::SNS::TopicPolicy` granting `SNS:Publish` to the `budgets.amazonaws.com` service principal. Without that policy, budget notifications to SNS silently fail to deliver — one of the most common footguns when wiring Budgets by hand.
86
+ When at least one notification subscriber is an SNS topic, the builder grants `SNS:Publish` to the `budgets.amazonaws.com` service principal. Without that grant, budget notifications to SNS silently fail to deliver — one of the most common footguns when wiring Budgets by hand.
86
87
 
87
- The created `TopicPolicy` constructs are returned on `result.topicPolicies`, keyed by the topic's fully-qualified node path (unique within the CDK app).
88
+ The statement is added to the topic's own access policy with `topic.addToResourcePolicy(...)`, next to any statement already there, such as the `enforceSSL` statement [`@composurecdk/sns`](../sns/README.md) adds by default. An SNS topic has exactly one access policy and every `AWS::SNS::TopicPolicy` replaces it, so a second policy resource would race the first. [`topicPolicyConflictPolicy`](../sns/README.md#topic-policy-conflict-policy) catches that at synth.
89
+
90
+ `result.topicPolicies` holds the `TopicPolicy` constructs the builder creates, keyed by the topic's fully-qualified node path (unique within the CDK app):
91
+
92
+ - **A topic created in CDK:** a transitional policy that shares the topic's own `PolicyDocument`, so both resources always render the same document. It sits at the logical id earlier versions used for a separate Budgets-only policy, and is retained on removal. Deleting that old resource would make CloudFormation reset the topic's policy after the update had written the merged one. This keeps the upgrade safe and will be removed in a later release; with its `Retain` policy in place by then, removing it resets nothing.
93
+ - **An imported topic** (`Topic.fromTopicArn`): CDK cannot add to its policy, so the builder creates a standalone `TopicPolicy` as before. It replaces whatever policy the topic already has, and the builder emits a synth warning (`@composurecdk/budgets:imported-topic-policy`) saying so.
94
+
95
+ To manage the topics' access policies yourself, turn this off with `.topicPolicy(false)`. The builder then adds no statement and creates no policy; Budgets cannot deliver to a topic whose policy does not allow `budgets.amazonaws.com` to publish.
88
96
 
89
97
  ## Recommended Alarms
90
98
 
@@ -68,6 +68,15 @@ export interface BudgetBuilderProps {
68
68
  * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
69
69
  */
70
70
  recommendedAlarms?: BudgetAlarmConfig | false;
71
+ /**
72
+ * Whether to grant `budgets.amazonaws.com` `SNS:Publish` on the SNS
73
+ * topics this budget notifies. Set to `false` when you manage those
74
+ * topics' access policies yourself; Budgets cannot deliver to a topic
75
+ * whose policy does not allow it.
76
+ *
77
+ * @default true
78
+ */
79
+ topicPolicy?: boolean;
71
80
  }
72
81
  /**
73
82
  * The build output of an {@link IBudgetBuilder}.
@@ -76,12 +85,14 @@ export interface BudgetBuilderResult {
76
85
  /** The `AWS::Budgets::Budget` construct. */
77
86
  budget: CfnBudget;
78
87
  /**
79
- * `AWS::SNS::TopicPolicy` constructs created automatically for any SNS
80
- * topic referenced as a notification subscriber, keyed by the topic's
81
- * fully-qualified node path. Grants `budgets.amazonaws.com` permission
82
- * to publish.
88
+ * `AWS::SNS::TopicPolicy` constructs the builder created for SNS topics
89
+ * referenced as notification subscribers, keyed by the topic's
90
+ * fully-qualified node path. The `budgets.amazonaws.com` publish
91
+ * statement itself is added to each topic's own policy; see
92
+ * {@link createBudgetsTopicPolicies} for what is created and why.
83
93
  *
84
- * `{}` when no SNS subscribers were configured.
94
+ * `{}` when no SNS subscribers were configured, or `topicPolicy` is
95
+ * `false`.
85
96
  */
86
97
  topicPolicies: Record<string, TopicPolicy>;
87
98
  /**
@@ -103,7 +114,7 @@ export interface BudgetBuilderResult {
103
114
  * Wraps the {@link CfnBudget} L1 construct (the CDK does not ship an L2
104
115
  * for Budgets) with well-architected defaults, helpers for the
105
116
  * percentage-threshold notification shape, and automatic
106
- * `AWS::SNS::TopicPolicy` wiring for SNS subscribers.
117
+ * `budgets.amazonaws.com` publish permission on SNS subscriber topics.
107
118
  *
108
119
  * The builder can also create the AWS-recommended `EstimatedCharges`
109
120
  * billing alarm; opt in via `recommendedAlarms`. For non-`us-east-1`
@@ -1 +1 @@
1
- {"version":3,"file":"budget-builder.d.ts","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAU,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAW,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,iBAAiB,EAGvB,MAAM,oBAAoB,CAAC;AAK5B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,MAAM,EAAE,SAAS,CAAC;IAClB;;;;;;;OAOG;IACH,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C;;;;;;;;;;OAUG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AAEzE,cAAM,aAAc,YAAW,SAAS,CAAC,mBAAmB,CAAC;;IAC3D,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAM;IAIxC;;;;;;;;;OASG;IACH,cAAc,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAI9E;;;;;;;;OAQG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAIlF;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAK/C;;;;;;;;;;OAUG;IACH,yBAAyB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAc/D;;;;;;;;;;;;;OAaG;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,aAAa,GAAG,IAAI;IAKzC,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,mBAAmB;CAkGhG;AAWD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAGpD"}
1
+ {"version":3,"file":"budget-builder.d.ts","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAU,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAW,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,iBAAiB,EAGvB,MAAM,oBAAoB,CAAC;AAK5B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;IAC9C;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,MAAM,EAAE,SAAS,CAAC;IAClB;;;;;;;;;OASG;IACH,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C;;;;;;;;;;OAUG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AAEzE,cAAM,aAAc,YAAW,SAAS,CAAC,mBAAmB,CAAC;;IAC3D,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAM;IAIxC;;;;;;;;;OASG;IACH,cAAc,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAI9E;;;;;;;;OAQG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAIlF;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAK/C;;;;;;;;;;OAUG;IACH,yBAAyB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAc/D;;;;;;;;;;;;;OAaG;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,aAAa,GAAG,IAAI;IAKzC,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,mBAAmB;CAsGhG;AAWD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAGpD"}
@@ -90,7 +90,7 @@ class BudgetBuilder {
90
90
  target.#customAlarms.push(...this.#customAlarms);
91
91
  }
92
92
  build(scope, id, context = {}) {
93
- const { recommendedAlarms: alarmConfig, ...budgetProps } = this.props;
93
+ const { recommendedAlarms: alarmConfig, topicPolicy = defaults_js_1.BUDGET_DEFAULTS.topicPolicy, ...budgetProps } = this.props;
94
94
  const budgetType = budgetProps.budgetType ?? defaults_js_1.BUDGET_DEFAULTS.budgetType;
95
95
  const timeUnit = budgetProps.timeUnit ?? defaults_js_1.BUDGET_DEFAULTS.timeUnit;
96
96
  const requiresLimit = budgetType === "COST" || budgetType === "USAGE";
@@ -123,7 +123,7 @@ class BudgetBuilder {
123
123
  ...(notificationsWithSubscribers.length > 0 ? { notificationsWithSubscribers } : {}),
124
124
  };
125
125
  const budget = new aws_budgets_1.CfnBudget(scope, id, cfnProps);
126
- const topicPolicies = (0, topic_policy_js_1.createBudgetsTopicPolicies)(scope, id, snsTopics);
126
+ const topicPolicies = topicPolicy ? (0, topic_policy_js_1.createBudgetsTopicPolicies)(scope, id, snsTopics) : {};
127
127
  const alarms = (0, budget_alarm_builder_js_1.buildBudgetAlarms)(scope, id, { budget }, {
128
128
  recommendedAlarms: alarmConfig,
129
129
  customAlarms: this.#customAlarms,
@@ -1 +1 @@
1
- {"version":3,"file":"budget-builder.js","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"budget-builder.js","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,13 @@ export declare const BUDGET_DEFAULTS: {
39
39
  actualPercent: number;
40
40
  forecastedPercent: number;
41
41
  };
42
+ /**
43
+ * Grant `budgets.amazonaws.com` `SNS:Publish` on SNS subscriber topics.
44
+ * Budgets cannot deliver to a topic whose access policy does not allow it.
45
+ *
46
+ * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
47
+ */
48
+ topicPolicy: boolean;
42
49
  };
43
50
  /**
44
51
  * ISO 4217 currency codes accepted by AWS Budgets for `COST` budgets'
@@ -1 +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"}
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;;;;;IAMH;;;;;OAKG;;CAEJ,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAkCtD,CAAC"}
@@ -42,6 +42,13 @@ exports.BUDGET_DEFAULTS = {
42
42
  actualPercent: 80,
43
43
  forecastedPercent: 100,
44
44
  },
45
+ /**
46
+ * Grant `budgets.amazonaws.com` `SNS:Publish` on SNS subscriber topics.
47
+ * Budgets cannot deliver to a topic whose access policy does not allow it.
48
+ *
49
+ * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
50
+ */
51
+ topicPolicy: true,
45
52
  };
46
53
  /**
47
54
  * ISO 4217 currency codes accepted by AWS Budgets for `COST` budgets'
@@ -1 +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"}
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;IAED;;;;;OAKG;IACH,WAAW,EAAE,IAAI;CAClB,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"}
@@ -1,18 +1,15 @@
1
1
  import { type ITopic, TopicPolicy } from "aws-cdk-lib/aws-sns";
2
2
  import type { IConstruct } from "constructs";
3
3
  /**
4
- * Create an `AWS::SNS::TopicPolicy` granting the AWS Budgets service
5
- * principal (`budgets.amazonaws.com`) permission to publish to each of
6
- * the supplied topics.
4
+ * Grant the AWS Budgets service principal (`budgets.amazonaws.com`)
5
+ * permission to publish to each of the supplied topics, by adding the
6
+ * statement to each topic's own access policy.
7
7
  *
8
- * Without this policy, a budget notification configured with an SNS
9
- * subscriber will silently fail to deliver — one of the most common
10
- * footguns when wiring Budgets to SNS by hand. The builder wires it up
11
- * automatically whenever at least one `SNS` subscriber is configured.
12
- *
13
- * Each topic gets its own `TopicPolicy` construct, keyed by the topic's
14
- * fully-qualified CDK node path, so callers can inspect or extend them
15
- * via the build result.
8
+ * Returns the `TopicPolicy` constructs this creates, keyed by the topic's
9
+ * fully-qualified CDK node path: a retained transitional policy sharing the
10
+ * topic's own document, or — for an imported topic, whose policy CDK cannot
11
+ * add to — a standalone policy. The package README's "Automatic SNS Topic
12
+ * Policies" section explains both.
16
13
  *
17
14
  * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
18
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"topic-policy.d.ts","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA2B7B"}
1
+ {"version":3,"file":"topic-policy.d.ts","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAY7C;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA8C7B"}
@@ -1,44 +1,66 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBudgetsTopicPolicies = createBudgetsTopicPolicies;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
4
5
  const aws_iam_1 = require("aws-cdk-lib/aws-iam");
5
6
  const aws_sns_1 = require("aws-cdk-lib/aws-sns");
7
+ /** Whether `x` is a `TopicPolicy` L2, by its L1's resource type (ADR-0011). */
8
+ function isTopicPolicy(x) {
9
+ const cfn = x?.node.defaultChild;
10
+ return (cfn !== undefined &&
11
+ aws_cdk_lib_1.CfnResource.isCfnResource(cfn) &&
12
+ cfn.cfnResourceType === aws_sns_1.CfnTopicPolicy.CFN_RESOURCE_TYPE_NAME);
13
+ }
6
14
  /**
7
- * Create an `AWS::SNS::TopicPolicy` granting the AWS Budgets service
8
- * principal (`budgets.amazonaws.com`) permission to publish to each of
9
- * the supplied topics.
10
- *
11
- * Without this policy, a budget notification configured with an SNS
12
- * subscriber will silently fail to deliver — one of the most common
13
- * footguns when wiring Budgets to SNS by hand. The builder wires it up
14
- * automatically whenever at least one `SNS` subscriber is configured.
15
+ * Grant the AWS Budgets service principal (`budgets.amazonaws.com`)
16
+ * permission to publish to each of the supplied topics, by adding the
17
+ * statement to each topic's own access policy.
15
18
  *
16
- * Each topic gets its own `TopicPolicy` construct, keyed by the topic's
17
- * fully-qualified CDK node path, so callers can inspect or extend them
18
- * via the build result.
19
+ * Returns the `TopicPolicy` constructs this creates, keyed by the topic's
20
+ * fully-qualified CDK node path: a retained transitional policy sharing the
21
+ * topic's own document, or — for an imported topic, whose policy CDK cannot
22
+ * add to — a standalone policy. The package README's "Automatic SNS Topic
23
+ * Policies" section explains both.
19
24
  *
20
25
  * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
21
26
  */
22
27
  function createBudgetsTopicPolicies(scope, id, topics) {
23
28
  const policies = {};
24
- const seen = new Set();
25
29
  for (const topic of topics) {
26
30
  const key = topic.node.path;
27
- if (seen.has(key))
31
+ if (key in policies)
28
32
  continue;
29
- seen.add(key);
30
- const policy = new aws_sns_1.TopicPolicy(scope, `${id}TopicPolicy${topic.node.addr}`, {
31
- topics: [topic],
32
- policyDocument: undefined,
33
- });
34
- policy.document.addStatements(new aws_iam_1.PolicyStatement({
33
+ const statement = new aws_iam_1.PolicyStatement({
35
34
  sid: "AllowBudgetsPublish",
36
35
  effect: aws_iam_1.Effect.ALLOW,
37
36
  principals: [new aws_iam_1.ServicePrincipal("budgets.amazonaws.com")],
38
37
  actions: ["SNS:Publish"],
39
38
  resources: [topic.topicArn],
40
- }));
41
- policies[key] = policy;
39
+ });
40
+ // The logical id earlier versions gave their separate Budgets-only policy.
41
+ const policyId = `${id}TopicPolicy${topic.node.addr}`;
42
+ const { statementAdded, policyDependable } = topic.addToResourcePolicy(statement);
43
+ if (!statementAdded) {
44
+ const policy = new aws_sns_1.TopicPolicy(scope, policyId, { topics: [topic] });
45
+ policy.document.addStatements(statement);
46
+ aws_cdk_lib_1.Annotations.of(policy).addWarningV2("@composurecdk/budgets:imported-topic-policy", `SNS topic ${key} was not created in this app, so its access policy cannot be added to. ` +
47
+ `This TopicPolicy grants budgets.amazonaws.com SNS:Publish and replaces the topic's ` +
48
+ `existing policy. Set topicPolicy(false) to manage the topic's policy yourself.`);
49
+ policies[key] = policy;
50
+ }
51
+ else if (isTopicPolicy(policyDependable)) {
52
+ const policy = new aws_sns_1.TopicPolicy(scope, policyId, {
53
+ topics: [topic],
54
+ policyDocument: policyDependable.document,
55
+ });
56
+ policy.applyRemovalPolicy(aws_cdk_lib_1.RemovalPolicy.RETAIN);
57
+ policies[key] = policy;
58
+ }
59
+ else {
60
+ aws_cdk_lib_1.Annotations.of(scope).addWarningV2("@composurecdk/budgets:topic-policy-not-found", `Could not find the access policy of SNS topic ${key}, so no transitional policy was ` +
61
+ `created at ${policyId}. If an earlier version deployed one there, removing it will ` +
62
+ `reset the topic's policy.`);
63
+ }
42
64
  }
43
65
  return policies;
44
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"topic-policy.js","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":";;AAoBA,gEA+BC;AAnDD,iDAAgF;AAChF,iDAA+D;AAG/D;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,0BAA0B,CACxC,KAAiB,EACjB,EAAU,EACV,MAAgB;IAEhB,MAAM,QAAQ,GAAgC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEd,MAAM,MAAM,GAAG,IAAI,qBAAW,CAAC,KAAK,EAAE,GAAG,EAAE,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE;YAC1E,MAAM,EAAE,CAAC,KAAK,CAAC;YACf,cAAc,EAAE,SAAS;SAC1B,CAAC,CAAC;QACH,MAAM,CAAC,QAAQ,CAAC,aAAa,CAC3B,IAAI,yBAAe,CAAC;YAClB,GAAG,EAAE,qBAAqB;YAC1B,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,UAAU,EAAE,CAAC,IAAI,0BAAgB,CAAC,uBAAuB,CAAC,CAAC;YAC3D,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC5B,CAAC,CACH,CAAC;QAEF,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"topic-policy.js","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":";;AA4BA,gEAkDC;AA9ED,6CAAsE;AACtE,iDAAgF;AAChF,iDAA+E;AAG/E,+EAA+E;AAC/E,SAAS,aAAa,CAAC,CAAU;IAC/B,MAAM,GAAG,GAAI,CAA4B,EAAE,IAAI,CAAC,YAAY,CAAC;IAC7D,OAAO,CACL,GAAG,KAAK,SAAS;QACjB,yBAAW,CAAC,aAAa,CAAC,GAAG,CAAC;QAC9B,GAAG,CAAC,eAAe,KAAK,wBAAc,CAAC,sBAAsB,CAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,0BAA0B,CACxC,KAAiB,EACjB,EAAU,EACV,MAAgB;IAEhB,MAAM,QAAQ,GAAgC,EAAE,CAAC;IAEjD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,IAAI,GAAG,IAAI,QAAQ;YAAE,SAAS;QAE9B,MAAM,SAAS,GAAG,IAAI,yBAAe,CAAC;YACpC,GAAG,EAAE,qBAAqB;YAC1B,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,UAAU,EAAE,CAAC,IAAI,0BAAgB,CAAC,uBAAuB,CAAC,CAAC;YAC3D,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC5B,CAAC,CAAC;QACH,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,GAAG,EAAE,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtD,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAElF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,IAAI,qBAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACrE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YACzC,yBAAW,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,YAAY,CACjC,6CAA6C,EAC7C,aAAa,GAAG,yEAAyE;gBACvF,qFAAqF;gBACrF,gFAAgF,CACnF,CAAC;YACF,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACzB,CAAC;aAAM,IAAI,aAAa,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,qBAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;gBAC9C,MAAM,EAAE,CAAC,KAAK,CAAC;gBACf,cAAc,EAAE,gBAAgB,CAAC,QAAQ;aAC1C,CAAC,CAAC;YACH,MAAM,CAAC,kBAAkB,CAAC,2BAAa,CAAC,MAAM,CAAC,CAAC;YAChD,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,yBAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAChC,8CAA8C,EAC9C,iDAAiD,GAAG,kCAAkC;gBACpF,cAAc,QAAQ,+DAA+D;gBACrF,2BAA2B,CAC9B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -68,6 +68,15 @@ export interface BudgetBuilderProps {
68
68
  * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
69
69
  */
70
70
  recommendedAlarms?: BudgetAlarmConfig | false;
71
+ /**
72
+ * Whether to grant `budgets.amazonaws.com` `SNS:Publish` on the SNS
73
+ * topics this budget notifies. Set to `false` when you manage those
74
+ * topics' access policies yourself; Budgets cannot deliver to a topic
75
+ * whose policy does not allow it.
76
+ *
77
+ * @default true
78
+ */
79
+ topicPolicy?: boolean;
71
80
  }
72
81
  /**
73
82
  * The build output of an {@link IBudgetBuilder}.
@@ -76,12 +85,14 @@ export interface BudgetBuilderResult {
76
85
  /** The `AWS::Budgets::Budget` construct. */
77
86
  budget: CfnBudget;
78
87
  /**
79
- * `AWS::SNS::TopicPolicy` constructs created automatically for any SNS
80
- * topic referenced as a notification subscriber, keyed by the topic's
81
- * fully-qualified node path. Grants `budgets.amazonaws.com` permission
82
- * to publish.
88
+ * `AWS::SNS::TopicPolicy` constructs the builder created for SNS topics
89
+ * referenced as notification subscribers, keyed by the topic's
90
+ * fully-qualified node path. The `budgets.amazonaws.com` publish
91
+ * statement itself is added to each topic's own policy; see
92
+ * {@link createBudgetsTopicPolicies} for what is created and why.
83
93
  *
84
- * `{}` when no SNS subscribers were configured.
94
+ * `{}` when no SNS subscribers were configured, or `topicPolicy` is
95
+ * `false`.
85
96
  */
86
97
  topicPolicies: Record<string, TopicPolicy>;
87
98
  /**
@@ -103,7 +114,7 @@ export interface BudgetBuilderResult {
103
114
  * Wraps the {@link CfnBudget} L1 construct (the CDK does not ship an L2
104
115
  * for Budgets) with well-architected defaults, helpers for the
105
116
  * percentage-threshold notification shape, and automatic
106
- * `AWS::SNS::TopicPolicy` wiring for SNS subscribers.
117
+ * `budgets.amazonaws.com` publish permission on SNS subscriber topics.
107
118
  *
108
119
  * The builder can also create the AWS-recommended `EstimatedCharges`
109
120
  * billing alarm; opt in via `recommendedAlarms`. For non-`us-east-1`
@@ -1 +1 @@
1
- {"version":3,"file":"budget-builder.d.ts","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"budget-builder.d.ts","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAU,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAW,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,iBAAiB,EAGvB,MAAM,oBAAoB,CAAC;AAK5B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;IAC9C;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,MAAM,EAAE,SAAS,CAAC;IAClB;;;;;;;;;OASG;IACH,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C;;;;;;;;;;OAUG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AAEzE,cAAM,aAAc,YAAW,SAAS,CAAC,mBAAmB,CAAC;;IAC3D,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAM;IAIxC;;;;;;;;;OASG;IACH,cAAc,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAI9E;;;;;;;;OAQG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAIlF;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAK/C;;;;;;;;;;OAUG;IACH,yBAAyB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAc/D;;;;;;;;;;;;;OAaG;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,aAAa,GAAG,IAAI;IAKzC,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,mBAAmB;CAsGhG;AAWD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAGpD"}
@@ -87,7 +87,7 @@ class BudgetBuilder {
87
87
  target.#customAlarms.push(...this.#customAlarms);
88
88
  }
89
89
  build(scope, id, context = {}) {
90
- const { recommendedAlarms: alarmConfig, ...budgetProps } = this.props;
90
+ const { recommendedAlarms: alarmConfig, topicPolicy = BUDGET_DEFAULTS.topicPolicy, ...budgetProps } = this.props;
91
91
  const budgetType = budgetProps.budgetType ?? BUDGET_DEFAULTS.budgetType;
92
92
  const timeUnit = budgetProps.timeUnit ?? BUDGET_DEFAULTS.timeUnit;
93
93
  const requiresLimit = budgetType === "COST" || budgetType === "USAGE";
@@ -120,7 +120,7 @@ class BudgetBuilder {
120
120
  ...(notificationsWithSubscribers.length > 0 ? { notificationsWithSubscribers } : {}),
121
121
  };
122
122
  const budget = new CfnBudget(scope, id, cfnProps);
123
- const topicPolicies = createBudgetsTopicPolicies(scope, id, snsTopics);
123
+ const topicPolicies = topicPolicy ? createBudgetsTopicPolicies(scope, id, snsTopics) : {};
124
124
  const alarms = buildBudgetAlarms(scope, id, { budget }, {
125
125
  recommendedAlarms: alarmConfig,
126
126
  customAlarms: this.#customAlarms,
@@ -1 +1 @@
1
- {"version":3,"file":"budget-builder.js","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"budget-builder.js","sourceRoot":"","sources":["../../src/budget-builder.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,13 @@ export declare const BUDGET_DEFAULTS: {
39
39
  actualPercent: number;
40
40
  forecastedPercent: number;
41
41
  };
42
+ /**
43
+ * Grant `budgets.amazonaws.com` `SNS:Publish` on SNS subscriber topics.
44
+ * Budgets cannot deliver to a topic whose access policy does not allow it.
45
+ *
46
+ * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
47
+ */
48
+ topicPolicy: boolean;
42
49
  };
43
50
  /**
44
51
  * ISO 4217 currency codes accepted by AWS Budgets for `COST` budgets'
@@ -1 +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"}
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;;;;;IAMH;;;;;OAKG;;CAEJ,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAkCtD,CAAC"}
@@ -39,6 +39,13 @@ export const BUDGET_DEFAULTS = {
39
39
  actualPercent: 80,
40
40
  forecastedPercent: 100,
41
41
  },
42
+ /**
43
+ * Grant `budgets.amazonaws.com` `SNS:Publish` on SNS subscriber topics.
44
+ * Budgets cannot deliver to a topic whose access policy does not allow it.
45
+ *
46
+ * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
47
+ */
48
+ topicPolicy: true,
42
49
  };
43
50
  /**
44
51
  * ISO 4217 currency codes accepted by AWS Budgets for `COST` budgets'
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,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;AACH,MAAM,CAAC,MAAM,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"}
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,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;IAED;;;;;OAKG;IACH,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,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"}
@@ -1,18 +1,15 @@
1
1
  import { type ITopic, TopicPolicy } from "aws-cdk-lib/aws-sns";
2
2
  import type { IConstruct } from "constructs";
3
3
  /**
4
- * Create an `AWS::SNS::TopicPolicy` granting the AWS Budgets service
5
- * principal (`budgets.amazonaws.com`) permission to publish to each of
6
- * the supplied topics.
4
+ * Grant the AWS Budgets service principal (`budgets.amazonaws.com`)
5
+ * permission to publish to each of the supplied topics, by adding the
6
+ * statement to each topic's own access policy.
7
7
  *
8
- * Without this policy, a budget notification configured with an SNS
9
- * subscriber will silently fail to deliver — one of the most common
10
- * footguns when wiring Budgets to SNS by hand. The builder wires it up
11
- * automatically whenever at least one `SNS` subscriber is configured.
12
- *
13
- * Each topic gets its own `TopicPolicy` construct, keyed by the topic's
14
- * fully-qualified CDK node path, so callers can inspect or extend them
15
- * via the build result.
8
+ * Returns the `TopicPolicy` constructs this creates, keyed by the topic's
9
+ * fully-qualified CDK node path: a retained transitional policy sharing the
10
+ * topic's own document, or — for an imported topic, whose policy CDK cannot
11
+ * add to — a standalone policy. The package README's "Automatic SNS Topic
12
+ * Policies" section explains both.
16
13
  *
17
14
  * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
18
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"topic-policy.d.ts","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA2B7B"}
1
+ {"version":3,"file":"topic-policy.d.ts","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAY7C;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA8C7B"}
@@ -1,41 +1,63 @@
1
+ import { Annotations, CfnResource, RemovalPolicy } from "aws-cdk-lib";
1
2
  import { Effect, PolicyStatement, ServicePrincipal } from "aws-cdk-lib/aws-iam";
2
- import { TopicPolicy } from "aws-cdk-lib/aws-sns";
3
+ import { CfnTopicPolicy, TopicPolicy } from "aws-cdk-lib/aws-sns";
4
+ /** Whether `x` is a `TopicPolicy` L2, by its L1's resource type (ADR-0011). */
5
+ function isTopicPolicy(x) {
6
+ const cfn = x?.node.defaultChild;
7
+ return (cfn !== undefined &&
8
+ CfnResource.isCfnResource(cfn) &&
9
+ cfn.cfnResourceType === CfnTopicPolicy.CFN_RESOURCE_TYPE_NAME);
10
+ }
3
11
  /**
4
- * Create an `AWS::SNS::TopicPolicy` granting the AWS Budgets service
5
- * principal (`budgets.amazonaws.com`) permission to publish to each of
6
- * the supplied topics.
7
- *
8
- * Without this policy, a budget notification configured with an SNS
9
- * subscriber will silently fail to deliver — one of the most common
10
- * footguns when wiring Budgets to SNS by hand. The builder wires it up
11
- * automatically whenever at least one `SNS` subscriber is configured.
12
+ * Grant the AWS Budgets service principal (`budgets.amazonaws.com`)
13
+ * permission to publish to each of the supplied topics, by adding the
14
+ * statement to each topic's own access policy.
12
15
  *
13
- * Each topic gets its own `TopicPolicy` construct, keyed by the topic's
14
- * fully-qualified CDK node path, so callers can inspect or extend them
15
- * via the build result.
16
+ * Returns the `TopicPolicy` constructs this creates, keyed by the topic's
17
+ * fully-qualified CDK node path: a retained transitional policy sharing the
18
+ * topic's own document, or — for an imported topic, whose policy CDK cannot
19
+ * add to — a standalone policy. The package README's "Automatic SNS Topic
20
+ * Policies" section explains both.
16
21
  *
17
22
  * @see https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-sns-policy.html
18
23
  */
19
24
  export function createBudgetsTopicPolicies(scope, id, topics) {
20
25
  const policies = {};
21
- const seen = new Set();
22
26
  for (const topic of topics) {
23
27
  const key = topic.node.path;
24
- if (seen.has(key))
28
+ if (key in policies)
25
29
  continue;
26
- seen.add(key);
27
- const policy = new TopicPolicy(scope, `${id}TopicPolicy${topic.node.addr}`, {
28
- topics: [topic],
29
- policyDocument: undefined,
30
- });
31
- policy.document.addStatements(new PolicyStatement({
30
+ const statement = new PolicyStatement({
32
31
  sid: "AllowBudgetsPublish",
33
32
  effect: Effect.ALLOW,
34
33
  principals: [new ServicePrincipal("budgets.amazonaws.com")],
35
34
  actions: ["SNS:Publish"],
36
35
  resources: [topic.topicArn],
37
- }));
38
- policies[key] = policy;
36
+ });
37
+ // The logical id earlier versions gave their separate Budgets-only policy.
38
+ const policyId = `${id}TopicPolicy${topic.node.addr}`;
39
+ const { statementAdded, policyDependable } = topic.addToResourcePolicy(statement);
40
+ if (!statementAdded) {
41
+ const policy = new TopicPolicy(scope, policyId, { topics: [topic] });
42
+ policy.document.addStatements(statement);
43
+ Annotations.of(policy).addWarningV2("@composurecdk/budgets:imported-topic-policy", `SNS topic ${key} was not created in this app, so its access policy cannot be added to. ` +
44
+ `This TopicPolicy grants budgets.amazonaws.com SNS:Publish and replaces the topic's ` +
45
+ `existing policy. Set topicPolicy(false) to manage the topic's policy yourself.`);
46
+ policies[key] = policy;
47
+ }
48
+ else if (isTopicPolicy(policyDependable)) {
49
+ const policy = new TopicPolicy(scope, policyId, {
50
+ topics: [topic],
51
+ policyDocument: policyDependable.document,
52
+ });
53
+ policy.applyRemovalPolicy(RemovalPolicy.RETAIN);
54
+ policies[key] = policy;
55
+ }
56
+ else {
57
+ Annotations.of(scope).addWarningV2("@composurecdk/budgets:topic-policy-not-found", `Could not find the access policy of SNS topic ${key}, so no transitional policy was ` +
58
+ `created at ${policyId}. If an earlier version deployed one there, removing it will ` +
59
+ `reset the topic's policy.`);
60
+ }
39
61
  }
40
62
  return policies;
41
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"topic-policy.js","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAe,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG/D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAiB,EACjB,EAAU,EACV,MAAgB;IAEhB,MAAM,QAAQ,GAAgC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEd,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE;YAC1E,MAAM,EAAE,CAAC,KAAK,CAAC;YACf,cAAc,EAAE,SAAS;SAC1B,CAAC,CAAC;QACH,MAAM,CAAC,QAAQ,CAAC,aAAa,CAC3B,IAAI,eAAe,CAAC;YAClB,GAAG,EAAE,qBAAqB;YAC1B,MAAM,EAAE,MAAM,CAAC,KAAK;YACpB,UAAU,EAAE,CAAC,IAAI,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;YAC3D,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC5B,CAAC,CACH,CAAC;QAEF,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"topic-policy.js","sourceRoot":"","sources":["../../src/topic-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAe,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG/E,+EAA+E;AAC/E,SAAS,aAAa,CAAC,CAAU;IAC/B,MAAM,GAAG,GAAI,CAA4B,EAAE,IAAI,CAAC,YAAY,CAAC;IAC7D,OAAO,CACL,GAAG,KAAK,SAAS;QACjB,WAAW,CAAC,aAAa,CAAC,GAAG,CAAC;QAC9B,GAAG,CAAC,eAAe,KAAK,cAAc,CAAC,sBAAsB,CAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAiB,EACjB,EAAU,EACV,MAAgB;IAEhB,MAAM,QAAQ,GAAgC,EAAE,CAAC;IAEjD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,IAAI,GAAG,IAAI,QAAQ;YAAE,SAAS;QAE9B,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC;YACpC,GAAG,EAAE,qBAAqB;YAC1B,MAAM,EAAE,MAAM,CAAC,KAAK;YACpB,UAAU,EAAE,CAAC,IAAI,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;YAC3D,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC5B,CAAC,CAAC;QACH,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,GAAG,EAAE,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtD,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAElF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACrE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YACzC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,YAAY,CACjC,6CAA6C,EAC7C,aAAa,GAAG,yEAAyE;gBACvF,qFAAqF;gBACrF,gFAAgF,CACnF,CAAC;YACF,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACzB,CAAC;aAAM,IAAI,aAAa,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;gBAC9C,MAAM,EAAE,CAAC,KAAK,CAAC;gBACf,cAAc,EAAE,gBAAgB,CAAC,QAAQ;aAC1C,CAAC,CAAC;YACH,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAChD,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAChC,8CAA8C,EAC9C,iDAAiD,GAAG,kCAAkC;gBACpF,cAAc,QAAQ,+DAA+D;gBACrF,2BAA2B,CAC9B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@composurecdk/budgets",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Composable AWS Budgets builder with well-architected defaults and automatic SNS topic policies",
5
5
  "repository": {
6
6
  "type": "git",