Skip to content

Commit 0d2b529

Browse files
authored
fix(config): Creating multiple rules from the same lambda (#21594)
fixes #17582 because the id of ".addPermission" is set to a fixed value of ″permission″, which means that only one can be set in the stack. 1. and add a unique suffix to the id. This will allow multiple custom rules to be handled in one stack. 2. Do the id check before addPermission. This will allow only one permission to be granted to a custom rule from the config service. Addendum:. I have created a hash from FunctionName, AccountID, and Region to make the suffix unique. Therefore, the omitted parts in the test code have been modified to fix the result. ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 1298cf6 commit 0d2b529

12 files changed

+99
-33
lines changed

packages/@aws-cdk/aws-config/lib/rule.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { createHash } from 'crypto';
12
import * as events from '@aws-cdk/aws-events';
23
import * as iam from '@aws-cdk/aws-iam';
34
import * as lambda from '@aws-cdk/aws-lambda';
4-
import { IResource, Lazy, Resource } from '@aws-cdk/core';
5+
import { IResource, Lazy, Resource, Stack } from '@aws-cdk/core';
56
import { Construct } from 'constructs';
67
import { CfnConfigRule } from './config.generated';
78

@@ -408,11 +409,20 @@ export class CustomRule extends RuleNew {
408409
messageType: MessageType.SCHEDULED_NOTIFICATION,
409410
});
410411
}
411-
412-
props.lambdaFunction.addPermission('Permission', {
413-
principal: new iam.ServicePrincipal('config.amazonaws.com'),
414-
sourceAccount: this.env.account,
415-
});
412+
const hash = createHash('sha256')
413+
.update(JSON.stringify({
414+
fnName: props.lambdaFunction.functionName.toString,
415+
accountId: Stack.of(this).resolve(this.env.account),
416+
region: Stack.of(this).resolve(this.env.region),
417+
}), 'utf8')
418+
.digest('base64');
419+
const customRulePermissionId: string = `CustomRulePermission${hash}`;
420+
if (!props.lambdaFunction.permissionsNode.tryFindChild(customRulePermissionId)) {
421+
props.lambdaFunction.addPermission(customRulePermissionId, {
422+
principal: new iam.ServicePrincipal('config.amazonaws.com'),
423+
sourceAccount: this.env.account,
424+
});
425+
};
416426

