diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/cdk.out new file mode 100644 index 0000000000000..188478b55560e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"41.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/events-api-destination-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/events-api-destination-stack.assets.json new file mode 100644 index 0000000000000..b79d0b3ef5c08 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/events-api-destination-stack.assets.json @@ -0,0 +1,20 @@ +{ + "version": "41.0.0", + "files": { + "512a8bdfd70bd68811f6023967a2e87fa76600dfc24a6bda1fa2487a325e1aa2": { + "displayName": "events-api-destination-stack Template", + "source": { + "path": "events-api-destination-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "512a8bdfd70bd68811f6023967a2e87fa76600dfc24a6bda1fa2487a325e1aa2.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/events-api-destination-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/events-api-destination-stack.template.json new file mode 100644 index 0000000000000..6c241b698ca00 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/events-api-destination-stack.template.json @@ -0,0 +1,107 @@ +{ + "Resources": { + "SecretA720EF05": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "SecretString": "abc123" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Connection07624BCD": { + "Type": "AWS::Events::Connection", + "Properties": { + "AuthParameters": { + "ApiKeyAuthParameters": { + "ApiKeyName": "x-api-key", + "ApiKeyValue": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "SecretA720EF05" + }, + ":SecretString:::}}" + ] + ] + } + } + }, + "AuthorizationType": "API_KEY", + "Description": "Connection with API Key x-api-key", + "Name": "MyConnection" + } + }, + "DestinationApiDestinationA879FAE5": { + "Type": "AWS::Events::ApiDestination", + "Properties": { + "ConnectionArn": { + "Fn::GetAtt": [ + "Connection07624BCD", + "Arn" + ] + }, + "Description": "Calling example.com with API key x-api-key", + "HttpMethod": "GET", + "InvocationEndpoint": "https://httpbin.org/headers", + "InvocationRateLimitPerSecond": 1, + "Name": "MyDestination" + } + } + }, + "Outputs": { + "DestinationArn": { + "Description": "The ARN of the API destination", + "Value": { + "Fn::GetAtt": [ + "DestinationApiDestinationA879FAE5", + "Arn" + ] + } + }, + "DestinationArnForPolicy": { + "Description": "The ARN of the API destination in resource format", + "Value": { + "Fn::GetAtt": [ + "DestinationApiDestinationA879FAE5", + "ArnForPolicy" + ] + } + } + }, + "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": [ + { + "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 diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets.json new file mode 100644 index 0000000000000..eed58d3e2568e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets.json @@ -0,0 +1,20 @@ +{ + "version": "41.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "eventsapidestinationintegDefaultTestDeployAssert460ADA7C Template", + "source": { + "path": "eventsapidestinationintegDefaultTestDeployAssert460ADA7C.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/eventsapidestinationintegDefaultTestDeployAssert460ADA7C.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/eventsapidestinationintegDefaultTestDeployAssert460ADA7C.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/eventsapidestinationintegDefaultTestDeployAssert460ADA7C.template.json @@ -0,0 +1,36 @@ +{ + "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": [ + { + "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 diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/integ.json new file mode 100644 index 0000000000000..956d9f207c27f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "41.0.0", + "testCases": { + "events-api-destination-integ/DefaultTest": { + "stacks": [ + "events-api-destination-stack" + ], + "assertionStack": "events-api-destination-integ/DefaultTest/DeployAssert", + "assertionStackName": "eventsapidestinationintegDefaultTestDeployAssert460ADA7C" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/manifest.json new file mode 100644 index 0000000000000..c755154a1313d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/manifest.json @@ -0,0 +1,162 @@ +{ + "version": "42.0.0", + "artifacts": { + "events-api-destination-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "events-api-destination-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "events-api-destination-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "events-api-destination-stack.template.json", + "terminationProtection": false, + "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}/512a8bdfd70bd68811f6023967a2e87fa76600dfc24a6bda1fa2487a325e1aa2.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "events-api-destination-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "events-api-destination-stack.assets" + ], + "metadata": { + "/events-api-destination-stack/Secret": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "secretStringValue": "*" + } + } + ], + "/events-api-destination-stack/Secret/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "SecretA720EF05" + } + ], + "/events-api-destination-stack/Connection": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "authorization": "*", + "description": "*", + "connectionName": "*" + } + } + ], + "/events-api-destination-stack/Connection/Connection": [ + { + "type": "aws:cdk:logicalId", + "data": "Connection07624BCD" + } + ], + "/events-api-destination-stack/Destination": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + } + ], + "/events-api-destination-stack/Destination/ApiDestination": [ + { + "type": "aws:cdk:logicalId", + "data": "DestinationApiDestinationA879FAE5" + } + ], + "/events-api-destination-stack/DestinationArn": [ + { + "type": "aws:cdk:logicalId", + "data": "DestinationArn" + } + ], + "/events-api-destination-stack/DestinationArnForPolicy": [ + { + "type": "aws:cdk:logicalId", + "data": "DestinationArnForPolicy" + } + ], + "/events-api-destination-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/events-api-destination-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "events-api-destination-stack" + }, + "eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "eventsapidestinationintegDefaultTestDeployAssert460ADA7C": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "eventsapidestinationintegDefaultTestDeployAssert460ADA7C.template.json", + "terminationProtection": false, + "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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "eventsapidestinationintegDefaultTestDeployAssert460ADA7C.assets" + ], + "metadata": { + "/events-api-destination-integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/events-api-destination-integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "events-api-destination-integ/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + }, + "minimumCliVersion": "2.1006.0" +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/tree.json new file mode 100644 index 0000000000000..d695b66c1ad72 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","children":{"events-api-destination-stack":{"id":"events-api-destination-stack","path":"events-api-destination-stack","children":{"Secret":{"id":"Secret","path":"events-api-destination-stack/Secret","children":{"Resource":{"id":"Resource","path":"events-api-destination-stack/Secret/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::SecretsManager::Secret","aws:cdk:cloudformation:props":{"secretString":"abc123"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_secretsmanager.CfnSecret","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_secretsmanager.Secret","version":"0.0.0","metadata":[{"secretStringValue":"*"}]}},"Connection":{"id":"Connection","path":"events-api-destination-stack/Connection","children":{"Connection":{"id":"Connection","path":"events-api-destination-stack/Connection/Connection","attributes":{"aws:cdk:cloudformation:type":"AWS::Events::Connection","aws:cdk:cloudformation:props":{"authorizationType":"API_KEY","authParameters":{"apiKeyAuthParameters":{"apiKeyName":"x-api-key","apiKeyValue":{"Fn::Join":["",["{{resolve:secretsmanager:",{"Ref":"SecretA720EF05"},":SecretString:::}}"]]}}},"description":"Connection with API Key x-api-key","name":"MyConnection"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_events.CfnConnection","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_events.Connection","version":"0.0.0","metadata":[{"authorization":"*","description":"*","connectionName":"*"}]}},"Destination":{"id":"Destination","path":"events-api-destination-stack/Destination","children":{"ApiDestination":{"id":"ApiDestination","path":"events-api-destination-stack/Destination/ApiDestination","attributes":{"aws:cdk:cloudformation:type":"AWS::Events::ApiDestination","aws:cdk:cloudformation:props":{"connectionArn":{"Fn::GetAtt":["Connection07624BCD","Arn"]},"description":"Calling example.com with API key x-api-key","httpMethod":"GET","invocationEndpoint":"https://httpbin.org/headers","invocationRateLimitPerSecond":1,"name":"MyDestination"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_events.CfnApiDestination","version":"0.0.0"}}},"constructInfo":{"fqn":"constructs.Construct","version":"10.4.2","metadata":["*"]}},"DestinationArn":{"id":"DestinationArn","path":"events-api-destination-stack/DestinationArn","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DestinationArnForPolicy":{"id":"DestinationArnForPolicy","path":"events-api-destination-stack/DestinationArnForPolicy","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"BootstrapVersion":{"id":"BootstrapVersion","path":"events-api-destination-stack/BootstrapVersion","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"events-api-destination-stack/CheckBootstrapVersion","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"events-api-destination-integ":{"id":"events-api-destination-integ","path":"events-api-destination-integ","children":{"DefaultTest":{"id":"DefaultTest","path":"events-api-destination-integ/DefaultTest","children":{"Default":{"id":"Default","path":"events-api-destination-integ/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"events-api-destination-integ/DefaultTest/DeployAssert","children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"events-api-destination-integ/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"events-api-destination-integ/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"}}},"constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.ts new file mode 100644 index 0000000000000..0b89e66ebf396 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events/test/integ.api-destination.ts @@ -0,0 +1,42 @@ +import { App, CfnOutput, SecretValue, Stack } from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as events from 'aws-cdk-lib/aws-events'; +import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'; + +const app = new App(); + +const stack = new Stack(app, 'events-api-destination-stack'); + +const secret = new secretsmanager.Secret(stack, 'Secret', { + secretStringValue: SecretValue.unsafePlainText('abc123'), +}); + +const connection = new events.Connection(stack, 'Connection', { + authorization: events.Authorization.apiKey('x-api-key', secret.secretValue), + description: 'Connection with API Key x-api-key', + connectionName: 'MyConnection', +}); + +const destination = new events.ApiDestination(stack, 'Destination', { + connection, + endpoint: 'https://httpbin.org/headers', + httpMethod: events.HttpMethod.GET, + apiDestinationName: 'MyDestination', + rateLimitPerSecond: 1, + description: 'Calling example.com with API key x-api-key', +}); + +// arn:aws:events:{region}:{account}:api-destination/{destination-name}/11111111-1111-1111-1111-111111111111 +new CfnOutput(stack, 'DestinationArn', { + value: destination.apiDestinationArn, + description: 'The ARN of the API destination', +}); +// arn:aws:events:{region}:{account}:api-destination/{destination-name} +new CfnOutput(stack, 'DestinationArnForPolicy', { + value: destination.apiDestinationArnForPolicy || '', + description: 'The ARN of the API destination in resource format', +}); + +new IntegTest(app, 'events-api-destination-integ', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-events-targets/README.md b/packages/aws-cdk-lib/aws-events-targets/README.md index 333b3f29f6336..5666346b5a26d 100644 --- a/packages/aws-cdk-lib/aws-events-targets/README.md +++ b/packages/aws-cdk-lib/aws-events-targets/README.md @@ -369,11 +369,16 @@ const connection = events.Connection.fromEventBusArn( 'arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-f3gDy9', ); -const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName'; +const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName/11111111-1111-1111-1111-111111111111'; +const apiDestinationArnForPolicy = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName'; const destination = events.ApiDestination.fromApiDestinationAttributes( this, 'Destination', - { apiDestinationArn, connection }, + { + apiDestinationArn, + connection, + apiDestinationArnForPolicy // optional + }, ); const rule = new events.Rule(this, 'OtherRule', { diff --git a/packages/aws-cdk-lib/aws-events/lib/api-destination.ts b/packages/aws-cdk-lib/aws-events/lib/api-destination.ts index c55a9531990be..e30f321449bb3 100644 --- a/packages/aws-cdk-lib/aws-events/lib/api-destination.ts +++ b/packages/aws-cdk-lib/aws-events/lib/api-destination.ts @@ -62,6 +62,14 @@ export interface IApiDestination extends IResource { * @attribute */ readonly apiDestinationArn: string; + + /** + * The Amazon Resource Name (ARN) of an API destination in resource format, + * so it can be used in the Resource element of IAM permission policy statements. + * @see https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoneventbridge.html#amazoneventbridge-resources-for-iam-policies + * @attribute + */ + readonly apiDestinationArnForPolicy?: string; } /** @@ -76,6 +84,12 @@ export interface ApiDestinationAttributes { * The Connection to associate with the Api Destination */ readonly connection: IConnection; + /** + * The Amazon Resource Name (ARN) of an API destination in resource format. + * + * @default undefined - Imported API destination does not have ARN in resource format + */ + readonly apiDestinationArnForPolicy?: string; } /** @@ -111,6 +125,7 @@ export class ApiDestination extends Resource implements IApiDestination { class Import extends Resource implements ApiDestination { public readonly apiDestinationArn = attrs.apiDestinationArn; public readonly apiDestinationName = apiDestinationName!; + public readonly apiDestinationArnForPolicy = attrs.apiDestinationArnForPolicy; public readonly connection = attrs.connection; } @@ -133,6 +148,12 @@ export class ApiDestination extends Resource implements IApiDestination { */ public readonly apiDestinationArn: string; + /** + * The Amazon Resource Name (ARN) of an API destination in resource format. + * @attribute + */ + public readonly apiDestinationArnForPolicy?: string; + constructor(scope: Construct, id: string, props: ApiDestinationProps) { super(scope, id, { physicalName: props.apiDestinationName, @@ -153,5 +174,6 @@ export class ApiDestination extends Resource implements IApiDestination { this.apiDestinationName = this.getResourceNameAttribute(apiDestination.ref); this.apiDestinationArn = apiDestination.attrArn; + this.apiDestinationArnForPolicy = apiDestination.attrArnForPolicy; } } diff --git a/packages/aws-cdk-lib/aws-events/test/api-destination.test.ts b/packages/aws-cdk-lib/aws-events/test/api-destination.test.ts index 4cd48fe94d16b..1520ae5037dc7 100644 --- a/packages/aws-cdk-lib/aws-events/test/api-destination.test.ts +++ b/packages/aws-cdk-lib/aws-events/test/api-destination.test.ts @@ -44,16 +44,18 @@ test('imports an api destination from its arn', () => { ); // WHEN - const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName'; + const apiDestinationArnForPolicy = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName'; + const apiDestinationArn = `${apiDestinationArnForPolicy}/11111111-1111-1111-1111-111111111111`; const destination = events.ApiDestination.fromApiDestinationAttributes( stack, 'ApiDestination', - { apiDestinationArn, connection }, + { apiDestinationArn, connection, apiDestinationArnForPolicy }, ); // THEN - expect(destination.apiDestinationArn).toEqual('arn:aws:events:us-east-1:123456789012:api-destination/DestinationName'); - expect(destination.apiDestinationName).toEqual('DestinationName'); + expect(destination.apiDestinationArn).toEqual(apiDestinationArn); + expect(destination.apiDestinationArnForPolicy).toEqual(apiDestinationArnForPolicy); + expect(destination.apiDestinationName).toEqual('DestinationName/11111111-1111-1111-1111-111111111111'); }); test('throws if imported api destination ARN is invalid', () => {