From 4d90557ca960da7e80cb761aee59ba0275016a92 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Tue, 16 Apr 2024 17:57:37 +0000 Subject: [PATCH 01/16] add grantInvokeV2 --- .../lib/experimental/edge-function.ts | 3 + .../aws-lambda/lib/function-base.ts | 43 ++- .../aws-lambda/test/function.test.ts | 328 ++++++++++++++++++ 3 files changed, 372 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts index 0dcf4c581598c..1e58b82ca5790 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts @@ -119,6 +119,9 @@ export class EdgeFunction extends Resource implements lambda.IVersion { public grantInvoke(identity: iam.IGrantable): iam.Grant { return this.lambda.grantInvoke(identity); } + public grantInvokeV2(identity: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant { + return this.lambda.grantInvokeV2(identity, grantVersionAccess); + } public grantInvokeUrl(identity: iam.IGrantable): iam.Grant { return this.lambda.grantInvokeUrl(identity); } diff --git a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts index 9e6055eb86b4b..875dce94f2820 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts @@ -95,12 +95,18 @@ export interface IFunction extends IResource, ec2.IConnectable, iam.IGrantable { /** * Grant the given identity permissions to invoke this Lambda */ - grantInvoke(identity: iam.IGrantable): iam.Grant; + grantInvoke(grantee: iam.IGrantable): iam.Grant; + + /** + * Grant the given identity permissions to invoke to $Latest version when grantVersionAccess is false + * Grant the given identity permissions to invoke All version when grantVersionAccess is true + */ + grantInvokeV2(grantee: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant; /** * Grant the given identity permissions to invoke this Lambda Function URL */ - grantInvokeUrl(identity: iam.IGrantable): iam.Grant; + grantInvokeUrl(grantee: iam.IGrantable): iam.Grant; /** * Grant multiple principals the ability to invoke this Lambda via CompositePrincipal @@ -437,6 +443,39 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC return grant; } + /** + * Grants the specified identity permissions to invoke this Lambda function. + * + * **Important:** Avoid using `grantInvokeV2` in conjunction with `grantInvoke`. + * + * @param grantee The principal (identity) to grant invocation permission. + * @param grantVersionAccess (Optional) Controls whether to grant access to all function versions. Defaults to `false`. + * - When set to `false`, only the function without a specific version (`$Latest`) can be invoked. + * - When set to `true`, both the function and functions with specific versions can be invoked. + */ + public grantInvokeV2(grantee: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant { + const hash = createHash('sha256') + .update(JSON.stringify({ + principal: grantee.grantPrincipal.toString(), + conditions: grantee.grantPrincipal.policyFragment.conditions, + grantVersionAccess: grantVersionAccess, + }), 'utf8') + .digest('base64'); + const identifier = `Invoke${hash}`; + + // Memoize the result so subsequent grantInvokeV2() calls are idempotent + let grant = this._invocationGrants[identifier]; + if (!grant) { + let resouceArns = [this.functionArn]; + if (grantVersionAccess) { + resouceArns = this.resourceArnsForGrantInvoke; + } + grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', resouceArns); + this._invocationGrants[identifier] = grant; + } + return grant; + } + /** * Grant the given identity permissions to invoke this Lambda Function URL */ diff --git a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts index f4c5382707641..3e9c71d321cf6 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts @@ -1525,6 +1525,334 @@ describe('function', () => { }); }); + describe('grantInvokeV2', () => { + test('adds iam:InvokeFunction', () => { + // GIVEN + const stack = new cdk.Stack(); + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.AccountPrincipal('1234'), + }); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + + // WHEN + fn.grantInvokeV2(role); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Action: 'lambda:InvokeFunction', + Effect: 'Allow', + Resource: { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + }, + ], + }, + }); + }); + + test('adds iam:InvokeFunction with version', () => { + // GIVEN + const stack = new cdk.Stack(); + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.AccountPrincipal('1234'), + }); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + + // WHEN + fn.grantInvokeV2(role, true); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Action: 'lambda:InvokeFunction', + Effect: 'Allow', + Resource: [ + { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':*']] }, + ], + }, + ], + }, + }); + }); + + test('with a service principal', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + const service = new iam.ServicePrincipal('apigateway.amazonaws.com'); + + // WHEN + fn.grantInvokeV2(service); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn', + ], + }, + Principal: 'apigateway.amazonaws.com', + }); + }); + + test('with an account principal', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + const account = new iam.AccountPrincipal('123456789012'); + + // WHEN + fn.grantInvokeV2(account); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn', + ], + }, + Principal: '123456789012', + }); + }); + + test('with an arn principal', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + const account = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/someRole'); + + // WHEN + fn.grantInvokeV2(account); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn', + ], + }, + Principal: 'arn:aws:iam::123456789012:role/someRole', + }); + }); + + test('with an organization principal', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + const org = new iam.OrganizationPrincipal('my-org-id'); + + // WHEN + fn.grantInvokeV2(org); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn', + ], + }, + Principal: '*', + PrincipalOrgID: 'my-org-id', + }); + }); + + test('can be called twice for the same service principal', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + const service = new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com'); + + // WHEN + fn.grantInvokeV2(service); + fn.grantInvokeV2(service); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn', + ], + }, + Principal: 'elasticloadbalancing.amazonaws.com', + }); + }); + + test('with an imported role (in the same account)', () => { + // GIVEN + const stack = new cdk.Stack(undefined, undefined, { + env: { account: '123456789012' }, + }); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + + // WHEN + fn.grantInvokeV2(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'lambda:InvokeFunction', + Effect: 'Allow', + Resource: { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + }, + ], + }, + Roles: ['someRole'], + }); + }); + + test('with an imported role (from a different account)', () => { + // GIVEN + const stack = new cdk.Stack(undefined, undefined, { + env: { account: '3333' }, + }); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + + // WHEN + fn.grantInvokeV2(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn', + ], + }, + Principal: 'arn:aws:iam::123456789012:role/someRole', + }); + }); + + test('on an imported function (same account)', () => { + // GIVEN + const stack = new cdk.Stack(undefined, undefined, { + env: { account: '123456789012' }, + }); + const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); + + // WHEN + fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', + Principal: 'elasticloadbalancing.amazonaws.com', + }); + }); + + test('on an imported function (unresolved account)', () => { + const stack = new cdk.Stack(); + const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); + + expect( + () => fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')), + ).toThrow(/Cannot modify permission to lambda function/); + }); + + test('on an imported function (unresolved account & w/ allowPermissions)', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = lambda.Function.fromFunctionAttributes(stack, 'Function', { + functionArn: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', + sameEnvironment: true, + }); + + // WHEN + fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', + Principal: 'elasticloadbalancing.amazonaws.com', + }); + }); + + test('on an imported function (different account)', () => { + // GIVEN + const stack = new cdk.Stack(undefined, undefined, { + env: { account: '111111111111' }, // Different account + }); + const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); + + // THEN + expect(() => { + fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + }).toThrow(/Cannot modify permission to lambda function/); + }); + + test('on an imported function (different account & w/ skipPermissions', () => { + // GIVEN + const stack = new cdk.Stack(undefined, undefined, { + env: { account: '111111111111' }, // Different account + }); + const fn = lambda.Function.fromFunctionAttributes(stack, 'Function', { + functionArn: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', + skipPermissions: true, + }); + + // THEN + expect(() => { + fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + }).not.toThrow(); + }); + }); + describe('grantInvokeCompositePrincipal', () => { test('adds iam:InvokeFunction for a CompositePrincipal (two accounts)', () => { // GIVEN From a2ca2f28ce38d3fcc3805695a886a7f2d485dff8 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Tue, 16 Apr 2024 21:33:07 +0000 Subject: [PATCH 02/16] add readme --- packages/aws-cdk-lib/aws-lambda/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index 5a876c8ae68eb..a8357014b64fe 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -201,6 +201,17 @@ You can also restrict permissions given to AWS services by providing a source account or ARN (representing the account and identifier of the resource that accesses the function or layer). +**Important**: Be aware that `fn.grantInvoke()` grants permission to the principal to call any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `fn.grantInvokeV2()` instead. + +```ts +// Grant permissions to a service +declare const fn: lambda.Function; +const principal = new iam.ServicePrincipal('my-service'); + +fn.grantInvokeV2(principal, false); +// false is the default and can be omitted +``` + For more information, see [Granting function access to AWS services](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke) in the AWS Lambda Developer Guide. From aa9d4ca6df4d3fe6d9f387fad6ebc1f47aaec242 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Tue, 16 Apr 2024 22:06:37 +0000 Subject: [PATCH 03/16] add integ test --- .../integ.permissions.js.snapshot/cdk.out | 2 +- .../integ.permissions.js.snapshot/integ.json | 2 +- .../lambda-permissions.assets.json | 6 +- .../lambda-permissions.template.json | 28 ++++ .../manifest.json | 25 ++-- .../integ.permissions.js.snapshot/tree.json | 126 ++++++++++++------ .../test/aws-lambda/test/integ.permissions.ts | 4 + 7 files changed, 136 insertions(+), 57 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out index 2313ab5436501..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"34.0.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json index 4c852f34a8d7b..cdd86e13c9071 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "testCases": { "integ.permissions": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json index 0fd8578c0072d..0fe6f14bc19f9 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json @@ -1,7 +1,7 @@ { - "version": "34.0.0", + "version": "36.0.0", "files": { - "4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341": { + "b2e192de6e64cd300b19c8ae06b46a2c61406cd49caa35f4ce1bf976f679491b": { "source": { "path": "lambda-permissions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341.json", + "objectKey": "b2e192de6e64cd300b19c8ae06b46a2c61406cd49caa35f4ce1bf976f679491b.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json index 7ac3e75fde374..ca8f785185e12 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json @@ -78,6 +78,34 @@ "PrincipalOrgID": "o-xxxxxxxxxx" } }, + "MyLambdaInvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ48B59B4A": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-yyyyyyyyyy2" + } + }, + "MyLambdaInvokefy1YgRC9j8kJQBgyNsNsleYXOlPp4RTnXEx2NNmcs4CE101ED": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-xxxxxxxxxx2" + } + }, "MyLambdaFunctionUrlC2055677": { "Type": "AWS::Lambda::Url", "Properties": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json index da8aab0b10e64..63ca9f40b6f84 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "artifacts": { "lambda-permissions.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b2e192de6e64cd300b19c8ae06b46a2c61406cd49caa35f4ce1bf976f679491b.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -58,6 +58,18 @@ "data": "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8" } ], + "/lambda-permissions/MyLambda/InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaInvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ48B59B4A" + } + ], + "/lambda-permissions/MyLambda/Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaInvokefy1YgRC9j8kJQBgyNsNsleYXOlPp4RTnXEx2NNmcs4CE101ED" + } + ], "/lambda-permissions/MyLambda/FunctionUrl/Resource": [ { "type": "aws:cdk:logicalId", @@ -99,15 +111,6 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } - ], - "MyLambdaInvokemcfVL7pJA0SB0Bm8yGhELN3cZ1c8fYqVoNxjNP4pYCE95D85164": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokemcfVL7pJA0SB0Bm8yGhELN3cZ1c8fYqVoNxjNP4pYCE95D85164", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } ] }, "displayName": "lambda-permissions" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json index 2fdf6450ac79c..8d760b30501af 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json @@ -20,8 +20,8 @@ "id": "ImportServiceRole", "path": "lambda-permissions/MyLambda/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "Resource": { @@ -59,14 +59,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" } }, "Resource": { @@ -89,8 +89,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" } }, "Invokehl--ab6+Vr41INt1IUX--IhhCesB4gzNedP5IURKNgciw=": { @@ -111,8 +111,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "Invoke138AF9IJcZORjZ--NKCKShZMMuVQwCnUkbFqMoQf5of0=": { @@ -133,8 +133,52 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=": { + "id": "InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=", + "path": "lambda-permissions/MyLambda/InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "principal": "*", + "principalOrgId": "o-yyyyyyyyyy2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=": { + "id": "Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=", + "path": "lambda-permissions/MyLambda/Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "principal": "*", + "principalOrgId": "o-xxxxxxxxxx2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "FunctionUrl": { @@ -157,14 +201,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnUrl", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.FunctionUrl", + "version": "0.0.0" } }, "InvokeSz2P2C4jO--iX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM=": { @@ -185,8 +229,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "InvokeFcyXBRX02EWa52GlF+ECQiCzDt0fdRUDi4mo4foC5aU=": { @@ -206,14 +250,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" } }, "MyRole": { @@ -224,8 +268,8 @@ "id": "ImportMyRole", "path": "lambda-permissions/MyRole/ImportMyRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "Resource": { @@ -249,8 +293,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" } }, "DefaultPolicy": { @@ -287,42 +331,42 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "lambda-permissions/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "lambda-permissions/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" } }, "Tree": { @@ -330,13 +374,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts index ce56cd25c0f8a..55f173d714ba4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts @@ -17,6 +17,10 @@ fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy')); fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx')); +fn.grantInvokeV2(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2')); + +fn.grantInvokeV2(new iam.OrganizationPrincipal('o-xxxxxxxxxx2')); + const fnUrl = fn.addFunctionUrl(); const role = new iam.Role(stack, 'MyRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), From fc612e317a10bbd0c3171b276e773dd161d93110 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 18 Apr 2024 00:17:04 +0000 Subject: [PATCH 04/16] change to grantinvoke --- .../lambda-permissions.assets.json | 4 +- .../lambda-permissions.template.json | 4 +- .../manifest.json | 10 +- .../integ.permissions.js.snapshot/tree.json | 12 +- .../test/aws-lambda/test/integ.permissions.ts | 4 +- .../lib/experimental/edge-function.ts | 7 +- packages/aws-cdk-lib/aws-lambda/README.md | 5 +- .../aws-lambda/lib/function-base.ts | 63 ++-- .../aws-lambda/test/function.test.ts | 336 +----------------- 9 files changed, 63 insertions(+), 382 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json index 0fe6f14bc19f9..8ce83217aff9a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "b2e192de6e64cd300b19c8ae06b46a2c61406cd49caa35f4ce1bf976f679491b": { + "018c275dea5b6c3d59a2559a0749bbb85138bfa549ff989fc5bdea87a681546f": { "source": { "path": "lambda-permissions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "b2e192de6e64cd300b19c8ae06b46a2c61406cd49caa35f4ce1bf976f679491b.json", + "objectKey": "018c275dea5b6c3d59a2559a0749bbb85138bfa549ff989fc5bdea87a681546f.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json index ca8f785185e12..e3b51a1d026ad 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json @@ -78,7 +78,7 @@ "PrincipalOrgID": "o-xxxxxxxxxx" } }, - "MyLambdaInvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ48B59B4A": { + "MyLambdaInvokeiasez2Hq1vE2Fl1I4Yaq8UbNdwu1QsvuMXzIoTAF759EB93": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -92,7 +92,7 @@ "PrincipalOrgID": "o-yyyyyyyyyy2" } }, - "MyLambdaInvokefy1YgRC9j8kJQBgyNsNsleYXOlPp4RTnXEx2NNmcs4CE101ED": { + "MyLambdaInvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c0F884F73": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json index 63ca9f40b6f84..b7f336e9615b0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b2e192de6e64cd300b19c8ae06b46a2c61406cd49caa35f4ce1bf976f679491b.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/018c275dea5b6c3d59a2559a0749bbb85138bfa549ff989fc5bdea87a681546f.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -58,16 +58,16 @@ "data": "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8" } ], - "/lambda-permissions/MyLambda/InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=": [ + "/lambda-permissions/MyLambda/Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ48B59B4A" + "data": "MyLambdaInvokeiasez2Hq1vE2Fl1I4Yaq8UbNdwu1QsvuMXzIoTAF759EB93" } ], - "/lambda-permissions/MyLambda/Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=": [ + "/lambda-permissions/MyLambda/InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokefy1YgRC9j8kJQBgyNsNsleYXOlPp4RTnXEx2NNmcs4CE101ED" + "data": "MyLambdaInvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c0F884F73" } ], "/lambda-permissions/MyLambda/FunctionUrl/Resource": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json index 8d760b30501af..f53602a03e6d1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json @@ -137,9 +137,9 @@ "version": "0.0.0" } }, - "InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=": { - "id": "InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=", - "path": "lambda-permissions/MyLambda/InvokeZoBUDhNic8W9iwOX3PUHW4PxLYxcNvgQd0I750ZVGfQ=", + "Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=": { + "id": "Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=", + "path": "lambda-permissions/MyLambda/Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", "aws:cdk:cloudformation:props": { @@ -159,9 +159,9 @@ "version": "0.0.0" } }, - "Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=": { - "id": "Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=", - "path": "lambda-permissions/MyLambda/Invokefy1YgRC9j8kJQBgy+NsNsleYXOl--Pp4RTnXEx2NNmcs=", + "InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=": { + "id": "InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=", + "path": "lambda-permissions/MyLambda/InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", "aws:cdk:cloudformation:props": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts index 55f173d714ba4..9079c0a76efbf 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts @@ -17,9 +17,9 @@ fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy')); fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx')); -fn.grantInvokeV2(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2')); +fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'), { onlyGrantLatestVersion: true }); -fn.grantInvokeV2(new iam.OrganizationPrincipal('o-xxxxxxxxxx2')); +fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx2'), { onlyGrantLatestVersion: true }); const fnUrl = fn.addFunctionUrl(); const role = new iam.Role(stack, 'MyRole', { diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts index 1e58b82ca5790..93974491855e0 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts @@ -116,11 +116,8 @@ export class EdgeFunction extends Resource implements lambda.IVersion { public addToRolePolicy(statement: iam.PolicyStatement): void { return this.lambda.addToRolePolicy(statement); } - public grantInvoke(identity: iam.IGrantable): iam.Grant { - return this.lambda.grantInvoke(identity); - } - public grantInvokeV2(identity: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant { - return this.lambda.grantInvokeV2(identity, grantVersionAccess); + public grantInvoke(identity: iam.IGrantable, props?: lambda.GrantInvokeProps): iam.Grant { + return this.lambda.grantInvoke(identity, props); } public grantInvokeUrl(identity: iam.IGrantable): iam.Grant { return this.lambda.grantInvokeUrl(identity); diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index a8357014b64fe..04311dc47b715 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -201,15 +201,14 @@ You can also restrict permissions given to AWS services by providing a source account or ARN (representing the account and identifier of the resource that accesses the function or layer). -**Important**: Be aware that `fn.grantInvoke()` grants permission to the principal to call any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `fn.grantInvokeV2()` instead. +**Important**: By default `fn.grantInvoke()` grants permission to the principal to invoke any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `grantInvoke(grantee, { onlyGrantLatestVersion:true })`. ```ts // Grant permissions to a service declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); -fn.grantInvokeV2(principal, false); -// false is the default and can be omitted +grantInvoke(principal, { onlyGrantLatestVersion = true }); ``` For more information, see diff --git a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts index 875dce94f2820..5b5b483f7e0de 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts @@ -95,13 +95,7 @@ export interface IFunction extends IResource, ec2.IConnectable, iam.IGrantable { /** * Grant the given identity permissions to invoke this Lambda */ - grantInvoke(grantee: iam.IGrantable): iam.Grant; - - /** - * Grant the given identity permissions to invoke to $Latest version when grantVersionAccess is false - * Grant the given identity permissions to invoke All version when grantVersionAccess is true - */ - grantInvokeV2(grantee: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant; + grantInvoke(grantee: iam.IGrantable, props?: GrantInvokeProps): iam.Grant; /** * Grant the given identity permissions to invoke this Lambda Function URL @@ -233,6 +227,19 @@ export interface FunctionAttributes { readonly architecture?: Architecture; } +/** + * Parameters to pass into grantInvoke method + */ +export interface GrantInvokeProps { + /** + * Controls whether to grant invoke access to all function versions. Defaults to `false`. + * - When set to `false`, both the function and functions with specific versions can be invoked. + * - When set to `true`, only the function without a specific version (`$Latest`) can be invoked. + * @default false + */ + readonly onlyGrantLatestVersion?: boolean; +} + export abstract class FunctionBase extends Resource implements IFunction, ec2.IClientVpnConnectionHandler { /** * The principal this Lambda Function is running as @@ -424,51 +431,27 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC /** * Grant the given identity permissions to invoke this Lambda - */ - public grantInvoke(grantee: iam.IGrantable): iam.Grant { - const hash = createHash('sha256') - .update(JSON.stringify({ - principal: grantee.grantPrincipal.toString(), - conditions: grantee.grantPrincipal.policyFragment.conditions, - }), 'utf8') - .digest('base64'); - const identifier = `Invoke${hash}`; - - // Memoize the result so subsequent grantInvoke() calls are idempotent - let grant = this._invocationGrants[identifier]; - if (!grant) { - grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', this.resourceArnsForGrantInvoke); - this._invocationGrants[identifier] = grant; - } - return grant; - } - - /** - * Grants the specified identity permissions to invoke this Lambda function. - * - * **Important:** Avoid using `grantInvokeV2` in conjunction with `grantInvoke`. - * * @param grantee The principal (identity) to grant invocation permission. - * @param grantVersionAccess (Optional) Controls whether to grant access to all function versions. Defaults to `false`. - * - When set to `false`, only the function without a specific version (`$Latest`) can be invoked. - * - When set to `true`, both the function and functions with specific versions can be invoked. + * @param props onlyGrantLatestVersion (Optional) Controls whether to grant access only to latest function versions. Defaults to `false`. + * - When set to `false`, both the function and functions with specific versions can be invoked. + * - When set to `true`, only the function without a specific version (`$Latest`) can be invoked. */ - public grantInvokeV2(grantee: iam.IGrantable, grantVersionAccess?: boolean): iam.Grant { + public grantInvoke(grantee: iam.IGrantable, props: GrantInvokeProps = {}): iam.Grant { const hash = createHash('sha256') .update(JSON.stringify({ principal: grantee.grantPrincipal.toString(), conditions: grantee.grantPrincipal.policyFragment.conditions, - grantVersionAccess: grantVersionAccess, + onlyGrantLatestVersion: props.onlyGrantLatestVersion, }), 'utf8') .digest('base64'); const identifier = `Invoke${hash}`; - // Memoize the result so subsequent grantInvokeV2() calls are idempotent + // Memoize the result so subsequent grantInvoke() calls are idempotent let grant = this._invocationGrants[identifier]; if (!grant) { - let resouceArns = [this.functionArn]; - if (grantVersionAccess) { - resouceArns = this.resourceArnsForGrantInvoke; + let resouceArns = this.resourceArnsForGrantInvoke; + if (props.onlyGrantLatestVersion) { + resouceArns = [this.functionArn]; } grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', resouceArns); this._invocationGrants[identifier] = grant; diff --git a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts index bfb37d73b4fb3..9038425b57347 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts @@ -1282,275 +1282,7 @@ describe('function', () => { }); }); - test('with a service principal', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - const service = new iam.ServicePrincipal('apigateway.amazonaws.com'); - - // WHEN - fn.grantInvoke(service); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: { - 'Fn::GetAtt': [ - 'Function76856677', - 'Arn', - ], - }, - Principal: 'apigateway.amazonaws.com', - }); - }); - - test('with an account principal', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - const account = new iam.AccountPrincipal('123456789012'); - - // WHEN - fn.grantInvoke(account); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: { - 'Fn::GetAtt': [ - 'Function76856677', - 'Arn', - ], - }, - Principal: '123456789012', - }); - }); - - test('with an arn principal', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - const account = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/someRole'); - - // WHEN - fn.grantInvoke(account); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: { - 'Fn::GetAtt': [ - 'Function76856677', - 'Arn', - ], - }, - Principal: 'arn:aws:iam::123456789012:role/someRole', - }); - }); - - test('with an organization principal', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - const org = new iam.OrganizationPrincipal('my-org-id'); - - // WHEN - fn.grantInvoke(org); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: { - 'Fn::GetAtt': [ - 'Function76856677', - 'Arn', - ], - }, - Principal: '*', - PrincipalOrgID: 'my-org-id', - }); - }); - - test('can be called twice for the same service principal', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - const service = new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com'); - - // WHEN - fn.grantInvoke(service); - fn.grantInvoke(service); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: { - 'Fn::GetAtt': [ - 'Function76856677', - 'Arn', - ], - }, - Principal: 'elasticloadbalancing.amazonaws.com', - }); - }); - - test('with an imported role (in the same account)', () => { - // GIVEN - const stack = new cdk.Stack(undefined, undefined, { - env: { account: '123456789012' }, - }); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - - // WHEN - fn.grantInvoke(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Statement: [ - { - Action: 'lambda:InvokeFunction', - Effect: 'Allow', - Resource: [ - { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, - { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':*']] }, - ], - }, - ], - }, - Roles: ['someRole'], - }); - }); - - test('with an imported role (from a different account)', () => { - // GIVEN - const stack = new cdk.Stack(undefined, undefined, { - env: { account: '3333' }, - }); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - - // WHEN - fn.grantInvoke(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: { - 'Fn::GetAtt': [ - 'Function76856677', - 'Arn', - ], - }, - Principal: 'arn:aws:iam::123456789012:role/someRole', - }); - }); - - test('on an imported function (same account)', () => { - // GIVEN - const stack = new cdk.Stack(undefined, undefined, { - env: { account: '123456789012' }, - }); - const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); - - // WHEN - fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', - Principal: 'elasticloadbalancing.amazonaws.com', - }); - }); - - test('on an imported function (unresolved account)', () => { - const stack = new cdk.Stack(); - const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); - - expect( - () => fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')), - ).toThrow(/Cannot modify permission to lambda function/); - }); - - test('on an imported function (unresolved account & w/ allowPermissions)', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = lambda.Function.fromFunctionAttributes(stack, 'Function', { - functionArn: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', - sameEnvironment: true, - }); - - // WHEN - fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - Action: 'lambda:InvokeFunction', - FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', - Principal: 'elasticloadbalancing.amazonaws.com', - }); - }); - - test('on an imported function (different account)', () => { - // GIVEN - const stack = new cdk.Stack(undefined, undefined, { - env: { account: '111111111111' }, // Different account - }); - const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); - - // THEN - expect(() => { - fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); - }).toThrow(/Cannot modify permission to lambda function/); - }); - - test('on an imported function (different account & w/ skipPermissions', () => { - // GIVEN - const stack = new cdk.Stack(undefined, undefined, { - env: { account: '111111111111' }, // Different account - }); - const fn = lambda.Function.fromFunctionAttributes(stack, 'Function', { - functionArn: 'arn:aws:lambda:us-east-1:123456789012:function:MyFn', - skipPermissions: true, - }); - - // THEN - expect(() => { - fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); - }).not.toThrow(); - }); - }); - - describe('grantInvokeV2', () => { - test('adds iam:InvokeFunction', () => { + test('adds iam:InvokeFunction with onlyGrantLatestVersion', () => { // GIVEN const stack = new cdk.Stack(); const role = new iam.Role(stack, 'Role', { @@ -1563,7 +1295,7 @@ describe('function', () => { }); // WHEN - fn.grantInvokeV2(role); + fn.grantInvoke(role, { onlyGrantLatestVersion:true }); // THEN Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { @@ -1580,39 +1312,6 @@ describe('function', () => { }); }); - test('adds iam:InvokeFunction with version', () => { - // GIVEN - const stack = new cdk.Stack(); - const role = new iam.Role(stack, 'Role', { - assumedBy: new iam.AccountPrincipal('1234'), - }); - const fn = new lambda.Function(stack, 'Function', { - code: lambda.Code.fromInline('xxx'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_LATEST, - }); - - // WHEN - fn.grantInvokeV2(role, true); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Version: '2012-10-17', - Statement: [ - { - Action: 'lambda:InvokeFunction', - Effect: 'Allow', - Resource: [ - { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, - { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':*']] }, - ], - }, - ], - }, - }); - }); - test('with a service principal', () => { // GIVEN const stack = new cdk.Stack(); @@ -1624,7 +1323,7 @@ describe('function', () => { const service = new iam.ServicePrincipal('apigateway.amazonaws.com'); // WHEN - fn.grantInvokeV2(service); + fn.grantInvoke(service); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1650,7 +1349,7 @@ describe('function', () => { const account = new iam.AccountPrincipal('123456789012'); // WHEN - fn.grantInvokeV2(account); + fn.grantInvoke(account); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1676,7 +1375,7 @@ describe('function', () => { const account = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/someRole'); // WHEN - fn.grantInvokeV2(account); + fn.grantInvoke(account); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1702,7 +1401,7 @@ describe('function', () => { const org = new iam.OrganizationPrincipal('my-org-id'); // WHEN - fn.grantInvokeV2(org); + fn.grantInvoke(org); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1729,8 +1428,8 @@ describe('function', () => { const service = new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com'); // WHEN - fn.grantInvokeV2(service); - fn.grantInvokeV2(service); + fn.grantInvoke(service); + fn.grantInvoke(service); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1757,7 +1456,7 @@ describe('function', () => { }); // WHEN - fn.grantInvokeV2(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); + fn.grantInvoke(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); // THEN Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { @@ -1766,7 +1465,10 @@ describe('function', () => { { Action: 'lambda:InvokeFunction', Effect: 'Allow', - Resource: { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + Resource: [ + { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':*']] }, + ], }, ], }, @@ -1786,7 +1488,7 @@ describe('function', () => { }); // WHEN - fn.grantInvokeV2(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); + fn.grantInvoke(iam.Role.fromRoleArn(stack, 'ForeignRole', 'arn:aws:iam::123456789012:role/someRole')); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1809,7 +1511,7 @@ describe('function', () => { const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); // WHEN - fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1824,7 +1526,7 @@ describe('function', () => { const fn = lambda.Function.fromFunctionArn(stack, 'Function', 'arn:aws:lambda:us-east-1:123456789012:function:MyFn'); expect( - () => fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')), + () => fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')), ).toThrow(/Cannot modify permission to lambda function/); }); @@ -1837,7 +1539,7 @@ describe('function', () => { }); // WHEN - fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { @@ -1856,7 +1558,7 @@ describe('function', () => { // THEN expect(() => { - fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); }).toThrow(/Cannot modify permission to lambda function/); }); @@ -1872,7 +1574,7 @@ describe('function', () => { // THEN expect(() => { - fn.grantInvokeV2(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); + fn.grantInvoke(new iam.ServicePrincipal('elasticloadbalancing.amazonaws.com')); }).not.toThrow(); }); }); From 679e6a6479d2ddc6ac4a5f1d43533f7fe10ea4df Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 18 Apr 2024 00:31:19 +0000 Subject: [PATCH 05/16] lint --- packages/aws-cdk-lib/aws-lambda/test/function.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts index 9038425b57347..355429e7d26a3 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts @@ -1295,7 +1295,7 @@ describe('function', () => { }); // WHEN - fn.grantInvoke(role, { onlyGrantLatestVersion:true }); + fn.grantInvoke(role, { onlyGrantLatestVersion: true }); // THEN Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { From 0857f65b7fa179d300d9e01df88d5833d82317c4 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 18 Apr 2024 01:48:57 +0000 Subject: [PATCH 06/16] typo --- packages/aws-cdk-lib/aws-lambda/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index 04311dc47b715..4878de793dd02 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -208,7 +208,7 @@ that accesses the function or layer). declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); -grantInvoke(principal, { onlyGrantLatestVersion = true }); +grantInvoke(principal, { onlyGrantLatestVersion : true }); ``` For more information, see From 34d1506a4a537eb233328b2e426eef23ccf71160 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 18 Apr 2024 02:23:49 +0000 Subject: [PATCH 07/16] add fn --- packages/aws-cdk-lib/aws-lambda/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index 4878de793dd02..394f448284f05 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -208,7 +208,7 @@ that accesses the function or layer). declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); -grantInvoke(principal, { onlyGrantLatestVersion : true }); +fn.grantInvoke(principal, { onlyGrantLatestVersion : true }); ``` For more information, see From a502cd0bb57a4ad2e6403f9655b0d9088031a8c9 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 18 Apr 2024 02:42:30 +0000 Subject: [PATCH 08/16] test --- packages/aws-cdk-lib/aws-lambda/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index 394f448284f05..b3db1dde410ab 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -204,10 +204,9 @@ that accesses the function or layer). **Important**: By default `fn.grantInvoke()` grants permission to the principal to invoke any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `grantInvoke(grantee, { onlyGrantLatestVersion:true })`. ```ts -// Grant permissions to a service declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); - +// Grant invoke only to latest version fn.grantInvoke(principal, { onlyGrantLatestVersion : true }); ``` From 5e5e6c9fb745377da8431bcd307e5f44ae5d94c2 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Fri, 3 May 2024 01:29:42 +0000 Subject: [PATCH 09/16] add grantInvokeLatestVersion --- .../lambda-permissions.assets.json | 4 +- .../lambda-permissions.template.json | 40 ++++++++- .../manifest.json | 28 ++++-- .../integ.permissions.js.snapshot/tree.json | 90 +++++++++++++++++-- .../test/aws-lambda/test/integ.permissions.ts | 12 ++- .../lib/experimental/edge-function.ts | 10 ++- packages/aws-cdk-lib/aws-lambda/README.md | 15 +++- .../aws-lambda/lib/function-base.ts | 69 +++++++++----- .../aws-lambda/test/function.test.ts | 42 ++++++++- 9 files changed, 263 insertions(+), 47 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json index 8ce83217aff9a..69073756cdbd4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "018c275dea5b6c3d59a2559a0749bbb85138bfa549ff989fc5bdea87a681546f": { + "7bb46ab3ee8f5a5ea32ecdb2339294d95acaf255531ed2a40e8e845f4104bce6": { "source": { "path": "lambda-permissions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "018c275dea5b6c3d59a2559a0749bbb85138bfa549ff989fc5bdea87a681546f.json", + "objectKey": "7bb46ab3ee8f5a5ea32ecdb2339294d95acaf255531ed2a40e8e845f4104bce6.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json index e3b51a1d026ad..6fd033b4bb135 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json @@ -78,7 +78,7 @@ "PrincipalOrgID": "o-xxxxxxxxxx" } }, - "MyLambdaInvokeiasez2Hq1vE2Fl1I4Yaq8UbNdwu1QsvuMXzIoTAF759EB93": { + "MyLambdaInvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgpnic82377EF6": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -92,7 +92,35 @@ "PrincipalOrgID": "o-yyyyyyyyyy2" } }, - "MyLambdaInvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c0F884F73": { + "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-xxxxxxxxxx2" + } + }, + "MyLambdaInvokeeSO2bF2vs89Bu95ZGbotCaJ9349433GggVuY4yuDDo6A19947D": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-yyyyyyyyyy2" + } + }, + "MyLambdaInvokevlkDSBAbWHnqhYUcxXc8dNNBhmEU5NTv6gX4EMtBA9DCAF0DD": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -145,6 +173,14 @@ "Principal": "apigateway.amazonaws.com" } }, + "v192FF9954": { + "Type": "AWS::Lambda::Version", + "Properties": { + "FunctionName": { + "Ref": "MyLambdaCCE802FB" + } + } + }, "MyRoleF48FFE04": { "Type": "AWS::IAM::Role", "Properties": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json index b7f336e9615b0..e6f10bfc200a1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/018c275dea5b6c3d59a2559a0749bbb85138bfa549ff989fc5bdea87a681546f.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7bb46ab3ee8f5a5ea32ecdb2339294d95acaf255531ed2a40e8e845f4104bce6.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -58,16 +58,28 @@ "data": "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8" } ], - "/lambda-permissions/MyLambda/Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=": [ + "/lambda-permissions/MyLambda/InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeiasez2Hq1vE2Fl1I4Yaq8UbNdwu1QsvuMXzIoTAF759EB93" + "data": "MyLambdaInvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgpnic82377EF6" } ], - "/lambda-permissions/MyLambda/InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=": [ + "/lambda-permissions/MyLambda/InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c0F884F73" + "data": "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4" + } + ], + "/lambda-permissions/MyLambda/InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaInvokeeSO2bF2vs89Bu95ZGbotCaJ9349433GggVuY4yuDDo6A19947D" + } + ], + "/lambda-permissions/MyLambda/Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaInvokevlkDSBAbWHnqhYUcxXc8dNNBhmEU5NTv6gX4EMtBA9DCAF0DD" } ], "/lambda-permissions/MyLambda/FunctionUrl/Resource": [ @@ -88,6 +100,12 @@ "data": "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58" } ], + "/lambda-permissions/v1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "v192FF9954" + } + ], "/lambda-permissions/MyRole/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json index f53602a03e6d1..52035017690f2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json @@ -137,9 +137,17 @@ "version": "0.0.0" } }, - "Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=": { - "id": "Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=", - "path": "lambda-permissions/MyLambda/Invoke--iasez2Hq1vE2Fl1I4--Yaq8UbNdw--u1QsvuMXzIo+TA=", + "$LATEST": { + "id": "$LATEST", + "path": "lambda-permissions/MyLambda/$LATEST", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=": { + "id": "InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=", + "path": "lambda-permissions/MyLambda/InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", "aws:cdk:cloudformation:props": { @@ -159,9 +167,53 @@ "version": "0.0.0" } }, - "InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=": { - "id": "InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=", - "path": "lambda-permissions/MyLambda/InvokeeCd3Xf1YrYI9J9KZWaa7iTC3wv2MejAlHdcglgF5m4c=", + "InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=": { + "id": "InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=", + "path": "lambda-permissions/MyLambda/InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "principal": "*", + "principalOrgId": "o-xxxxxxxxxx2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=": { + "id": "InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=", + "path": "lambda-permissions/MyLambda/InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "principal": "*", + "principalOrgId": "o-yyyyyyyyyy2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=": { + "id": "Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=", + "path": "lambda-permissions/MyLambda/Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", "aws:cdk:cloudformation:props": { @@ -260,6 +312,32 @@ "version": "0.0.0" } }, + "v1": { + "id": "v1", + "path": "lambda-permissions/v1", + "children": { + "Resource": { + "id": "Resource", + "path": "lambda-permissions/v1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Version", + "aws:cdk:cloudformation:props": { + "functionName": { + "Ref": "MyLambdaCCE802FB" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnVersion", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Version", + "version": "0.0.0" + } + }, "MyRole": { "id": "MyRole", "path": "lambda-permissions/MyRole", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts index 9079c0a76efbf..4a57ca80d94ec 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts @@ -17,9 +17,17 @@ fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy')); fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx')); -fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'), { onlyGrantLatestVersion: true }); +fn.grantInvokeLatestVersion(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2')); -fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx2'), { onlyGrantLatestVersion: true }); +fn.grantInvokeLatestVersion(new iam.OrganizationPrincipal('o-xxxxxxxxxx2')); + +const version1 = new lambda.Version(stack, 'v1', { + lambda: fn +}); + +fn.grantInvokeVersion(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'), version1); + +fn.grantInvokeVersion(new iam.OrganizationPrincipal('o-xxxxxxxxxx2'), version1); const fnUrl = fn.addFunctionUrl(); const role = new iam.Role(stack, 'MyRole', { diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts index 93974491855e0..86861e8a1ca10 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/experimental/edge-function.ts @@ -116,8 +116,14 @@ export class EdgeFunction extends Resource implements lambda.IVersion { public addToRolePolicy(statement: iam.PolicyStatement): void { return this.lambda.addToRolePolicy(statement); } - public grantInvoke(identity: iam.IGrantable, props?: lambda.GrantInvokeProps): iam.Grant { - return this.lambda.grantInvoke(identity, props); + public grantInvoke(identity: iam.IGrantable): iam.Grant { + return this.lambda.grantInvoke(identity); + } + public grantInvokeLatestVersion(identity: iam.IGrantable): iam.Grant { + return this.lambda.grantInvokeLatestVersion(identity); + } + public grantInvokeVersion(identity: iam.IGrantable, version: lambda.IVersion): iam.Grant { + return this.lambda.grantInvokeVersion(identity, version); } public grantInvokeUrl(identity: iam.IGrantable): iam.Grant { return this.lambda.grantInvokeUrl(identity); diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index b3db1dde410ab..e77dc0b7fa9d9 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -201,13 +201,24 @@ You can also restrict permissions given to AWS services by providing a source account or ARN (representing the account and identifier of the resource that accesses the function or layer). -**Important**: By default `fn.grantInvoke()` grants permission to the principal to invoke any version of the function, including all past ones. If you only want the principal to invoke the latest version, use `grantInvoke(grantee, { onlyGrantLatestVersion:true })`. +**Important**: +> By default `fn.grantInvoke()` grants permission to the principal to invoke any version of the function, including all past ones. If you only want the principal to be granted permission to invoke the latest version or the unqualified Lambda ARN, use `grantInvokeLatestVersion(grantee)`. ```ts declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); +declare const version: lambda.IVersion; // Grant invoke only to latest version -fn.grantInvoke(principal, { onlyGrantLatestVersion : true }); +fn.grantInvokeVersion(principal, version); +``` + +If you want to grant access for invoking a specific version of Lambda function, you can use `fn.grantInovkeVersion(grantee, version)` + +```ts +declare const fn: lambda.Function; +const principal = new iam.ServicePrincipal('my-service'); +// Grant invoke only to latest version +fn.grantInvokeLatestVersion(principal); ``` For more information, see diff --git a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts index 5b5b483f7e0de..c5a108cf396de 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts @@ -95,7 +95,18 @@ export interface IFunction extends IResource, ec2.IConnectable, iam.IGrantable { /** * Grant the given identity permissions to invoke this Lambda */ - grantInvoke(grantee: iam.IGrantable, props?: GrantInvokeProps): iam.Grant; + grantInvoke(identity: iam.IGrantable): iam.Grant; + + /** + * Grant the given identity permissions to invoke the $LATEST version or + * unqualified version of this Lambda + */ + grantInvokeLatestVersion(identity: iam.IGrantable): iam.Grant; + + /** + * Grant the given identity permissions to invoke the given version of this Lambda + */ + grantInvokeVersion(identity: iam.IGrantable, version: IVersion): iam.Grant; /** * Grant the given identity permissions to invoke this Lambda Function URL @@ -227,19 +238,6 @@ export interface FunctionAttributes { readonly architecture?: Architecture; } -/** - * Parameters to pass into grantInvoke method - */ -export interface GrantInvokeProps { - /** - * Controls whether to grant invoke access to all function versions. Defaults to `false`. - * - When set to `false`, both the function and functions with specific versions can be invoked. - * - When set to `true`, only the function without a specific version (`$Latest`) can be invoked. - * @default false - */ - readonly onlyGrantLatestVersion?: boolean; -} - export abstract class FunctionBase extends Resource implements IFunction, ec2.IClientVpnConnectionHandler { /** * The principal this Lambda Function is running as @@ -431,17 +429,42 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC /** * Grant the given identity permissions to invoke this Lambda - * @param grantee The principal (identity) to grant invocation permission. - * @param props onlyGrantLatestVersion (Optional) Controls whether to grant access only to latest function versions. Defaults to `false`. - * - When set to `false`, both the function and functions with specific versions can be invoked. - * - When set to `true`, only the function without a specific version (`$Latest`) can be invoked. */ - public grantInvoke(grantee: iam.IGrantable, props: GrantInvokeProps = {}): iam.Grant { + public grantInvoke(grantee: iam.IGrantable): iam.Grant { + const hash = createHash('sha256') + .update(JSON.stringify({ + principal: grantee.grantPrincipal.toString(), + conditions: grantee.grantPrincipal.policyFragment.conditions, + }), 'utf8') + .digest('base64'); + const identifier = `Invoke${hash}`; + + // Memoize the result so subsequent grantInvoke() calls are idempotent + let grant = this._invocationGrants[identifier]; + if (!grant) { + grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', this.resourceArnsForGrantInvoke); + this._invocationGrants[identifier] = grant; + } + return grant; + } + + /** + * Grant the given identity permissions to invoke the $LATEST version or + * unqualified version of this Lambda + */ + public grantInvokeLatestVersion(grantee: iam.IGrantable): iam.Grant { + return this.grantInvokeVersion(grantee, this.latestVersion); + } + + /** + * Grant the given identity permissions to invoke the given version of this Lambda + */ + public grantInvokeVersion(grantee: iam.IGrantable, version: IVersion): iam.Grant { const hash = createHash('sha256') .update(JSON.stringify({ principal: grantee.grantPrincipal.toString(), conditions: grantee.grantPrincipal.policyFragment.conditions, - onlyGrantLatestVersion: props.onlyGrantLatestVersion, + version: version.version, }), 'utf8') .digest('base64'); const identifier = `Invoke${hash}`; @@ -449,9 +472,9 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC // Memoize the result so subsequent grantInvoke() calls are idempotent let grant = this._invocationGrants[identifier]; if (!grant) { - let resouceArns = this.resourceArnsForGrantInvoke; - if (props.onlyGrantLatestVersion) { - resouceArns = [this.functionArn]; + let resouceArns = [`${this.functionArn}:${version.version}`]; + if (version == this.latestVersion) { + resouceArns = [this.functionArn, `${this.functionArn}:$LATEST`]; } grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', resouceArns); this._invocationGrants[identifier] = grant; diff --git a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts index 355429e7d26a3..4ab5fb204f9d9 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts @@ -1282,7 +1282,7 @@ describe('function', () => { }); }); - test('adds iam:InvokeFunction with onlyGrantLatestVersion', () => { + test('adds grantInvokeLatestVersion ', () => { // GIVEN const stack = new cdk.Stack(); const role = new iam.Role(stack, 'Role', { @@ -1295,7 +1295,7 @@ describe('function', () => { }); // WHEN - fn.grantInvoke(role, { onlyGrantLatestVersion: true }); + fn.grantInvokeLatestVersion(role); // THEN Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { @@ -1305,7 +1305,43 @@ describe('function', () => { { Action: 'lambda:InvokeFunction', Effect: 'Allow', - Resource: { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + Resource: [ + { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, + { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':$LATEST']] }, + ], + }, + ], + }, + }); + }); + + test('adds grantInvokeVersion ', () => { + // GIVEN + const stack = new cdk.Stack(); + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.AccountPrincipal('1234'), + }); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.fromInline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_LATEST, + }); + + const lv2 = new lambda.Version(stack, 'v2', { + lambda: fn, + }); + // WHEN + fn.grantInvokeVersion(role, lv2); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Action: 'lambda:InvokeFunction', + Effect: 'Allow', + Resource: { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':', { 'Fn::GetAtt': ['v248F3DDCC', 'Version'] }]] }, }, ], }, From c734032113f2399eac136e3f49faa2bec30fe2a8 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Fri, 3 May 2024 01:29:52 +0000 Subject: [PATCH 10/16] add grantInvokeLatestVersion --- packages/aws-cdk-lib/aws-lambda/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index e77dc0b7fa9d9..59b47eb284c5d 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -207,9 +207,9 @@ that accesses the function or layer). ```ts declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); -declare const version: lambda.IVersion; -// Grant invoke only to latest version -fn.grantInvokeVersion(principal, version); +// Grant invoke only to latest version and unqualified lambda arn +fn.grantInvokeLatestVersion(principal); + ``` If you want to grant access for invoking a specific version of Lambda function, you can use `fn.grantInovkeVersion(grantee, version)` @@ -217,8 +217,9 @@ If you want to grant access for invoking a specific version of Lambda function, ```ts declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); -// Grant invoke only to latest version -fn.grantInvokeLatestVersion(principal); +declare const version: lambda.IVersion; +// Grant invoke only to the specific version +fn.grantInvokeVersion(principal, version); ``` For more information, see From f4b873f759db6838b508d2733e89b1ef6767bd6a Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Fri, 3 May 2024 22:28:36 +0000 Subject: [PATCH 11/16] fix lint --- .../framework-integ/test/aws-lambda/test/integ.permissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts index 4a57ca80d94ec..eb9a9792e3e6a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts @@ -22,7 +22,7 @@ fn.grantInvokeLatestVersion(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2 fn.grantInvokeLatestVersion(new iam.OrganizationPrincipal('o-xxxxxxxxxx2')); const version1 = new lambda.Version(stack, 'v1', { - lambda: fn + lambda: fn, }); fn.grantInvokeVersion(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'), version1); From a7b2b36d3f6b3702f5c3234ef1d2fc1d02e24640 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Fri, 3 May 2024 23:29:38 +0000 Subject: [PATCH 12/16] fix integ --- .../lambda-permissions.assets.json | 4 ++-- .../lambda-permissions.template.json | 4 ++-- .../test/integ.permissions.js.snapshot/manifest.json | 10 +++++----- .../test/integ.permissions.js.snapshot/tree.json | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json index 69073756cdbd4..ecb09fc7a5b6c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "7bb46ab3ee8f5a5ea32ecdb2339294d95acaf255531ed2a40e8e845f4104bce6": { + "65bd4647d6fbc45a6dd9e138bf67e3e8dac09d64a3964095fd6da7a9bfa743ff": { "source": { "path": "lambda-permissions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "7bb46ab3ee8f5a5ea32ecdb2339294d95acaf255531ed2a40e8e845f4104bce6.json", + "objectKey": "65bd4647d6fbc45a6dd9e138bf67e3e8dac09d64a3964095fd6da7a9bfa743ff.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json index 6fd033b4bb135..52b679eff1f50 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json @@ -106,7 +106,7 @@ "PrincipalOrgID": "o-xxxxxxxxxx2" } }, - "MyLambdaInvokeeSO2bF2vs89Bu95ZGbotCaJ9349433GggVuY4yuDDo6A19947D": { + "MyLambdaInvokeuz4W2yTbGThmvdaaDTPvZaj4QwgyGHVAJ0384HNZc259082DE": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -120,7 +120,7 @@ "PrincipalOrgID": "o-yyyyyyyyyy2" } }, - "MyLambdaInvokevlkDSBAbWHnqhYUcxXc8dNNBhmEU5NTv6gX4EMtBA9DCAF0DD": { + "MyLambdaInvokePaKsdYKGi1vlRPtO5abSuPlD732bbpd4pyJuWGZToQ4C024630": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json index e6f10bfc200a1..cd1c7e025170a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7bb46ab3ee8f5a5ea32ecdb2339294d95acaf255531ed2a40e8e845f4104bce6.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/65bd4647d6fbc45a6dd9e138bf67e3e8dac09d64a3964095fd6da7a9bfa743ff.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -70,16 +70,16 @@ "data": "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4" } ], - "/lambda-permissions/MyLambda/InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=": [ + "/lambda-permissions/MyLambda/Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeeSO2bF2vs89Bu95ZGbotCaJ9349433GggVuY4yuDDo6A19947D" + "data": "MyLambdaInvokeuz4W2yTbGThmvdaaDTPvZaj4QwgyGHVAJ0384HNZc259082DE" } ], - "/lambda-permissions/MyLambda/Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=": [ + "/lambda-permissions/MyLambda/InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokevlkDSBAbWHnqhYUcxXc8dNNBhmEU5NTv6gX4EMtBA9DCAF0DD" + "data": "MyLambdaInvokePaKsdYKGi1vlRPtO5abSuPlD732bbpd4pyJuWGZToQ4C024630" } ], "/lambda-permissions/MyLambda/FunctionUrl/Resource": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json index 52035017690f2..fd0425577e199 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json @@ -189,9 +189,9 @@ "version": "0.0.0" } }, - "InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=": { - "id": "InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=", - "path": "lambda-permissions/MyLambda/InvokeeSO2bF2vs89Bu95ZGbotCaJ9349433Gg+gVuY4yuDDo=", + "Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=": { + "id": "Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=", + "path": "lambda-permissions/MyLambda/Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", "aws:cdk:cloudformation:props": { @@ -211,9 +211,9 @@ "version": "0.0.0" } }, - "Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=": { - "id": "Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=", - "path": "lambda-permissions/MyLambda/Invokev--lkDSBAbWHnqhYUcxXc8d+NNBhmEU5NTv6gX4EMtBA=", + "InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=": { + "id": "InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=", + "path": "lambda-permissions/MyLambda/InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", "aws:cdk:cloudformation:props": { From 2e601741ffaa1869767a655ca9162438c4131762 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Mon, 6 May 2024 21:11:13 +0000 Subject: [PATCH 13/16] revert to original snapshot --- .../integ.permissions.js.snapshot/cdk.out | 2 +- .../integ.permissions.js.snapshot/integ.json | 2 +- .../lambda-permissions.assets.json | 6 +- .../lambda-permissions.template.json | 424 ++++++++---------- .../manifest.json | 43 +- .../integ.permissions.js.snapshot/tree.json | 204 ++------- .../test/aws-lambda/test/integ.permissions.ts | 14 +- 7 files changed, 238 insertions(+), 457 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out index 1f0068d32659a..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"36.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json index cdd86e13c9071..4c852f34a8d7b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "34.0.0", "testCases": { "integ.permissions": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json index ecb09fc7a5b6c..0fd8578c0072d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.0", + "version": "34.0.0", "files": { - "65bd4647d6fbc45a6dd9e138bf67e3e8dac09d64a3964095fd6da7a9bfa743ff": { + "4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341": { "source": { "path": "lambda-permissions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "65bd4647d6fbc45a6dd9e138bf67e3e8dac09d64a3964095fd6da7a9bfa743ff.json", + "objectKey": "4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json index 52b679eff1f50..02c5159a0d3a3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json @@ -1,262 +1,198 @@ { - "Resources": { - "MyLambdaServiceRole4539ECB6": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", + "Resources": { + "MyLambdaServiceRole4539ECB6": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } ] + } + }, + "MyLambdaCCE802FB": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyLambdaServiceRole4539ECB6", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "MyLambdaServiceRole4539ECB6" ] - } - ] - } - }, - "MyLambdaCCE802FB": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "foo" - }, - "Handler": "index.handler", - "Role": { - "Fn::GetAtt": [ - "MyLambdaServiceRole4539ECB6", - "Arn" - ] - }, - "Runtime": "nodejs18.x" - }, - "DependsOn": [ - "MyLambdaServiceRole4539ECB6" - ] - }, - "MyLambdaInvokehlab6Vr41INt1IUXIhhCesB4gzNedP5IURKNgciwD9D5EABD": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-yyyyyyyyyy" - } - }, - "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-xxxxxxxxxx" - } - }, - "MyLambdaInvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgpnic82377EF6": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-yyyyyyyyyy2" - } - }, - "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-xxxxxxxxxx2" - } - }, - "MyLambdaInvokeuz4W2yTbGThmvdaaDTPvZaj4QwgyGHVAJ0384HNZc259082DE": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-yyyyyyyyyy2" - } - }, - "MyLambdaInvokePaKsdYKGi1vlRPtO5abSuPlD732bbpd4pyJuWGZToQ4C024630": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-xxxxxxxxxx2" - } - }, - "MyLambdaFunctionUrlC2055677": { - "Type": "AWS::Lambda::Url", - "Properties": { - "AuthType": "AWS_IAM", - "TargetFunctionArn": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - } - } - }, - "MyLambdaInvokeSz2P2C4jOiX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM7C8BE4B5": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-mmmmmmmmmm" - } - }, - "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "apigateway.amazonaws.com" - } - }, - "v192FF9954": { - "Type": "AWS::Lambda::Version", - "Properties": { - "FunctionName": { - "Ref": "MyLambdaCCE802FB" - } - } - }, - "MyRoleF48FFE04": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" + }, + "MyLambdaInvokehlab6Vr41INt1IUXIhhCesB4gzNedP5IURKNgciwD9D5EABD": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-yyyyyyyyyy" + } + }, + "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-xxxxxxxxxx" + } + }, + "MyLambdaFunctionUrlC2055677": { + "Type": "AWS::Lambda::Url", + "Properties": { + "AuthType": "AWS_IAM", + "TargetFunctionArn": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] } } - ], - "Version": "2012-10-17" - } - } - }, - "MyRoleDefaultPolicyA36BE1DD": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "lambda:InvokeFunctionUrl", - "Effect": "Allow", - "Resource": { + }, + "MyLambdaInvokeSz2P2C4jOiX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM7C8BE4B5": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { "Fn::GetAtt": [ "MyLambdaCCE802FB", "Arn" ] + }, + "Principal": "*", + "PrincipalOrgID": "o-mmmmmmmmmm" + } + }, + "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "apigateway.amazonaws.com" + } + }, + "MyRoleF48FFE04": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" } } - ], - "Version": "2012-10-17" + }, + "MyRoleDefaultPolicyA36BE1DD": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunctionUrl", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyRoleDefaultPolicyA36BE1DD", + "Roles": [ + { + "Ref": "MyRoleF48FFE04" + } + ] + } + } }, - "PolicyName": "MyRoleDefaultPolicyA36BE1DD", - "Roles": [ - { - "Ref": "MyRoleF48FFE04" + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } - ] - } - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." } ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } } - ] - } - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json index cd1c7e025170a..da8aab0b10e64 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "34.0.0", "artifacts": { "lambda-permissions.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/65bd4647d6fbc45a6dd9e138bf67e3e8dac09d64a3964095fd6da7a9bfa743ff.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -58,30 +58,6 @@ "data": "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8" } ], - "/lambda-permissions/MyLambda/InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgpnic82377EF6" - } - ], - "/lambda-permissions/MyLambda/InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4" - } - ], - "/lambda-permissions/MyLambda/Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokeuz4W2yTbGThmvdaaDTPvZaj4QwgyGHVAJ0384HNZc259082DE" - } - ], - "/lambda-permissions/MyLambda/InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokePaKsdYKGi1vlRPtO5abSuPlD732bbpd4pyJuWGZToQ4C024630" - } - ], "/lambda-permissions/MyLambda/FunctionUrl/Resource": [ { "type": "aws:cdk:logicalId", @@ -100,12 +76,6 @@ "data": "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58" } ], - "/lambda-permissions/v1/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "v192FF9954" - } - ], "/lambda-permissions/MyRole/Resource": [ { "type": "aws:cdk:logicalId", @@ -129,6 +99,15 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } + ], + "MyLambdaInvokemcfVL7pJA0SB0Bm8yGhELN3cZ1c8fYqVoNxjNP4pYCE95D85164": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaInvokemcfVL7pJA0SB0Bm8yGhELN3cZ1c8fYqVoNxjNP4pYCE95D85164", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } ] }, "displayName": "lambda-permissions" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json index fd0425577e199..2fdf6450ac79c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json @@ -20,8 +20,8 @@ "id": "ImportServiceRole", "path": "lambda-permissions/MyLambda/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Resource": { @@ -59,14 +59,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Resource": { @@ -89,8 +89,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Invokehl--ab6+Vr41INt1IUX--IhhCesB4gzNedP5IURKNgciw=": { @@ -111,8 +111,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Invoke138AF9IJcZORjZ--NKCKShZMMuVQwCnUkbFqMoQf5of0=": { @@ -133,104 +133,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" - } - }, - "$LATEST": { - "id": "$LATEST", - "path": "lambda-permissions/MyLambda/$LATEST", - "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" - } - }, - "InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=": { - "id": "InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=", - "path": "lambda-permissions/MyLambda/InvokeeGvYElS6PTHSMTWuZJGucRJGsEgHU9SwyLyJrgp--nic=", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", - "aws:cdk:cloudformation:props": { - "action": "lambda:InvokeFunction", - "functionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "principal": "*", - "principalOrgId": "o-yyyyyyyyyy2" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" - } - }, - "InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=": { - "id": "InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=", - "path": "lambda-permissions/MyLambda/InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", - "aws:cdk:cloudformation:props": { - "action": "lambda:InvokeFunction", - "functionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "principal": "*", - "principalOrgId": "o-xxxxxxxxxx2" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" - } - }, - "Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=": { - "id": "Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=", - "path": "lambda-permissions/MyLambda/Invokeuz4W2yT--bGThmvdaaDTPv--Zaj4QwgyGHVAJ0384HNZc=", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", - "aws:cdk:cloudformation:props": { - "action": "lambda:InvokeFunction", - "functionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "principal": "*", - "principalOrgId": "o-yyyyyyyyyy2" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" - } - }, - "InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=": { - "id": "InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=", - "path": "lambda-permissions/MyLambda/InvokePaKsdYKGi1vlRPtO5abSuPlD--732bbpd4pyJuWGZToQ=", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", - "aws:cdk:cloudformation:props": { - "action": "lambda:InvokeFunction", - "functionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "principal": "*", - "principalOrgId": "o-xxxxxxxxxx2" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "FunctionUrl": { @@ -253,14 +157,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnUrl", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.FunctionUrl", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "InvokeSz2P2C4jO--iX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM=": { @@ -281,8 +185,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "InvokeFcyXBRX02EWa52GlF+ECQiCzDt0fdRUDi4mo4foC5aU=": { @@ -302,40 +206,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" - } - }, - "v1": { - "id": "v1", - "path": "lambda-permissions/v1", - "children": { - "Resource": { - "id": "Resource", - "path": "lambda-permissions/v1/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Version", - "aws:cdk:cloudformation:props": { - "functionName": { - "Ref": "MyLambdaCCE802FB" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnVersion", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Version", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "MyRole": { @@ -346,8 +224,8 @@ "id": "ImportMyRole", "path": "lambda-permissions/MyRole/ImportMyRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Resource": { @@ -371,8 +249,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "DefaultPolicy": { @@ -409,42 +287,42 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "lambda-permissions/BootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "lambda-permissions/CheckBootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } }, "Tree": { @@ -452,13 +330,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.App", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.70" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts index eb9a9792e3e6a..fe0a455409b3e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts @@ -17,18 +17,6 @@ fn.grantInvoke(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy')); fn.grantInvoke(new iam.OrganizationPrincipal('o-xxxxxxxxxx')); -fn.grantInvokeLatestVersion(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2')); - -fn.grantInvokeLatestVersion(new iam.OrganizationPrincipal('o-xxxxxxxxxx2')); - -const version1 = new lambda.Version(stack, 'v1', { - lambda: fn, -}); - -fn.grantInvokeVersion(new iam.AnyPrincipal().inOrganization('o-yyyyyyyyyy2'), version1); - -fn.grantInvokeVersion(new iam.OrganizationPrincipal('o-xxxxxxxxxx2'), version1); - const fnUrl = fn.addFunctionUrl(); const role = new iam.Role(stack, 'MyRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), @@ -38,4 +26,4 @@ fnUrl.grantInvokeUrl(role); fn.grantInvokeCompositePrincipal(new iam.CompositePrincipal( new iam.OrganizationPrincipal('o-mmmmmmmmmm'), new iam.ServicePrincipal('apigateway.amazonaws.com'), -)); +)); \ No newline at end of file From 36ee9a9a091eaf1121fa6f5a16e89826735c8b57 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Mon, 6 May 2024 22:38:47 +0000 Subject: [PATCH 14/16] fix integ test --- .../integ.permissions.js.snapshot/cdk.out | 2 +- .../integ.permissions.js.snapshot/integ.json | 2 +- .../lambda-permissions.assets.json | 6 +- .../lambda-permissions.template.json | 422 ++++++++++-------- .../manifest.json | 25 +- .../integ.permissions.js.snapshot/tree.json | 184 ++++++-- .../test/aws-lambda/test/integ.permissions.ts | 12 +- 7 files changed, 418 insertions(+), 235 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out index 2313ab5436501..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"34.0.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json index 4c852f34a8d7b..cdd86e13c9071 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "testCases": { "integ.permissions": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json index 0fd8578c0072d..abdbf49cb5e70 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.assets.json @@ -1,7 +1,7 @@ { - "version": "34.0.0", + "version": "36.0.0", "files": { - "4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341": { + "1a743b710c7ecd428918f2c36c87ccee4561ad5e3b7ea92c07269338e7baaddf": { "source": { "path": "lambda-permissions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341.json", + "objectKey": "1a743b710c7ecd428918f2c36c87ccee4561ad5e3b7ea92c07269338e7baaddf.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json index 02c5159a0d3a3..2cee179bb72dd 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/lambda-permissions.template.json @@ -1,198 +1,266 @@ { - "Resources": { - "MyLambdaServiceRole4539ECB6": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ + "Resources": { + "MyLambdaServiceRole4539ECB6": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] - } - }, - "MyLambdaCCE802FB": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "foo" - }, - "Handler": "index.handler", - "Role": { - "Fn::GetAtt": [ - "MyLambdaServiceRole4539ECB6", - "Arn" - ] - }, - "Runtime": "nodejs18.x" - }, - "DependsOn": [ - "MyLambdaServiceRole4539ECB6" ] - }, - "MyLambdaInvokehlab6Vr41INt1IUXIhhCesB4gzNedP5IURKNgciwD9D5EABD": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-yyyyyyyyyy" - } - }, - "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-xxxxxxxxxx" - } - }, - "MyLambdaFunctionUrlC2055677": { - "Type": "AWS::Lambda::Url", - "Properties": { - "AuthType": "AWS_IAM", - "TargetFunctionArn": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] + } + ] + } + }, + "MyLambdaCCE802FB": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyLambdaServiceRole4539ECB6", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "MyLambdaServiceRole4539ECB6" + ] + }, + "MyLambdaInvokehlab6Vr41INt1IUXIhhCesB4gzNedP5IURKNgciwD9D5EABD": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-yyyyyyyyyy" + } + }, + "MyLambdaInvoke138AF9IJcZORjZNKCKShZMMuVQwCnUkbFqMoQf5of0C1F7DFD8": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-xxxxxxxxxx" + } + }, + "MyLambdaFunctionUrlC2055677": { + "Type": "AWS::Lambda::Url", + "Properties": { + "AuthType": "AWS_IAM", + "TargetFunctionArn": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + } + } + }, + "MyLambdaInvokeSz2P2C4jOiX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM7C8BE4B5": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-mmmmmmmmmm" + } + }, + "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "apigateway.amazonaws.com" + } + }, + "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "Principal": "*", + "PrincipalOrgID": "o-xxxxxxxxxx2" + } + }, + "MyRoleF48FFE04": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" } } - }, - "MyLambdaInvokeSz2P2C4jOiX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM7C8BE4B5": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - }, - "Principal": "*", - "PrincipalOrgID": "o-mmmmmmmmmm" - } - }, - "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:InvokeFunction", - "FunctionName": { + ], + "Version": "2012-10-17" + } + } + }, + "MyRoleDefaultPolicyA36BE1DD": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunctionUrl", + "Effect": "Allow", + "Resource": { "Fn::GetAtt": [ "MyLambdaCCE802FB", "Arn" ] - }, - "Principal": "apigateway.amazonaws.com" - } - }, - "MyRoleF48FFE04": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" } - } - }, - "MyRoleDefaultPolicyA36BE1DD": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "lambda:InvokeFunctionUrl", - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "MyLambdaCCE802FB", - "Arn" - ] - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "MyRoleDefaultPolicyA36BE1DD", - "Roles": [ + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ { - "Ref": "MyRoleF48FFE04" + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + ":", + { + "Fn::GetAtt": [ + "v192FF9954", + "Version" + ] + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + ":$LATEST" + ] + ] } ] } - } + ], + "Version": "2012-10-17" }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + "PolicyName": "MyRoleDefaultPolicyA36BE1DD", + "Roles": [ + { + "Ref": "MyRoleF48FFE04" } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ + ] + } + }, + "v192FF9954": { + "Type": "AWS::Lambda::Version", + "Properties": { + "FunctionName": { + "Ref": "MyLambdaCCE802FB" + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] } ] - } + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." } - } \ No newline at end of file + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json index da8aab0b10e64..84a86c8091c44 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "artifacts": { "lambda-permissions.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4a7337dac9cfd962c6206c10044011cbcfe4c604459c5eada3df438eb578f341.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1a743b710c7ecd428918f2c36c87ccee4561ad5e3b7ea92c07269338e7baaddf.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -76,6 +76,12 @@ "data": "MyLambdaInvokeFcyXBRX02EWa52GlFECQiCzDt0fdRUDi4mo4foC5aU41318F58" } ], + "/lambda-permissions/MyLambda/InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLambdaInvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPIBE1EB3A4" + } + ], "/lambda-permissions/MyRole/Resource": [ { "type": "aws:cdk:logicalId", @@ -88,25 +94,22 @@ "data": "MyRoleDefaultPolicyA36BE1DD" } ], - "/lambda-permissions/BootstrapVersion": [ + "/lambda-permissions/v1/Resource": [ { "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" + "data": "v192FF9954" } ], - "/lambda-permissions/CheckBootstrapVersion": [ + "/lambda-permissions/BootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" + "data": "BootstrapVersion" } ], - "MyLambdaInvokemcfVL7pJA0SB0Bm8yGhELN3cZ1c8fYqVoNxjNP4pYCE95D85164": [ + "/lambda-permissions/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "MyLambdaInvokemcfVL7pJA0SB0Bm8yGhELN3cZ1c8fYqVoNxjNP4pYCE95D85164", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "CheckBootstrapVersion" } ] }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json index 2fdf6450ac79c..7687019e6dfa4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.js.snapshot/tree.json @@ -20,8 +20,8 @@ "id": "ImportServiceRole", "path": "lambda-permissions/MyLambda/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "Resource": { @@ -59,14 +59,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" } }, "Resource": { @@ -89,8 +89,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" } }, "Invokehl--ab6+Vr41INt1IUX--IhhCesB4gzNedP5IURKNgciw=": { @@ -111,8 +111,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "Invoke138AF9IJcZORjZ--NKCKShZMMuVQwCnUkbFqMoQf5of0=": { @@ -133,8 +133,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "FunctionUrl": { @@ -157,14 +157,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnUrl", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.FunctionUrl", + "version": "0.0.0" } }, "InvokeSz2P2C4jO--iX4AmIs1ANCq2qfq8PhgVeKtRAVyAkFmM=": { @@ -185,8 +185,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } }, "InvokeFcyXBRX02EWa52GlF+ECQiCzDt0fdRUDi4mo4foC5aU=": { @@ -206,14 +206,44 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + }, + "$LATEST": { + "id": "$LATEST", + "path": "lambda-permissions/MyLambda/$LATEST", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.FunctionBase", + "version": "0.0.0" + } + }, + "InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=": { + "id": "InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=", + "path": "lambda-permissions/MyLambda/InvokeZQDUzUWqDuiGYFrGB6ik9uIPJSgF8GSLIg6NTO8jHPI=", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + "principal": "*", + "principalOrgId": "o-xxxxxxxxxx2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" } }, "MyRole": { @@ -224,8 +254,8 @@ "id": "ImportMyRole", "path": "lambda-permissions/MyRole/ImportMyRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "Resource": { @@ -249,8 +279,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" } }, "DefaultPolicy": { @@ -274,6 +304,52 @@ "Arn" ] } + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + ":", + { + "Fn::GetAtt": [ + "v192FF9954", + "Version" + ] + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyLambdaCCE802FB", + "Arn" + ] + }, + ":$LATEST" + ] + ] + } + ] } ], "Version": "2012-10-17" @@ -287,42 +363,68 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "v1": { + "id": "v1", + "path": "lambda-permissions/v1", + "children": { + "Resource": { + "id": "Resource", + "path": "lambda-permissions/v1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Version", + "aws:cdk:cloudformation:props": { + "functionName": { + "Ref": "MyLambdaCCE802FB" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.CfnVersion", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.aws_lambda.Version", + "version": "0.0.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "lambda-permissions/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "lambda-permissions/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" } }, "Tree": { @@ -330,13 +432,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.70" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts index fe0a455409b3e..c987a5f12d07e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.permissions.ts @@ -26,4 +26,14 @@ fnUrl.grantInvokeUrl(role); fn.grantInvokeCompositePrincipal(new iam.CompositePrincipal( new iam.OrganizationPrincipal('o-mmmmmmmmmm'), new iam.ServicePrincipal('apigateway.amazonaws.com'), -)); \ No newline at end of file +)); + +fn.grantInvokeLatestVersion(role); + +fn.grantInvokeLatestVersion(new iam.OrganizationPrincipal('o-xxxxxxxxxx2')); + +const version1 = new lambda.Version(stack, 'v1', { + lambda: fn, +}); + +fn.grantInvokeVersion(role, version1); \ No newline at end of file From 7501abd8e1927252f4d242e3f83db85beaaa4962 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 26 Jun 2024 00:09:54 +0000 Subject: [PATCH 15/16] address comments --- packages/aws-cdk-lib/aws-lambda/README.md | 2 +- packages/aws-cdk-lib/aws-lambda/lib/function-base.ts | 4 ++-- packages/aws-cdk-lib/aws-lambda/test/function.test.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index d99ca5c8d7ad5..83384b195e8c5 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -216,7 +216,7 @@ fn.grantInvokeLatestVersion(principal); ``` -If you want to grant access for invoking a specific version of Lambda function, you can use `fn.grantInovkeVersion(grantee, version)` +If you want to grant access for invoking a specific version of Lambda function, you can use `fn.grantInvokeVersion(grantee, version)` ```ts declare const fn: lambda.Function; diff --git a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts index 93f658785a5b1..c7d0bf5b4c543 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/function-base.ts @@ -111,7 +111,7 @@ export interface IFunction extends IResource, ec2.IConnectable, iam.IGrantable { /** * Grant the given identity permissions to invoke this Lambda Function URL */ - grantInvokeUrl(grantee: iam.IGrantable): iam.Grant; + grantInvokeUrl(identity: iam.IGrantable): iam.Grant; /** * Grant multiple principals the ability to invoke this Lambda via CompositePrincipal @@ -476,7 +476,7 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC if (!grant) { let resouceArns = [`${this.functionArn}:${version.version}`]; if (version == this.latestVersion) { - resouceArns = [this.functionArn, `${this.functionArn}:$LATEST`]; + resouceArns.push(this.functionArn); } grant = this.grant(grantee, identifier, 'lambda:InvokeFunction', resouceArns); this._invocationGrants[identifier] = grant; diff --git a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts index 13fe3ceb74ac6..db2b73c2749b7 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts @@ -1333,8 +1333,8 @@ describe('function', () => { Action: 'lambda:InvokeFunction', Effect: 'Allow', Resource: [ - { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, { 'Fn::Join': ['', [{ 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ':$LATEST']] }, + { 'Fn::GetAtt': ['Function76856677', 'Arn'] }, ], }, ], From 734aae62885d10b35340959ad79d9f93f0fac03f Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 26 Jun 2024 00:51:08 +0000 Subject: [PATCH 16/16] add desc --- packages/aws-cdk-lib/aws-lambda/test/function.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts index db2b73c2749b7..f3ad8836102e5 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/function.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/function.test.ts @@ -1324,7 +1324,7 @@ describe('function', () => { // WHEN fn.grantInvokeLatestVersion(role); - // THEN + // THEN function should have allow on both unqualified arn and arn:$LATEST Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Version: '2012-10-17',