From fff9cf694b14811682c8671a1e55afa53151df8b Mon Sep 17 00:00:00 2001 From: Michael Sambol Date: Fri, 3 May 2024 17:59:02 -0600 Subject: [PATCH] fix(ecr): incorrect format for rule pattern (#29243) Closes #29225. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-ecr-integ-stack.assets.json | 6 +- .../aws-ecr-integ-stack.template.json | 111 +++++++- .../test/integ.basic.js.snapshot/cdk.out | 2 +- ...efaultTestDeployAssert4F7FBFB4.assets.json | 2 +- .../test/integ.basic.js.snapshot/integ.json | 2 +- .../integ.basic.js.snapshot/manifest.json | 42 ++- .../test/integ.basic.js.snapshot/tree.json | 259 +++++++++++++++--- .../test/aws-ecr/test/integ.basic.ts | 15 +- packages/aws-cdk-lib/aws-ecr/README.md | 20 ++ .../aws-cdk-lib/aws-ecr/lib/repository.ts | 4 +- .../aws-ecr/test/repository.test.ts | 27 ++ 11 files changed, 436 insertions(+), 54 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json index b1ebebaa8af67..4c3e52290d817 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.assets.json @@ -1,7 +1,7 @@ { - "version": "35.0.0", + "version": "36.0.0", "files": { - "830646461dc1fed84d30409177199864dfe0b167864b2fcdca22f4b9aad8a063": { + "2a0c9ab351877403efca7490b5ac5c6c52cc4738e9f7e5ec7c38fb974a3aba7b": { "source": { "path": "aws-ecr-integ-stack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "830646461dc1fed84d30409177199864dfe0b167864b2fcdca22f4b9aad8a063.json", + "objectKey": "2a0c9ab351877403efca7490b5ac5c6c52cc4738e9f7e5ec7c38fb974a3aba7b.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-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json index ed4ac96c9385e..f965c47d2b1aa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/aws-ecr-integ-stack.template.json @@ -22,10 +22,10 @@ "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "MyUserDC45028B": { + "MyIamUser046086A4": { "Type": "AWS::IAM::User" }, - "MyUserDefaultPolicy7B897426": { + "MyIamUserDefaultPolicy4B9C0A95": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -58,10 +58,10 @@ ], "Version": "2012-10-17" }, - "PolicyName": "MyUserDefaultPolicy7B897426", + "PolicyName": "MyIamUserDefaultPolicy4B9C0A95", "Users": [ { - "Ref": "MyUserDC45028B" + "Ref": "MyIamUser046086A4" } ] } @@ -73,6 +73,109 @@ }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "RepoOnEvent13B6ADDB": { + "Type": "AWS::ECR::Repository", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "RepoOnEventOnEventTargetLambda2934FA99": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventPattern": { + "source": [ + "aws.ecr" + ], + "detail": { + "repository-name": [ + { + "Ref": "RepoOnEvent13B6ADDB" + } + ] + } + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "Id": "Target0" + } + ] + } + }, + "RepoOnEventOnEventTargetLambdaAllowEventRuleawsecrintegstackLambdaFunctionB6045AA7FBA3AA33": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "Principal": "events.amazonaws.com", + "SourceArn": { + "Fn::GetAtt": [ + "RepoOnEventOnEventTargetLambda2934FA99", + "Arn" + ] + } + } + }, + "LambdaFunctionServiceRoleC555A460": { + "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:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "# dummy func" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRoleC555A460", + "Arn" + ] + }, + "Runtime": "python3.12" + }, + "DependsOn": [ + "LambdaFunctionServiceRoleC555A460" + ] } }, "Outputs": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out index c5cb2e5de6344..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"35.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-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json index 4a4a176d22fed..eaa4d77f5282d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/cdkecrintegtestbasicDefaultTestDeployAssert4F7FBFB4.assets.json @@ -1,5 +1,5 @@ { - "version": "35.0.0", + "version": "36.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json index 530efded1be3b..2144156a73f14 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "35.0.0", + "version": "36.0.0", "testCases": { "cdk-ecr-integ-test-basic/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json index f53c26891f1ed..a623c9ce25e64 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "35.0.0", + "version": "36.0.0", "artifacts": { "aws-ecr-integ-stack.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}/830646461dc1fed84d30409177199864dfe0b167864b2fcdca22f4b9aad8a063.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2a0c9ab351877403efca7490b5ac5c6c52cc4738e9f7e5ec7c38fb974a3aba7b.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -40,16 +40,16 @@ "data": "Repo02AC86CF" } ], - "/aws-ecr-integ-stack/MyUser/Resource": [ + "/aws-ecr-integ-stack/MyIamUser/Resource": [ { "type": "aws:cdk:logicalId", - "data": "MyUserDC45028B" + "data": "MyIamUser046086A4" } ], - "/aws-ecr-integ-stack/MyUser/DefaultPolicy/Resource": [ + "/aws-ecr-integ-stack/MyIamUser/DefaultPolicy/Resource": [ { "type": "aws:cdk:logicalId", - "data": "MyUserDefaultPolicy7B897426" + "data": "MyIamUserDefaultPolicy4B9C0A95" } ], "/aws-ecr-integ-stack/RepoWithEmptyOnDelete/Resource": [ @@ -64,6 +64,36 @@ "data": "RepositoryURI" } ], + "/aws-ecr-integ-stack/RepoOnEvent/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RepoOnEvent13B6ADDB" + } + ], + "/aws-ecr-integ-stack/RepoOnEvent/OnEventTargetLambda/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RepoOnEventOnEventTargetLambda2934FA99" + } + ], + "/aws-ecr-integ-stack/RepoOnEvent/OnEventTargetLambda/AllowEventRuleawsecrintegstackLambdaFunctionB6045AA7": [ + { + "type": "aws:cdk:logicalId", + "data": "RepoOnEventOnEventTargetLambdaAllowEventRuleawsecrintegstackLambdaFunctionB6045AA7FBA3AA33" + } + ], + "/aws-ecr-integ-stack/LambdaFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaFunctionServiceRoleC555A460" + } + ], + "/aws-ecr-integ-stack/LambdaFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaFunctionBF21E41F" + } + ], "/aws-ecr-integ-stack/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json index 53559b0722b55..563c239e24991 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.js.snapshot/tree.json @@ -36,39 +36,39 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.aws_ecr.CfnRepository", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.aws_ecr.Repository", + "version": "0.0.0" } }, - "MyUser": { - "id": "MyUser", - "path": "aws-ecr-integ-stack/MyUser", + "MyIamUser": { + "id": "MyIamUser", + "path": "aws-ecr-integ-stack/MyIamUser", "children": { "Resource": { "id": "Resource", - "path": "aws-ecr-integ-stack/MyUser/Resource", + "path": "aws-ecr-integ-stack/MyIamUser/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::IAM::User", "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.aws_iam.CfnUser", + "version": "0.0.0" } }, "DefaultPolicy": { "id": "DefaultPolicy", - "path": "aws-ecr-integ-stack/MyUser/DefaultPolicy", + "path": "aws-ecr-integ-stack/MyIamUser/DefaultPolicy", "children": { "Resource": { "id": "Resource", - "path": "aws-ecr-integ-stack/MyUser/DefaultPolicy/Resource", + "path": "aws-ecr-integ-stack/MyIamUser/DefaultPolicy/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::IAM::Policy", "aws:cdk:cloudformation:props": { @@ -102,29 +102,29 @@ ], "Version": "2012-10-17" }, - "policyName": "MyUserDefaultPolicy7B897426", + "policyName": "MyIamUserDefaultPolicy4B9C0A95", "users": [ { - "Ref": "MyUserDC45028B" + "Ref": "MyIamUser046086A4" } ] } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.aws_iam.User", + "version": "0.0.0" } }, "RepoWithEmptyOnDelete": { @@ -155,30 +155,217 @@ "id": "RepositoryURI", "path": "aws-ecr-integ-stack/RepositoryURI", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "RepoOnEvent": { + "id": "RepoOnEvent", + "path": "aws-ecr-integ-stack/RepoOnEvent", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-ecr-integ-stack/RepoOnEvent/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ECR::Repository", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecr.CfnRepository", + "version": "0.0.0" + } + }, + "OnEventTargetLambda": { + "id": "OnEventTargetLambda", + "path": "aws-ecr-integ-stack/RepoOnEvent/OnEventTargetLambda", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-ecr-integ-stack/RepoOnEvent/OnEventTargetLambda/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Events::Rule", + "aws:cdk:cloudformation:props": { + "eventPattern": { + "source": [ + "aws.ecr" + ], + "detail": { + "repository-name": [ + { + "Ref": "RepoOnEvent13B6ADDB" + } + ] + } + }, + "state": "ENABLED", + "targets": [ + { + "id": "Target0", + "arn": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_events.CfnRule", + "version": "0.0.0" + } + }, + "AllowEventRuleawsecrintegstackLambdaFunctionB6045AA7": { + "id": "AllowEventRuleawsecrintegstackLambdaFunctionB6045AA7", + "path": "aws-ecr-integ-stack/RepoOnEvent/OnEventTargetLambda/AllowEventRuleawsecrintegstackLambdaFunctionB6045AA7", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "principal": "events.amazonaws.com", + "sourceArn": { + "Fn::GetAtt": [ + "RepoOnEventOnEventTargetLambda2934FA99", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_events.Rule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecr.Repository", + "version": "0.0.0" + } + }, + "LambdaFunction": { + "id": "LambdaFunction", + "path": "aws-ecr-integ-stack/LambdaFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-ecr-integ-stack/LambdaFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-ecr-integ-stack/LambdaFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecr-integ-stack/LambdaFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecr-integ-stack/LambdaFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "# dummy func" + }, + "handler": "index.handler", + "role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRoleC555A460", + "Arn" + ] + }, + "runtime": "python3.12" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "aws-ecr-integ-stack/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "aws-ecr-integ-stack/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" } }, "cdk-ecr-integ-test-basic": { @@ -205,22 +392,22 @@ "id": "BootstrapVersion", "path": "cdk-ecr-integ-test-basic/DefaultTest/DeployAssert/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "cdk-ecr-integ-test-basic/DefaultTest/DeployAssert/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" } } }, @@ -245,8 +432,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" + "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-ecr/test/integ.basic.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts index 199c1d7f152ae..a357c581f8ae6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.basic.ts @@ -2,6 +2,8 @@ import * as cdk from 'aws-cdk-lib'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; import * as ecr from 'aws-cdk-lib/aws-ecr'; import * as iam from 'aws-cdk-lib/aws-iam'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; +import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecr-integ-stack'); @@ -15,7 +17,7 @@ repo.addToResourcePolicy(new iam.PolicyStatement({ principals: [new iam.AnyPrincipal()], })); -const user = new iam.User(stack, 'MyUser'); +const user = new iam.User(stack, 'MyIamUser'); repo.grantRead(user); repo.grantPullPush(user); @@ -28,6 +30,17 @@ new cdk.CfnOutput(stack, 'RepositoryURI', { value: repo.repositoryUri, }); +const repoOnEvent = new ecr.Repository(stack, 'RepoOnEvent'); +const lambdaHandler = new lambda.Function(stack, 'LambdaFunction', { + runtime: lambda.Runtime.PYTHON_3_12, + code: lambda.Code.fromInline('# dummy func'), + handler: 'index.handler', +}); + +repoOnEvent.onEvent('OnEventTargetLambda', { + target: new LambdaFunction(lambdaHandler), +}); + new IntegTest(app, 'cdk-ecr-integ-test-basic', { testCases: [stack], }); diff --git a/packages/aws-cdk-lib/aws-ecr/README.md b/packages/aws-cdk-lib/aws-ecr/README.md index bba3db8e0ac27..d0ff9fc16cc35 100644 --- a/packages/aws-cdk-lib/aws-ecr/README.md +++ b/packages/aws-cdk-lib/aws-ecr/README.md @@ -208,3 +208,23 @@ repository.addToResourcePolicy(new iam.PolicyStatement({ principals: [new iam.AnyPrincipal()], })); ``` + +## CloudWatch event rules + +You can publish repository events to a CloudWatch event rule with `onEvent`: + +```ts +import * as lambda from 'aws-cdk-lib/aws-lambda'; +import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets'; + +const repo = new ecr.Repository(this, 'Repo'); +const lambdaHandler = new lambda.Function(this, 'LambdaFunction', { + runtime: lambda.Runtime.PYTHON_3_12, + code: lambda.Code.fromInline('# dummy func'), + handler: 'index.handler', +}); + +repo.onEvent('OnEventTargetLambda', { + target: new LambdaFunction(lambdaHandler), +}); +``` diff --git a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts index 720bf9002331c..f86b2d11b5b9f 100644 --- a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts +++ b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts @@ -317,7 +317,9 @@ export abstract class RepositoryBase extends Resource implements IRepository { const rule = new events.Rule(this, id, options); rule.addEventPattern({ source: ['aws.ecr'], - resources: [this.repositoryArn], + detail: { + 'repository-name': [this.repositoryName], + }, }); rule.addTarget(options.target); return rule; diff --git a/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts b/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts index 700a8e6ca8ea0..0c703ad7763da 100644 --- a/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts +++ b/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts @@ -980,6 +980,33 @@ describe('repository', () => { }, }); }); + + test('grant read adds appropriate permissions', () => { + // GIVEN + const stack = new cdk.Stack(); + const repo = new ecr.Repository(stack, 'TestRepo'); + + // WHEN + repo.onEvent('EcrOnEventRule', { + target: { + bind: () => ({ arn: 'ARN', id: '' }), + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { + 'EventPattern': { + 'source': [ + 'aws.ecr', + ], + 'detail': { + 'repository-name': [ + { 'Ref': 'TestRepo08D311A0' }, + ], + }, + }, + }); + }); }); describe('repository name validation', () => {