417427
if (props.lambdaFunction.role) {
418428
props.lambdaFunction.role.addManagedPolicy(

packages/@aws-cdk/aws-config/test/integ.rule.lit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,5 @@ class ConfigStack extends cdk.Stack {
3838
}
3939
}
4040

41-
new ConfigStack(app, 'aws-cdk-config-rule-integ');
41+
new ConfigStack(app, 'aws-cdk-config-rule-integ', {});
4242
app.synth();

packages/@aws-cdk/aws-config/test/integ.scoped-rule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as config from '../lib';
44

55
const app = new cdk.App();
66

7-
const stack = new cdk.Stack(app, 'aws-cdk-config-rule-scoped-integ');
7+
const stack = new cdk.Stack(app, 'aws-cdk-config-rule-scoped-integ', {});
88

99
const fn = new lambda.Function(stack, 'CustomFunction', {
1010
code: lambda.AssetCode.fromInline('exports.handler = (event) => console.log(event);'),

packages/@aws-cdk/aws-config/test/rule.lit.integ.snapshot/aws-cdk-config-rule-integ.assets.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"version": "21.0.0",
33
"files": {
4-
"9c0ec14ff7954b877625fb363a75213d58cb40e40acfcb23727388ddf0c52fec": {
4+
"99b272ad5d23fb805d1e06b58a04179d8720a36f6aa8cf035eff419db2e87432": {
55
"source": {
66
"path": "aws-cdk-config-rule-integ.template.json",
77
"packaging": "file"
88
},
99
"destinations": {
1010
"current_account-current_region": {
1111
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12-
"objectKey": "9c0ec14ff7954b877625fb363a75213d58cb40e40acfcb23727388ddf0c52fec.json",
12+
"objectKey": "99b272ad5d23fb805d1e06b58a04179d8720a36f6aa8cf035eff419db2e87432.json",
1313
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
1414
}
1515
}

packages/@aws-cdk/aws-config/test/rule.lit.integ.snapshot/aws-cdk-config-rule-integ.template.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"CustomFunctionServiceRoleD3F73B79"
6363
]
6464
},
65-
"CustomFunctionPermission41887A5E": {
65+
"CustomFunctionCustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5QED54A3F8": {
6666
"Type": "AWS::Lambda::Permission",
6767
"Properties": {
6868
"Action": "lambda:InvokeFunction",
@@ -107,7 +107,7 @@
107107
}
108108
},
109109
"DependsOn": [
110-
"CustomFunctionPermission41887A5E",
110+
"CustomFunctionCustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5QED54A3F8",
111111
"CustomFunctionBADD59E7",
112112
"CustomFunctionServiceRoleD3F73B79"
113113
]

packages/@aws-cdk/aws-config/test/rule.lit.integ.snapshot/manifest.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"validateOnSynth": false,
2424
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
2525
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
26-
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/9c0ec14ff7954b877625fb363a75213d58cb40e40acfcb23727388ddf0c52fec.json",
26+
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/99b272ad5d23fb805d1e06b58a04179d8720a36f6aa8cf035eff419db2e87432.json",
2727
"requiresBootstrapStackVersion": 6,
2828
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
2929
"additionalDependencies": [
@@ -51,10 +51,10 @@
5151
"data": "CustomFunctionBADD59E7"
5252
}
5353
],
54-
"/aws-cdk-config-rule-integ/CustomFunction/Permission": [
54+
"/aws-cdk-config-rule-integ/CustomFunction/CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=": [
5555
{
5656
"type": "aws:cdk:logicalId",
57-
"data": "CustomFunctionPermission41887A5E"
57+
"data": "CustomFunctionCustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5QED54A3F8"
5858
}
5959
],
6060
"/aws-cdk-config-rule-integ/Custom/Resource": [
@@ -104,6 +104,15 @@
104104
"type": "aws:cdk:logicalId",
105105
"data": "CheckBootstrapVersion"
106106
}
107+
],
108+
"CustomFunctionCustomRulePermissionXogMcOcBfKkfAgTC3zxpecyWNuSNTUwy6QrCZdRtCdwF5AB15B7": [
109+
{
110+
"type": "aws:cdk:logicalId",
111+
"data": "CustomFunctionCustomRulePermissionXogMcOcBfKkfAgTC3zxpecyWNuSNTUwy6QrCZdRtCdwF5AB15B7",
112+
"trace": [
113+
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
114+
]
115+
}
107116
]
108117
},
109118
"displayName": "aws-cdk-config-rule-integ"

packages/@aws-cdk/aws-config/test/rule.lit.integ.snapshot/tree.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@
105105
"version": "0.0.0"
106106
}
107107
},
108-
"Permission": {
109-
"id": "Permission",
110-
"path": "aws-cdk-config-rule-integ/CustomFunction/Permission",
108+
"CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=": {
109+
"id": "CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=",
110+
"path": "aws-cdk-config-rule-integ/CustomFunction/CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=",
111111
"attributes": {
112112
"aws:cdk:cloudformation:type": "AWS::Lambda::Permission",
113113
"aws:cdk:cloudformation:props": {

packages/@aws-cdk/aws-config/test/rule.test.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,6 @@ describe('rule', () => {
9191
},
9292
MaximumExecutionFrequency: 'Six_Hours',
9393
},
94-
DependsOn: [
95-
'FunctionPermissionEC8FE997',
96-
'Function76856677',
97-
'FunctionServiceRole675BB04A',
98-
],
9994
});
10095

10196
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', {
@@ -460,6 +455,49 @@ describe('rule', () => {
460455
});
461456
});
462457

458+
test('create two custom rules and one function', () => {
459+
// GIVEN
460+
const stack = new cdk.Stack();
461+
const fn = new lambda.Function(stack, 'Function', {
462+
code: lambda.AssetCode.fromInline('foo'),
463+
handler: 'index.handler',
464+
runtime: lambda.Runtime.NODEJS_14_X,
465+
});
466+
467+
// WHEN
468+
new config.CustomRule(stack, 'Rule1', {
469+
configurationChanges: true,
470+
description: 'really cool rule',
471+
lambdaFunction: fn,
472+
maximumExecutionFrequency: config.MaximumExecutionFrequency.SIX_HOURS,
473+
configRuleName: 'cool rule 1',
474+
periodic: true,
475+
});
476+
new config.CustomRule(stack, 'Rule2', {
477+
configurationChanges: true,
478+
description: 'really cool rule',
479+
lambdaFunction: fn,
480+
configRuleName: 'cool rule 2',
481+
});
482+
483+
// THEN
484+
Template.fromStack(stack).resourceCountIs('AWS::Config::ConfigRule', 2);
485+
Template.fromStack(stack).resourceCountIs('AWS::Lambda::Permission', 1);
486+
487+
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', {
488+
Action: 'lambda:InvokeFunction',
489+
FunctionName: {
490+
'Fn::GetAtt': [
491+
'Function76856677',
492+
'Arn',
493+
],
494+
},
495+
Principal: 'config.amazonaws.com',
496+
SourceAccount: {
497+
Ref: 'AWS::AccountId',
498+
},
499+
});
500+
});
463501
test('create a 0 charactor policy', () => {
464502
// GIVEN
465503
const stack = new cdk.Stack();

packages/@aws-cdk/aws-config/test/scoped-rule.integ.snapshot/aws-cdk-config-rule-scoped-integ.assets.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"version": "21.0.0",
33
"files": {
4-
"334d65f391737c79c5dd4a7f1fd9b8b58c86d362835cfcfd1a3873245cb214e0": {
4+
"ce24448515abcdc66d5b46f4e7b5a3a4bad2eda8fa9f00dde24710cbc9860c87": {
55
"source": {
66
"path": "aws-cdk-config-rule-scoped-integ.template.json",
77
"packaging": "file"
88
},
99
"destinations": {
1010
"current_account-current_region": {
1111
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12-
"objectKey": "334d65f391737c79c5dd4a7f1fd9b8b58c86d362835cfcfd1a3873245cb214e0.json",
12+
"objectKey": "ce24448515abcdc66d5b46f4e7b5a3a4bad2eda8fa9f00dde24710cbc9860c87.json",
1313
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
1414
}
1515
}

packages/@aws-cdk/aws-config/test/scoped-rule.integ.snapshot/aws-cdk-config-rule-scoped-integ.template.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"CustomFunctionServiceRoleD3F73B79"
6363
]
6464
},
65-
"CustomFunctionPermission41887A5E": {
65+
"CustomFunctionCustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5QED54A3F8": {
6666
"Type": "AWS::Lambda::Permission",
6767
"Properties": {
6868
"Action": "lambda:InvokeFunction",
@@ -103,7 +103,7 @@
103103
}
104104
},
105105
"DependsOn": [
106-
"CustomFunctionPermission41887A5E",
106+
"CustomFunctionCustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5QED54A3F8",
107107
"CustomFunctionBADD59E7",
108108
"CustomFunctionServiceRoleD3F73B79"
109109
]

packages/@aws-cdk/aws-config/test/scoped-rule.integ.snapshot/manifest.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"validateOnSynth": false,
2424
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
2525
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
26-
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/334d65f391737c79c5dd4a7f1fd9b8b58c86d362835cfcfd1a3873245cb214e0.json",
26+
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/ce24448515abcdc66d5b46f4e7b5a3a4bad2eda8fa9f00dde24710cbc9860c87.json",
2727
"requiresBootstrapStackVersion": 6,
2828
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
2929
"additionalDependencies": [
@@ -51,10 +51,10 @@
5151
"data": "CustomFunctionBADD59E7"
5252
}
5353
],
54-
"/aws-cdk-config-rule-scoped-integ/CustomFunction/Permission": [
54+
"/aws-cdk-config-rule-scoped-integ/CustomFunction/CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=": [
5555
{
5656
"type": "aws:cdk:logicalId",
57-
"data": "CustomFunctionPermission41887A5E"
57+
"data": "CustomFunctionCustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5QED54A3F8"
5858
}
5959
],
6060
"/aws-cdk-config-rule-scoped-integ/Custom/Resource": [
@@ -74,6 +74,15 @@
7474
"type": "aws:cdk:logicalId",
7575
"data": "CheckBootstrapVersion"
7676
}
77+
],
78+
"CustomFunctionPermission41887A5E": [
79+
{
80+
"type": "aws:cdk:logicalId",
81+
"data": "CustomFunctionPermission41887A5E",
82+
"trace": [
83+
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
84+
]
85+
}
7786
]
7887
},
7988
"displayName": "aws-cdk-config-rule-scoped-integ"

packages/@aws-cdk/aws-config/test/scoped-rule.integ.snapshot/tree.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@
105105
"version": "0.0.0"
106106
}
107107
},
108-
"Permission": {
109-
"id": "Permission",
110-
"path": "aws-cdk-config-rule-scoped-integ/CustomFunction/Permission",
108+
"CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=": {
109+
"id": "CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=",
110+
"path": "aws-cdk-config-rule-scoped-integ/CustomFunction/CustomRulePermissionbM1jVaicvRO9SDCiAbsQcYrOlESEtMwrrF9ZQQRvd5Q=",
111111
"attributes": {
112112
"aws:cdk:cloudformation:type": "AWS::Lambda::Permission",
113113
"aws:cdk:cloudformation:props": {

0 commit comments

Comments
 (0)