From 2167289658e8f3431ec815c741277dc1be1aa110 Mon Sep 17 00:00:00 2001 From: Jung Lee <97768438+jungle-amazon@users.noreply.github.com> Date: Wed, 15 Mar 2023 16:02:00 -0700 Subject: [PATCH] feat(servicecatalogappregistry-alpha): Introduce flag to control application sharing and association behavior for cross-account stacks (#24408) Problem: * Currently, the ApplicationAssociator construct automatically shares the target Application with any accounts of cross-account stacks. [[code reference](https://github.com/aws/aws-cdk/blob/main/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts#L91-L95)] * If the owner of a cross-account stack is not part of the same AWS Organization as the owner of the ApplicationAssociator stack, or otherwise have not enabled cross-account sharing, during deployment the ApplicationAssociator will fail when attempting to share the application with the stack owner, with a message like below: ``` Principal 123456789012 is not in your AWS organization. You do not have permission to add external AWS accounts to a resource share. (Service: AWSRAM; Status Code: 400; Error Code: OperationNotPermittedException; Request ID: aaa; Proxy: null) ``` Feature: * We want to introduce a mechanism (`associateCrossAccountStacks` field in TargetApplicationOptions) where the user can specify if they want to allow sharing their application to any accounts of cross-account stacks in order to then subsequently associate the stack with the application. * This flag will be `false` by default. This allows customers to have their stack deployments proceed without being blocked on application sharing or cross-account associations. * If set to `false`, ApplicationAssociator will skip the application sharing and association for cross-account stacks. During synthesis, a warning will be displayed to notify that cross-account stacks were detected but sharing and association will be skipped. * If set to `true`, the application will be shared and then associated for cross-account stacks. This relies on the user properly setting up cross-account sharing beforehand. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-servicecatalogappregistry/README.md | 18 ++ .../lib/application-associator.ts | 17 +- .../lib/application.ts | 6 +- .../lib/aspects/stack-associator.ts | 47 ++- .../lib/target-application.ts | 14 + .../test/application-associator.test.ts | 33 +- ...efaultTestDeployAssert2A5F2DB9.assets.json | 19 ++ ...aultTestDeployAssert2A5F2DB9.template.json | 48 +++ ...estAppRegistryApplicationStack.assets.json | 19 ++ ...tAppRegistryApplicationStack.template.json | 102 ++++++ .../cdk.out | 1 + ...egistry-cross-account-resource.assets.json | 19 ++ ...istry-cross-account-resource.template.json | 48 +++ ...alogappregistry-local-resource.assets.json | 19 ++ ...ogappregistry-local-resource.template.json | 48 +++ .../integ.json | 13 + .../manifest.json | 267 +++++++++++++++ .../tree.json | 303 ++++++++++++++++++ ...cross-account-stack-association-enabled.ts | 27 ++ 19 files changed, 1051 insertions(+), 17 deletions(-) create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.assets.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.template.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.ts diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/README.md b/packages/@aws-cdk/aws-servicecatalogappregistry/README.md index 801f2f084b07e..867803c159594 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/README.md +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/README.md @@ -198,6 +198,24 @@ const cdkPipeline = new ApplicationPipelineStack(app, 'CDKApplicationPipelineSta }); ``` +By default, ApplicationAssociator will not perform cross-account stack associations with the target Application, +to avoid deployment failures for accounts which have not been setup for cross-account associations. +To enable cross-account stack associations, make sure all accounts are in the same organization as the +target Application's account and that resource sharing is enabled within the organization. +If you wish to turn on cross-account sharing and associations, set the `associateCrossAccountStacks` field to `true`, +as shown in the example below: + +```ts +const app = new App(); +const associatedApp = new appreg.ApplicationAssociator(app, 'AssociatedApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + associateCrossAccountStacks: true, + applicationName: 'MyAssociatedApplication', + env: { account: '123456789012', region: 'us-east-1' }, + })], +}); +``` + ## Attribute Group An AppRegistry attribute group acts as a container for user-defined attributes for an application. diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application-associator.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application-associator.ts index d01c42bf1bd78..ecb17fc924f43 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application-associator.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application-associator.ts @@ -24,7 +24,9 @@ export interface ApplicationAssociatorProps { * in case of a `Pipeline` stack, stage underneath the pipeline will not automatically be associated and * needs to be associated separately. * - * If cross account stack is detected, then this construct will automatically share the application to consumer accounts. + * If cross account stack is detected and `associateCrossAccountStacks` in `TargetApplicationOptions` is `true`, + * then the application will automatically be shared with the consumer accounts to allow associations. + * Otherwise, the application will not be shared. * Cross account feature will only work for non environment agnostic stacks. */ export class ApplicationAssociator extends Construct { @@ -33,6 +35,7 @@ export class ApplicationAssociator extends Construct { */ private readonly application: IApplication; private readonly associatedStages: Set = new Set(); + private readonly associateCrossAccountStacks?: boolean; constructor(scope: cdk.App, id: string, props: ApplicationAssociatorProps) { super(scope, id); @@ -42,8 +45,12 @@ export class ApplicationAssociator extends Construct { } const targetApplication = props.applications[0]; - this.application = targetApplication.bind(scope).application; - cdk.Aspects.of(scope).add(new CheckedStageStackAssociator(this)); + const targetBindResult = targetApplication.bind(scope); + this.application = targetBindResult.application; + this.associateCrossAccountStacks = targetBindResult.associateCrossAccountStacks; + cdk.Aspects.of(scope).add(new CheckedStageStackAssociator(this, { + associateCrossAccountStacks: this.associateCrossAccountStacks, + })); } /** @@ -52,7 +59,9 @@ export class ApplicationAssociator extends Construct { */ public associateStage(stage: cdk.Stage): cdk.Stage { this.associatedStages.add(stage); - cdk.Aspects.of(stage).add(new CheckedStageStackAssociator(this)); + cdk.Aspects.of(stage).add(new CheckedStageStackAssociator(this, { + associateCrossAccountStacks: this.associateCrossAccountStacks, + })); return stage; } diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts index bb5abdfed4da8..b630e1a883fb9 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/application.ts @@ -172,14 +172,16 @@ abstract class ApplicationBase extends cdk.Resource implements IApplication { } /** - * Associate all stacks present in construct's aspect with application. + * Associate all stacks present in construct's aspect with application, including cross-account stacks. * * NOTE: This method won't automatically register stacks under pipeline stages, * and requires association of each pipeline stage by calling this method with stage Construct. * */ public associateAllStacksInScope(scope: Construct): void { - cdk.Aspects.of(scope).add(new StageStackAssociator(this)); + cdk.Aspects.of(scope).add(new StageStackAssociator(this, { + associateCrossAccountStacks: true, + })); } /** diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts index 9a59fc58bbeaf..25549c048937b 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts @@ -5,6 +5,16 @@ import { ApplicationAssociator } from '../application-associator'; import { SharePermission } from '../common'; import { isRegionUnresolved, isAccountUnresolved } from '../private/utils'; +export interface StackAssociatorBaseProps { + /** + * Indicates if the target Application should be shared with the cross-account stack owners and then + * associated with the cross-account stacks. + * + * @default - false + */ + readonly associateCrossAccountStacks?: boolean; +} + /** * Aspect class, this will visit each node from the provided construct once. * @@ -14,9 +24,14 @@ import { isRegionUnresolved, isAccountUnresolved } from '../private/utils'; abstract class StackAssociatorBase implements IAspect { protected abstract readonly application: IApplication; protected abstract readonly applicationAssociator?: ApplicationAssociator; + protected readonly associateCrossAccountStacks?: boolean; protected readonly sharedAccounts: Set = new Set(); + constructor(props?: StackAssociatorBaseProps) { + this.associateCrossAccountStacks = props?.associateCrossAccountStacks ?? false; + } + public visit(node: IConstruct): void { // verify if a stage in a particular stack is associated to Application. node.node.children.forEach((childNode) => { @@ -42,6 +57,13 @@ abstract class StackAssociatorBase implements IAspect { * @param node A Stage stack. */ private associate(node: Stack): void { + if (!isRegionUnresolved(this.application.env.region, node.region) + && node.account != this.application.env.account + && !this.associateCrossAccountStacks) { + // Skip association when cross-account sharing/association is not enabled. + // A warning will have been displayed as part of `handleCrossAccountStack()`. + return; + } this.application.associateApplicationWithStack(node); } @@ -77,7 +99,7 @@ abstract class StackAssociatorBase implements IAspect { /** * Handle cross-account association. - * If any stack is evaluated as cross-account than that of application, + * If any stack is evaluated as cross-account than that of application, and cross-account option is enabled, * then we will share the application to the stack owning account. * * @param node Cfn stack. @@ -89,12 +111,17 @@ abstract class StackAssociatorBase implements IAspect { } if (node.account != this.application.env.account && !this.sharedAccounts.has(node.account)) { - this.application.shareApplication({ - accounts: [node.account], - sharePermission: SharePermission.ALLOW_ACCESS, - }); + if (this.associateCrossAccountStacks) { + this.application.shareApplication({ + accounts: [node.account], + sharePermission: SharePermission.ALLOW_ACCESS, + }); - this.sharedAccounts.add(node.account); + this.sharedAccounts.add(node.account); + } else { + this.warning(node, 'Cross-account stack detected but application sharing and association will be skipped because cross-account option is not enabled.'); + return; + } } } } @@ -103,8 +130,8 @@ export class CheckedStageStackAssociator extends StackAssociatorBase { protected readonly application: IApplication; protected readonly applicationAssociator?: ApplicationAssociator; - constructor(app: ApplicationAssociator) { - super(); + constructor(app: ApplicationAssociator, props?: StackAssociatorBaseProps) { + super(props); this.application = app.appRegistryApplication(); this.applicationAssociator = app; } @@ -114,8 +141,8 @@ export class StageStackAssociator extends StackAssociatorBase { protected readonly application: IApplication; protected readonly applicationAssociator?: ApplicationAssociator; - constructor(app: IApplication) { - super(); + constructor(app: IApplication, props?: StackAssociatorBaseProps) { + super(props); this.application = app; } } diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts index 2b6f13db1b0cb..a336f72a9df0e 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts @@ -15,6 +15,14 @@ export interface TargetApplicationCommonOptions extends cdk.StackProps { * @deprecated - Use `stackName` instead to control the name and id of the stack */ readonly stackId?: string; + + /** + * Determines whether any cross-account stacks defined in the CDK app definition should be associated with the + * target application. If set to `true`, the application will first be shared with the accounts that own the stacks. + * + * @default - false + */ + readonly associateCrossAccountStacks?: boolean; } @@ -87,6 +95,10 @@ export interface BindTargetApplicationResult { * Created or imported application. */ readonly application: IApplication; + /** + * Enables cross-account associations with the target application. + */ + readonly associateCrossAccountStacks: boolean; } /** @@ -124,6 +136,7 @@ class CreateTargetApplication extends TargetApplication { return { application: appRegApplication, + associateCrossAccountStacks: this.applicationOptions.associateCrossAccountStacks ?? false, }; } } @@ -144,6 +157,7 @@ class ExistingTargetApplication extends TargetApplication { const appRegApplication = Application.fromApplicationArn(applicationStack, 'ExistingApplication', this.applicationOptions.applicationArnValue); return { application: appRegApplication, + associateCrossAccountStacks: this.applicationOptions.associateCrossAccountStacks ?? false, }; } } diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts index c61cf4f10e6cd..e6b43fce35dab 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts @@ -179,7 +179,38 @@ describe('Scope based Associations with Application with Cross Region/Account', }); }), - test('ApplicationAssociator with cross region stacks inside cdkApp throws error', () => { + test('ApplicationAssociator with cross account stacks inside cdkApp gives warning if associateCrossAccountStacks is not provided', () => { + new appreg.ApplicationAssociator(app, 'MyApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + applicationName: 'MyAssociatedApplication', + stackName: 'MyAssociatedApplicationStack', + env: { account: 'account2', region: 'region' }, + })], + }); + + const crossAccountStack = new cdk.Stack(app, 'crossRegionStack', { + env: { account: 'account', region: 'region' }, + }); + Annotations.fromStack(crossAccountStack).hasWarning('*', 'Cross-account stack detected but application sharing and association will be skipped because cross-account option is not enabled.'); + }); + + test('ApplicationAssociator with cross account stacks inside cdkApp does not give warning if associateCrossAccountStacks is set to true', () => { + new appreg.ApplicationAssociator(app, 'MyApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + applicationName: 'MyAssociatedApplication', + stackName: 'MyAssociatedApplicationStack', + associateCrossAccountStacks: true, + env: { account: 'account', region: 'region' }, + })], + }); + + const crossAccountStack = new cdk.Stack(app, 'crossRegionStack', { + env: { account: 'account2', region: 'region' }, + }); + Annotations.fromStack(crossAccountStack).hasNoWarning('*', 'Cross-account stack detected but application sharing and association will be skipped because cross-account option is not enabled.'); + }); + + test('ApplicationAssociator with cross region stacks inside cdkApp gives warning', () => { new appreg.ApplicationAssociator(app, 'MyApplication', { applications: [appreg.TargetApplication.createApplicationStack({ applicationName: 'MyAssociatedApplication', diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json new file mode 100644 index 0000000000000..aec9ce7619bdd --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json @@ -0,0 +1,19 @@ +{ + "version": "31.0.0", + "files": { + "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": { + "source": { + "path": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.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/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json new file mode 100644 index 0000000000000..ecc817b74774a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json @@ -0,0 +1,48 @@ +{ + "Resources": { + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": "AppRegistryAssociatedApplication", + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.assets.json new file mode 100644 index 0000000000000..8aa7abe793fce --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "31.0.0", + "files": { + "1db9045d198a45233cf79d4f87770e1d94d5efd69f70a11d40e3a6310ba3b26c": { + "source": { + "path": "TestAppRegistryApplicationStack.template.json", + "packaging": "file" + }, + "destinations": { + "000000000000-current_region": { + "bucketName": "cdk-hnb659fds-assets-000000000000-${AWS::Region}", + "objectKey": "1db9045d198a45233cf79d4f87770e1d94d5efd69f70a11d40e3a6310ba3b26c.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-file-publishing-role-000000000000-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.template.json new file mode 100644 index 0000000000000..670672e9a2408 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/TestAppRegistryApplicationStack.template.json @@ -0,0 +1,102 @@ +{ + "Description": "Stack to create AppRegistry application", + "Resources": { + "DefaultCdkApplication4573D5A3": { + "Type": "AWS::ServiceCatalogAppRegistry::Application", + "Properties": { + "Name": "AppRegistryAssociatedApplication", + "Description": "Application containing stacks deployed via CDK.", + "Tags": { + "managedBy": "CDK_Application_Associator" + } + } + }, + "DefaultCdkApplicationRAMShare60b7c88c45feCE472D79": { + "Type": "AWS::RAM::ResourceShare", + "Properties": { + "Name": "RAMShare60b7c88c45fe", + "AllowExternalPrincipals": false, + "PermissionArns": [ + "arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationAllowAssociation" + ], + "Principals": [ + "111111111111" + ], + "ResourceArns": [ + { + "Fn::GetAtt": [ + "DefaultCdkApplication4573D5A3", + "Arn" + ] + } + ] + } + }, + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": { + "Fn::GetAtt": [ + "DefaultCdkApplication4573D5A3", + "Id" + ] + }, + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "Outputs": { + "DefaultCdkApplicationApplicationManagerUrl27C138EF": { + "Description": "System Manager Application Manager URL for the application created.", + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "AWS::Region" + }, + ".console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-AppRegistryAssociatedApplication" + ] + ] + } + } + }, + "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/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/cdk.out b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/cdk.out new file mode 100644 index 0000000000000..7925065efbcc4 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"31.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.assets.json new file mode 100644 index 0000000000000..79e8b8db0b894 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.assets.json @@ -0,0 +1,19 @@ +{ + "version": "31.0.0", + "files": { + "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": { + "source": { + "path": "integ-servicecatalogappregistry-cross-account-resource.template.json", + "packaging": "file" + }, + "destinations": { + "111111111111-current_region": { + "bucketName": "cdk-hnb659fds-assets-111111111111-${AWS::Region}", + "objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::111111111111:role/cdk-hnb659fds-file-publishing-role-111111111111-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.template.json new file mode 100644 index 0000000000000..ecc817b74774a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-cross-account-resource.template.json @@ -0,0 +1,48 @@ +{ + "Resources": { + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": "AppRegistryAssociatedApplication", + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.assets.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.assets.json new file mode 100644 index 0000000000000..400c7486bae88 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.assets.json @@ -0,0 +1,19 @@ +{ + "version": "31.0.0", + "files": { + "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": { + "source": { + "path": "integ-servicecatalogappregistry-local-resource.template.json", + "packaging": "file" + }, + "destinations": { + "000000000000-current_region": { + "bucketName": "cdk-hnb659fds-assets-000000000000-${AWS::Region}", + "objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-file-publishing-role-000000000000-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.template.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.template.json new file mode 100644 index 0000000000000..ecc817b74774a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ-servicecatalogappregistry-local-resource.template.json @@ -0,0 +1,48 @@ +{ + "Resources": { + "AppRegistryAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": "AppRegistryAssociatedApplication", + "Resource": { + "Ref": "AWS::StackId" + }, + "ResourceType": "CFN_STACK" + } + } + }, + "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/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ.json new file mode 100644 index 0000000000000..6aa5ad636b49b --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "31.0.0", + "testCases": { + "ApplicationAssociatorTest/DefaultTest": { + "stacks": [ + "integ-servicecatalogappregistry-local-resource", + "integ-servicecatalogappregistry-cross-account-resource" + ], + "assertionStack": "ApplicationAssociatorTest/DefaultTest/DeployAssert", + "assertionStackName": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/manifest.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/manifest.json new file mode 100644 index 0000000000000..62340b1e6d634 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/manifest.json @@ -0,0 +1,267 @@ +{ + "version": "31.0.0", + "artifacts": { + "integ-servicecatalogappregistry-local-resource.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-servicecatalogappregistry-local-resource.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-servicecatalogappregistry-local-resource": { + "type": "aws:cloudformation:stack", + "environment": "aws://000000000000/unknown-region", + "properties": { + "templateFile": "integ-servicecatalogappregistry-local-resource.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-deploy-role-000000000000-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-cfn-exec-role-000000000000-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-000000000000-${AWS::Region}/19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-servicecatalogappregistry-local-resource.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-lookup-role-000000000000-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TestAppRegistryApplicationStack", + "integ-servicecatalogappregistry-local-resource.assets" + ], + "metadata": { + "/integ-servicecatalogappregistry-local-resource": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/integ-servicecatalogappregistry-local-resource/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/integ-servicecatalogappregistry-local-resource/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-servicecatalogappregistry-local-resource/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-servicecatalogappregistry-local-resource" + }, + "TestAppRegistryApplicationStack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TestAppRegistryApplicationStack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TestAppRegistryApplicationStack": { + "type": "aws:cloudformation:stack", + "environment": "aws://000000000000/unknown-region", + "properties": { + "templateFile": "TestAppRegistryApplicationStack.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-deploy-role-000000000000-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-cfn-exec-role-000000000000-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-000000000000-${AWS::Region}/1db9045d198a45233cf79d4f87770e1d94d5efd69f70a11d40e3a6310ba3b26c.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TestAppRegistryApplicationStack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::000000000000:role/cdk-hnb659fds-lookup-role-000000000000-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TestAppRegistryApplicationStack.assets" + ], + "metadata": { + "/TestAppRegistryApplicationStack": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/TestAppRegistryApplicationStack/DefaultCdkApplication/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DefaultCdkApplication4573D5A3" + } + ], + "/TestAppRegistryApplicationStack/DefaultCdkApplication/ApplicationManagerUrl": [ + { + "type": "aws:cdk:logicalId", + "data": "DefaultCdkApplicationApplicationManagerUrl27C138EF" + } + ], + "/TestAppRegistryApplicationStack/DefaultCdkApplication/RAMShare60b7c88c45fe": [ + { + "type": "aws:cdk:logicalId", + "data": "DefaultCdkApplicationRAMShare60b7c88c45feCE472D79" + } + ], + "/TestAppRegistryApplicationStack/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/TestAppRegistryApplicationStack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TestAppRegistryApplicationStack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TestAppRegistryApplicationStack" + }, + "integ-servicecatalogappregistry-cross-account-resource.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-servicecatalogappregistry-cross-account-resource.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-servicecatalogappregistry-cross-account-resource": { + "type": "aws:cloudformation:stack", + "environment": "aws://111111111111/unknown-region", + "properties": { + "templateFile": "integ-servicecatalogappregistry-cross-account-resource.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::111111111111:role/cdk-hnb659fds-deploy-role-111111111111-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::111111111111:role/cdk-hnb659fds-cfn-exec-role-111111111111-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-111111111111-${AWS::Region}/19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-servicecatalogappregistry-cross-account-resource.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::111111111111:role/cdk-hnb659fds-lookup-role-111111111111-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integ-servicecatalogappregistry-cross-account-resource.assets" + ], + "metadata": { + "/integ-servicecatalogappregistry-cross-account-resource": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/integ-servicecatalogappregistry-cross-account-resource/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/integ-servicecatalogappregistry-cross-account-resource/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-servicecatalogappregistry-cross-account-resource/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-servicecatalogappregistry-cross-account-resource" + }, + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json", + "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}/19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.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": [ + "TestAppRegistryApplicationStack", + "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.assets" + ], + "metadata": { + "/ApplicationAssociatorTest/DefaultTest/DeployAssert": [ + { + "type": "aws:cdk:warning", + "data": "Environment agnostic stack determined, AppRegistry association might not work as expected in case you deploy cross-region or cross-account stack." + } + ], + "/ApplicationAssociatorTest/DefaultTest/DeployAssert/AppRegistryAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "AppRegistryAssociation" + } + ], + "/ApplicationAssociatorTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ApplicationAssociatorTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ApplicationAssociatorTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/tree.json b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/tree.json new file mode 100644 index 0000000000000..9af3e2f61d30a --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.js.snapshot/tree.json @@ -0,0 +1,303 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-servicecatalogappregistry-local-resource": { + "id": "integ-servicecatalogappregistry-local-resource", + "path": "integ-servicecatalogappregistry-local-resource", + "children": { + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "integ-servicecatalogappregistry-local-resource/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": "AppRegistryAssociatedApplication", + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-servicecatalogappregistry-local-resource/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-servicecatalogappregistry-local-resource/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "RegisterCdkApplication": { + "id": "RegisterCdkApplication", + "path": "RegisterCdkApplication", + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.ApplicationAssociator", + "version": "0.0.0" + } + }, + "TestAppRegistryApplicationStack": { + "id": "TestAppRegistryApplicationStack", + "path": "TestAppRegistryApplicationStack", + "children": { + "DefaultCdkApplication": { + "id": "DefaultCdkApplication", + "path": "TestAppRegistryApplicationStack/DefaultCdkApplication", + "children": { + "Resource": { + "id": "Resource", + "path": "TestAppRegistryApplicationStack/DefaultCdkApplication/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::Application", + "aws:cdk:cloudformation:props": { + "name": "AppRegistryAssociatedApplication", + "description": "Application containing stacks deployed via CDK.", + "tags": { + "managedBy": "CDK_Application_Associator" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnApplication", + "version": "0.0.0" + } + }, + "ApplicationManagerUrl": { + "id": "ApplicationManagerUrl", + "path": "TestAppRegistryApplicationStack/DefaultCdkApplication/ApplicationManagerUrl", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "RAMShare60b7c88c45fe": { + "id": "RAMShare60b7c88c45fe", + "path": "TestAppRegistryApplicationStack/DefaultCdkApplication/RAMShare60b7c88c45fe", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::RAM::ResourceShare", + "aws:cdk:cloudformation:props": { + "name": "RAMShare60b7c88c45fe", + "allowExternalPrincipals": false, + "permissionArns": [ + "arn:aws:ram::aws:permission/AWSRAMPermissionServiceCatalogAppRegistryApplicationAllowAssociation" + ], + "principals": [ + "111111111111" + ], + "resourceArns": [ + { + "Fn::GetAtt": [ + "DefaultCdkApplication4573D5A3", + "Arn" + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ram.CfnResourceShare", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.Application", + "version": "0.0.0" + } + }, + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "TestAppRegistryApplicationStack/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": { + "Fn::GetAtt": [ + "DefaultCdkApplication4573D5A3", + "Id" + ] + }, + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "TestAppRegistryApplicationStack/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "TestAppRegistryApplicationStack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "integ-servicecatalogappregistry-cross-account-resource": { + "id": "integ-servicecatalogappregistry-cross-account-resource", + "path": "integ-servicecatalogappregistry-cross-account-resource", + "children": { + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "integ-servicecatalogappregistry-cross-account-resource/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": "AppRegistryAssociatedApplication", + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-servicecatalogappregistry-cross-account-resource/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-servicecatalogappregistry-cross-account-resource/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "ApplicationAssociatorTest": { + "id": "ApplicationAssociatorTest", + "path": "ApplicationAssociatorTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "ApplicationAssociatorTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "ApplicationAssociatorTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.252" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert", + "children": { + "AppRegistryAssociation": { + "id": "AppRegistryAssociation", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert/AppRegistryAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "aws:cdk:cloudformation:props": { + "application": "AppRegistryAssociatedApplication", + "resource": { + "Ref": "AWS::StackId" + }, + "resourceType": "CFN_STACK" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnResourceAssociation", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "ApplicationAssociatorTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.252" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.ts new file mode 100644 index 0000000000000..e07ae464f5696 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/integ.application-associator.cross-account-stack-association-enabled.ts @@ -0,0 +1,27 @@ +import * as cdk from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; +import * as appreg from '../lib'; + +// When doing a deployment for these stacks, specify stack `env` properties and use +// the same `account` for `localStack` and the TargetApplication stack, and a separate +// account for `crossAccountStack`. +// The accounts should be in the same AWS Organization with cross-account sharing enabled. + +const app = new cdk.App(); +const localStack = new cdk.Stack(app, 'integ-servicecatalogappregistry-local-resource'); + +new appreg.ApplicationAssociator(app, 'RegisterCdkApplication', { + applications: [appreg.TargetApplication.createApplicationStack({ + associateCrossAccountStacks: true, + applicationName: 'AppRegistryAssociatedApplication', + stackName: 'TestAppRegistryApplicationStack', + })], +}); + +const crossAccountStack = new cdk.Stack(app, 'integ-servicecatalogappregistry-cross-account-resource'); + +new integ.IntegTest(app, 'ApplicationAssociatorTest', { + testCases: [localStack, crossAccountStack], +}); + +app.synth(); \ No newline at end of file