Skip to content

Commit 72b3a95

Browse files
authored
fix(logs-destinations): missing dependency to Permission Policy created by LambdaDestination (#24823)
Fixes #21941 Credit to @daschaa for their [original PR](#22100 (comment))
1 parent d0912ca commit 72b3a95

File tree

14 files changed

+3237
-3
lines changed

14 files changed

+3237
-3
lines changed

packages/@aws-cdk/aws-logs-destinations/lib/lambda.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Construct } from 'constructs';
66
/**
77
* Options that may be provided to LambdaDestination
88
*/
9-
export interface LambdaDestinationOptions{
9+
export interface LambdaDestinationOptions {
1010
/** Whether or not to add Lambda Permissions.
1111
* @default true
1212
*/
@@ -24,13 +24,22 @@ export class LambdaDestination implements logs.ILogSubscriptionDestination {
2424
public bind(scope: Construct, logGroup: logs.ILogGroup): logs.LogSubscriptionDestinationConfig {
2525
const arn = logGroup.logGroupArn;
2626
if (this.options.addPermissions !== false) {
27-
this.fn.addPermission('CanInvokeLambda', {
27+
const permissionId = 'CanInvokeLambda';
28+
this.fn.addPermission(permissionId, {
2829
principal: new iam.ServicePrincipal('logs.amazonaws.com'),
2930
sourceArn: arn,
3031
// Using SubScription Filter as scope is okay, since every Subscription Filter has only
3132
// one destination.
3233
scope,
3334
});
35+
// Need to add a dependency, otherwise the SubscriptionFilter can be created before the
36+
// Permission that allows the interaction.
37+
const cfnPermission = scope.node.tryFindChild(
38+
permissionId,
39+
) as lambda.CfnPermission;
40+
if (cfnPermission) {
41+
scope.node.addDependency(cfnPermission);
42+
}
3443
}
3544
return { arn: this.fn.functionArn };
3645
}

packages/@aws-cdk/aws-logs-destinations/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@
7373
"license": "Apache-2.0",
7474
"devDependencies": {
7575
"@aws-cdk/assertions": "0.0.0",
76+
"@aws-cdk/aws-events": "0.0.0",
77+
"@aws-cdk/aws-events-targets": "0.0.0",
78+
"@aws-cdk/aws-lambda-destinations": "0.0.0",
79+
"@aws-cdk/aws-sqs": "0.0.0",
7680
"@aws-cdk/cdk-build-tools": "0.0.0",
7781
"@aws-cdk/integ-runner": "0.0.0",
7882
"@aws-cdk/integ-tests": "0.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"version": "31.0.0",
3+
"files": {
4+
"33583035258f91f2130bb9759626b0a4b2fe7fad9f3e63d427ce5cdc3447b820": {
5+
"source": {
6+
"path": "asset.33583035258f91f2130bb9759626b0a4b2fe7fad9f3e63d427ce5cdc3447b820.bundle",
7+
"packaging": "zip"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "33583035258f91f2130bb9759626b0a4b2fe7fad9f3e63d427ce5cdc3447b820.zip",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
},
17+
"c8724f7396e55c5282f174d8ce47850ce496ad92024bf7cb532b4885c9ce593a": {
18+
"source": {
19+
"path": "LambdaIntegDefaultTestDeployAssert7BC530B7.template.json",
20+
"packaging": "file"
21+
},
22+
"destinations": {
23+
"current_account-current_region": {
24+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
25+
"objectKey": "c8724f7396e55c5282f174d8ce47850ce496ad92024bf7cb532b4885c9ce593a.json",
26+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
27+
}
28+
}
29+
}
30+
},
31+
"dockerImages": {}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
{
2+
"Resources": {
3+
"AwsApiCallEventBridgeputEvents": {
4+
"Type": "Custom::DeployAssert@SdkCallEventBridgeputEvents",
5+
"Properties": {
6+
"ServiceToken": {
7+
"Fn::GetAtt": [
8+
"SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F",
9+
"Arn"
10+
]
11+
},
12+
"service": "EventBridge",
13+
"api": "putEvents",
14+
"parameters": {
15+
"Entries": [
16+
{
17+
"Detail": "{\"foo\":\"bar\"}",
18+
"DetailType": "cdk-integ-custom-rule",
19+
"Source": "cdk-lambda-integ"
20+
}
21+
]
22+
},
23+
"flattenResponse": "false",
24+
"salt": "1680014156730"
25+
},
26+
"UpdateReplacePolicy": "Delete",
27+
"DeletionPolicy": "Delete"
28+
},
29+
"SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": {
30+
"Type": "AWS::IAM::Role",
31+
"Properties": {
32+
"AssumeRolePolicyDocument": {
33+
"Version": "2012-10-17",
34+
"Statement": [
35+
{
36+
"Action": "sts:AssumeRole",
37+
"Effect": "Allow",
38+
"Principal": {
39+
"Service": "lambda.amazonaws.com"
40+
}
41+
}
42+
]
43+
},
44+
"ManagedPolicyArns": [
45+
{
46+
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
47+
}
48+
],
49+
"Policies": [
50+
{
51+
"PolicyName": "Inline",
52+
"PolicyDocument": {
53+
"Version": "2012-10-17",
54+
"Statement": [
55+
{
56+
"Action": [
57+
"eventbridge:PutEvents"
58+
],
59+
"Effect": "Allow",
60+
"Resource": [
61+
"*"
62+
]
63+
},
64+
{
65+
"Effect": "Allow",
66+
"Action": [
67+
"events:PutEvents"
68+
],
69+
"Resource": [
70+
"*"
71+
]
72+
},
73+
{
74+
"Action": [
75+
"sqs:ReceiveMessage"
76+
],
77+
"Effect": "Allow",
78+
"Resource": [
79+
"*"
80+
]
81+
}
82+
]
83+
}
84+
}
85+
]
86+
}
87+
},
88+
"SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": {
89+
"Type": "AWS::Lambda::Function",
90+
"Properties": {
91+
"Runtime": "nodejs14.x",
92+
"Code": {
93+
"S3Bucket": {
94+
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
95+
},
96+
"S3Key": "33583035258f91f2130bb9759626b0a4b2fe7fad9f3e63d427ce5cdc3447b820.zip"
97+
},
98+
"Timeout": 120,
99+
"Handler": "index.handler",
100+
"Role": {
101+
"Fn::GetAtt": [
102+
"SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73",
103+
"Arn"
104+
]
105+
}
106+
}
107+
},
108+
"AwsApiCallSQSreceiveMessage": {
109+
"Type": "Custom::DeployAssert@SdkCallSQSreceiveMessage",
110+
"Properties": {
111+
"ServiceToken": {
112+
"Fn::GetAtt": [
113+
"SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F",
114+
"Arn"
115+
]
116+
},
117+
"service": "SQS",
118+
"api": "receiveMessage",
119+
"expected": "{\"$ObjectLike\":{\"Messages\":[{\"Body\":{\"$StringLike\":\"\\\"responsePayload\\\":\\\"success\\\"\"}}]}}",
120+
"parameters": {
121+
"QueueUrl": {
122+
"Fn::ImportValue": "lambda-logssubscription-integ:ExportsOutputRefQueue4A7E3555425E8BD3"
123+
},
124+
"WaitTimeSeconds": 20
125+
},
126+
"flattenResponse": "false",
127+
"salt": "1680014156731"
128+
},
129+
"UpdateReplacePolicy": "Delete",
130+
"DeletionPolicy": "Delete"
131+
}
132+
},
133+
"Outputs": {
134+
"AssertionResultsAwsApiCallSQSreceiveMessage": {
135+
"Value": {
136+
"Fn::GetAtt": [
137+
"AwsApiCallSQSreceiveMessage",
138+
"assertion"
139+
]
140+
}
141+
}
142+
},
143+
"Parameters": {
144+
"BootstrapVersion": {
145+
"Type": "AWS::SSM::Parameter::Value<String>",
146+
"Default": "/cdk-bootstrap/hnb659fds/version",
147+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
148+
}
149+
},
150+
"Rules": {
151+
"CheckBootstrapVersion": {
152+
"Assertions": [
153+
{
154+
"Assert": {
155+
"Fn::Not": [
156+
{
157+
"Fn::Contains": [
158+
[
159+
"1",
160+
"2",
161+
"3",
162+
"4",
163+
"5"
164+
],
165+
{
166+
"Ref": "BootstrapVersion"
167+
}
168+
]
169+
}
170+
]
171+
},
172+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
173+
}
174+
]
175+
}
176+
}
177+
}

0 commit comments

Comments
 (0)