Skip to content

Commit b1e3dfd

Browse files
authored
fix(cloudwatch-actions): multiple alarms with LambdaAction for the same Lambda fail (under feature flag) (#28712)
Multiple alarms with LambdaAction for the same Lambda fail, because of the same logical IDs for generated lambda permissions. ```ts alarmConcurrentLambdasMaximumReached.addAlarmAction(new awsCloudWatchActions.LambdaAction(lambda)); alarmRdsCpuUtilizationMaximumReached.addAlarmAction(new awsCloudWatchActions.LambdaAction(lambda)); ``` ``` throw new Error(`There is already a Construct with name '${childName}' in ${typeName}${name.length > 0 ? ' [' + name + ']' : ''}`); ^ Error: There is already a Construct with name 'AlarmPermission' in NodejsFunction [...] ``` Since the existing logical IDs would change, I implemented this with a feature flag. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 5ede456 commit b1e3dfd

14 files changed

+919
-186
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch-actions/test/integ.lambda-alarm-action.js.snapshot/LambdaAlarmActionIntegrationTestStackWithFeatureFlag.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
{
2+
"Resources": {
3+
"inAlarmLambdaFeatureServiceRoleA2CD21D1": {
4+
"Type": "AWS::IAM::Role",
5+
"Properties": {
6+
"AssumeRolePolicyDocument": {
7+
"Statement": [
8+
{
9+
"Action": "sts:AssumeRole",
10+
"Effect": "Allow",
11+
"Principal": {
12+
"Service": "lambda.amazonaws.com"
13+
}
14+
}
15+
],
16+
"Version": "2012-10-17"
17+
},
18+
"ManagedPolicyArns": [
19+
{
20+
"Fn::Join": [
21+
"",
22+
[
23+
"arn:",
24+
{
25+
"Ref": "AWS::Partition"
26+
},
27+
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
28+
]
29+
]
30+
}
31+
]
32+
}
33+
},
34+
"inAlarmLambdaFeature6C78D351": {
35+
"Type": "AWS::Lambda::Function",
36+
"Properties": {
37+
"Code": {
38+
"ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}"
39+
},
40+
"FunctionName": "inAlarmLambdaFeature",
41+
"Handler": "index.handler",
42+
"Role": {
43+
"Fn::GetAtt": [
44+
"inAlarmLambdaFeatureServiceRoleA2CD21D1",
45+
"Arn"
46+
]
47+
},
48+
"Runtime": "nodejs18.x"
49+
},
50+
"DependsOn": [
51+
"inAlarmLambdaFeatureServiceRoleA2CD21D1"
52+
]
53+
},
54+
"Alarm7103F465": {
55+
"Type": "AWS::CloudWatch::Alarm",
56+
"Properties": {
57+
"ActionsEnabled": true,
58+
"AlarmActions": [
59+
{
60+
"Ref": "alarmLambdaFeatureCurrentVersionCF39751979501d2f67eaf906b2ef0c378303873b"
61+
},
62+
{
63+
"Ref": "alarmLambdaFeatureAliasaliasName16F91D34"
64+
},
65+
{
66+
"Fn::GetAtt": [
67+
"alarmLambdaFeatureD560800F",
68+
"Arn"
69+
]
70+
}
71+
],
72+
"ComparisonOperator": "GreaterThanThreshold",
73+
"Dimensions": [
74+
{
75+
"Name": "FunctionName",
76+
"Value": {
77+
"Ref": "inAlarmLambdaFeature6C78D351"
78+
}
79+
}
80+
],
81+
"EvaluationPeriods": 1,
82+
"MetricName": "Errors",
83+
"Namespace": "AWS/Lambda",
84+
"Period": 60,
85+
"Statistic": "Sum",
86+
"Threshold": 1,
87+
"TreatMissingData": "notBreaching"
88+
}
89+
},
90+
"alarmLambdaFeatureServiceRole853A864D": {
91+
"Type": "AWS::IAM::Role",
92+
"Properties": {
93+
"AssumeRolePolicyDocument": {
94+
"Statement": [
95+
{
96+
"Action": "sts:AssumeRole",
97+
"Effect": "Allow",
98+
"Principal": {
99+
"Service": "lambda.amazonaws.com"
100+
}
101+
}
102+
],
103+
"Version": "2012-10-17"
104+
},
105+
"ManagedPolicyArns": [
106+
{
107+
"Fn::Join": [
108+
"",
109+
[
110+
"arn:",
111+
{
112+
"Ref": "AWS::Partition"
113+
},
114+
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
115+
]
116+
]
117+
}
118+
]
119+
}
120+
},
121+
"alarmLambdaFeatureD560800F": {
122+
"Type": "AWS::Lambda::Function",
123+
"Properties": {
124+
"Code": {
125+
"ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}"
126+
},
127+
"FunctionName": "alarmLambdaFeature",
128+
"Handler": "index.handler",
129+
"Role": {
130+
"Fn::GetAtt": [
131+
"alarmLambdaFeatureServiceRole853A864D",
132+
"Arn"
133+
]
134+
},
135+
"Runtime": "nodejs18.x"
136+
},
137+
"DependsOn": [
138+
"alarmLambdaFeatureServiceRole853A864D"
139+
]
140+
},
141+
"alarmLambdaFeatureCurrentVersionCF39751979501d2f67eaf906b2ef0c378303873b": {
142+
"Type": "AWS::Lambda::Version",
143+
"Properties": {
144+
"FunctionName": {
145+
"Ref": "alarmLambdaFeatureD560800F"
146+
}
147+
}
148+
},
149+
"alarmLambdaFeatureCurrentVersionAlarmAlarmPermissionA0D80E66": {
150+
"Type": "AWS::Lambda::Permission",
151+
"Properties": {
152+
"Action": "lambda:InvokeFunction",
153+
"FunctionName": {
154+
"Ref": "alarmLambdaFeatureCurrentVersionCF39751979501d2f67eaf906b2ef0c378303873b"
155+
},
156+
"Principal": "lambda.alarms.cloudwatch.amazonaws.com",
157+
"SourceAccount": {
158+
"Ref": "AWS::AccountId"
159+
},
160+
"SourceArn": {
161+
"Fn::GetAtt": [
162+
"Alarm7103F465",
163+
"Arn"
164+
]
165+
}
166+
}
167+
},
168+
"alarmLambdaFeatureCurrentVersionAlarmFeatureAlarmPermission192451B4": {
169+
"Type": "AWS::Lambda::Permission",
170+
"Properties": {
171+
"Action": "lambda:InvokeFunction",
172+
"FunctionName": {
173+
"Ref": "alarmLambdaFeatureCurrentVersionCF39751979501d2f67eaf906b2ef0c378303873b"
174+
},
175+
"Principal": "lambda.alarms.cloudwatch.amazonaws.com",
176+
"SourceAccount": {
177+
"Ref": "AWS::AccountId"
178+
},
179+
"SourceArn": {
180+
"Fn::GetAtt": [
181+
"AlarmFeature9DD74C42",
182+
"Arn"
183+
]
184+
}
185+
}
186+
},
187+
"alarmLambdaFeatureAliasaliasName16F91D34": {
188+
"Type": "AWS::Lambda::Alias",
189+
"Properties": {
190+
"FunctionName": {
191+
"Ref": "alarmLambdaFeatureD560800F"
192+
},
193+
"FunctionVersion": {
194+
"Fn::GetAtt": [
195+
"alarmLambdaFeatureCurrentVersionCF39751979501d2f67eaf906b2ef0c378303873b",
196+
"Version"
197+
]
198+
},
199+
"Name": "aliasName"
200+
}
201+
},
202+
"alarmLambdaFeatureAliasaliasNameAlarmAlarmPermissionE344338D": {
203+
"Type": "AWS::Lambda::Permission",
204+
"Properties": {
205+
"Action": "lambda:InvokeFunction",
206+
"FunctionName": {
207+
"Ref": "alarmLambdaFeatureAliasaliasName16F91D34"
208+
},
209+
"Principal": "lambda.alarms.cloudwatch.amazonaws.com",
210+
"SourceAccount": {
211+
"Ref": "AWS::AccountId"
212+
},
213+
"SourceArn": {
214+
"Fn::GetAtt": [
215+
"Alarm7103F465",
216+
"Arn"
217+
]
218+
}
219+
}
220+
},
221+
"alarmLambdaFeatureAliasaliasNameAlarmFeatureAlarmPermission6A0A5797": {
222+
"Type": "AWS::Lambda::Permission",
223+
"Properties": {
224+
"Action": "lambda:InvokeFunction",
225+
"FunctionName": {
226+
"Ref": "alarmLambdaFeatureAliasaliasName16F91D34"
227+
},
228+
"Principal": "lambda.alarms.cloudwatch.amazonaws.com",
229+
"SourceAccount": {
230+
"Ref": "AWS::AccountId"
231+
},
232+
"SourceArn": {
233+
"Fn::GetAtt": [
234+
"AlarmFeature9DD74C42",
235+
"Arn"
236+
]
237+
}
238+
}
239+
},
240+
"alarmLambdaFeatureAlarmAlarmPermissionCF637A1C": {
241+
"Type": "AWS::Lambda::Permission",
242+
"Properties": {
243+
"Action": "lambda:InvokeFunction",
244+
"FunctionName": {
245+
"Fn::GetAtt": [
246+
"alarmLambdaFeatureD560800F",
247+
"Arn"
248+
]
249+
},
250+
"Principal": "lambda.alarms.cloudwatch.amazonaws.com",
251+
"SourceAccount": {
252+
"Ref": "AWS::AccountId"
253+
},
254+
"SourceArn": {
255+
"Fn::GetAtt": [
256+
"Alarm7103F465",
257+
"Arn"
258+
]
259+
}
260+
}
261+
},
262+
"alarmLambdaFeatureAlarmFeatureAlarmPermission7032FB2D": {
263+
"Type": "AWS::Lambda::Permission",
264+
"Properties": {
265+
"Action": "lambda:InvokeFunction",
266+
"FunctionName": {
267+
"Fn::GetAtt": [
268+
"alarmLambdaFeatureD560800F",
269+
"Arn"
270+
]
271+
},
272+
"Principal": "lambda.alarms.cloudwatch.amazonaws.com",
273+
"SourceAccount": {
274+
"Ref": "AWS::AccountId"
275+
},
276+
"SourceArn": {
277+
"Fn::GetAtt": [
278+
"AlarmFeature9DD74C42",
279+
"Arn"
280+
]
281+
}
282+
}
283+
},
284+
"AlarmFeature9DD74C42": {
285+
"Type": "AWS::CloudWatch::Alarm",
286+
"Properties": {
287+
"ActionsEnabled": true,
288+
"AlarmActions": [
289+
{
290+
"Ref": "alarmLambdaFeatureCurrentVersionCF39751979501d2f67eaf906b2ef0c378303873b"
291+
},
292+
{
293+
"Ref": "alarmLambdaFeatureAliasaliasName16F91D34"
294+
},
295+
{
296+
"Fn::GetAtt": [
297+
"alarmLambdaFeatureD560800F",
298+
"Arn"
299+
]
300+
}
301+
],
302+
"ComparisonOperator": "GreaterThanThreshold",
303+
"Dimensions": [
304+
{
305+
"Name": "FunctionName",
306+
"Value": {
307+
"Ref": "inAlarmLambdaFeature6C78D351"
308+
}
309+
}
310+
],
311+
"EvaluationPeriods": 1,
312+
"MetricName": "Errors",
313+
"Namespace": "AWS/Lambda",
314+
"Period": 60,
315+
"Statistic": "Sum",
316+
"Threshold": 1,
317+
"TreatMissingData": "notBreaching"
318+
}
319+
}
320+
},
321+
"Parameters": {
322+
"BootstrapVersion": {
323+
"Type": "AWS::SSM::Parameter::Value<String>",
324+
"Default": "/cdk-bootstrap/hnb659fds/version",
325+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
326+
}
327+
},
328+
"Rules": {
329+
"CheckBootstrapVersion": {
330+
"Assertions": [
331+
{
332+
"Assert": {
333+
"Fn::Not": [
334+
{
335+
"Fn::Contains": [
336+
[
337+
"1",
338+
"2",
339+
"3",
340+
"4",
341+
"5"
342+
],
343+
{
344+
"Ref": "BootstrapVersion"
345+
}
346+
]
347+
}
348+
]
349+
},
350+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
351+
}
352+
]
353+
}
354+
}
355+
}

packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch-actions/test/integ.lambda-alarm-action.js.snapshot/LambdaAlarmActionIntegrationTestWithFeatureFlagDefaultTestDeployAssertB72D1A4A.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)