Skip to content

Commit 6e14166

Browse files
rsmaso-awsRolando Santamaria Maso
andauthored
add fine-grained invoke perms for custom resource lambda function
Co-authored-by: Rolando Santamaria Maso <rsmaso@amazon.de>
1 parent dc9d29c commit 6e14166

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

lib/resource-initializer.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import * as ec2 from '@aws-cdk/aws-ec2'
55
import * as lambda from '@aws-cdk/aws-lambda'
6-
import { Construct, Duration } from '@aws-cdk/core'
6+
import { Construct, Duration, Stack, Tags } from '@aws-cdk/core'
77
import { createHash } from 'crypto'
88
import { calculateFunctionHash } from '@aws-cdk/aws-lambda/lib/function-hash'
99
import { AwsCustomResource, AwsCustomResourcePolicy, AwsSdkCall, PhysicalResourceId } from '@aws-cdk/custom-resources'
@@ -29,6 +29,8 @@ export class CdkResourceInitializer extends Construct {
2929
constructor (scope: Construct, id: string, props: CdkResourceInitializerProps) {
3030
super(scope, id)
3131

32+
const stack = Stack.of(this)
33+
3234
const fnSg = new ec2.SecurityGroup(this, 'ResourceInitializerFnSg', {
3335
securityGroupName: `${id}ResourceInitializerFnSg`,
3436
vpc: props.vpc,
@@ -37,7 +39,7 @@ export class CdkResourceInitializer extends Construct {
3739

3840
const fn = new lambda.DockerImageFunction(this, 'ResourceInitializerFn', {
3941
memorySize: props.fnMemorySize || 128,
40-
functionName: `${id}ResourceInitializerFn`,
42+
functionName: `${id}-ResInit${stack.stackName}`,
4143
code: props.fnCode,
4244
vpcSubnets: props.vpc.selectSubnets(props.subnetsSelection),
4345
vpc: props.vpc,
@@ -66,25 +68,24 @@ export class CdkResourceInitializer extends Construct {
6668
},
6769
physicalResourceId: PhysicalResourceId.of(`${id}-AwsSdkCall-${physicalResIdHash}`)
6870
}
69-
70-
const role = new Role(this, 'AwsCustomResourceRole', {
71-
assumedBy: new ServicePrincipal('lambda.amazonaws.com')
72-
})
73-
71+
7472
// IMPORTANT: the AwsCustomResource construct deploys a singleton AWS Lambda function that is re-used across the same CDK Stack,
75-
// because it is intended to be re-used, make sure it has permissions to invoke multiple functions and it's timeout is sufficient.
73+
// because it is intended to be re-used, make sure it has permissions to invoke multiple "resource initializer functions" within the same stack and it's timeout is sufficient.
7674
// @see: https://github.com/aws/aws-cdk/blob/cafe8257b777c2c6f6143553b147873d640c6745/packages/%40aws-cdk/custom-resources/lib/aws-custom-resource/aws-custom-resource.ts#L360
77-
role.addToPolicy(
75+
const customResourceFnRole = new Role(this, 'AwsCustomResourceRole', {
76+
assumedBy: new ServicePrincipal('lambda.amazonaws.com')
77+
})
78+
customResourceFnRole.addToPolicy(
7879
new PolicyStatement({
79-
resources: ['*'],
80+
resources: [`arn:aws:lambda:${stack.region}:${stack.account}:function:*-ResInit${stack.stackName}`],
8081
actions: ['lambda:InvokeFunction']
8182
})
8283
)
8384
this.customResource = new AwsCustomResource(this, 'AwsCustomResource', {
8485
policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }),
8586
onUpdate: sdkCall,
8687
timeout: Duration.minutes(10),
87-
role
88+
role: customResourceFnRole
8889
})
8990

9091
this.response = this.customResource.getResponseField('Payload')

0 commit comments

Comments
 (0)