Skip to content

Commit 420b5ff

Browse files
fix(servicecatalogappregistry): default stack name is not meaningful and causes conflict when multiple stacks deployed to the same account-region (#23823)
- Replace stage association error with warning - Deprecate `stackId` in TargetApplication options - Provide a default dynamic stack name for CreateTargetApplication stack with a reference to the application name - Provide a default dynamic stack name for ExistingTargetApplication stack with a reference to the application ID This fixes: [23861](#23861) Note: With this change to `stackName`, you may run into the following error during deployment if you have been using the default stack id and name by not explicitly setting them. ``` Resource handler returned message: "You already own an application 'MyApplicationName' (Service: ServiceCatalogAppRegistry, Status Code: 409, Request ID: xxxx)" (RequestToken: yyyy, HandlerErrorCode: InvalidRequest) ``` To address this error, explicitly set the `stackName` value to the name of your existing stack. For example: ```typescript const associatedApp = new ApplicationAssociator(app, 'MyApplicationAssociator', { applications: [ TargetApplication.createApplicationStack({ applicationName: 'MyApplicationName', stackName: 'ApplicationAssociatorStack', // add your existing stack name here ... ``` ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent d3df40f commit 420b5ff

17 files changed

+877
-12
lines changed

packages/@aws-cdk/aws-servicecatalogappregistry/lib/aspects/stack-associator.ts

+1-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ abstract class StackAssociatorBase implements IAspect {
2323
if (Stage.isStage(childNode)) {
2424
var stageAssociated = this.applicationAssociator?.isStageAssociated(childNode);
2525
if (stageAssociated === false) {
26-
this.error(childNode, 'Associate Stage: ' + childNode.stageName + ' to ensure all stacks in your cdk app are associated with AppRegistry. '
26+
this.warning(childNode, 'Associate Stage: ' + childNode.stageName + ' to ensure all stacks in your cdk app are associated with AppRegistry. '
2727
+ 'You can use ApplicationAssociator.associateStage to associate any stage.');
2828
}
2929
}
@@ -45,16 +45,6 @@ abstract class StackAssociatorBase implements IAspect {
4545
this.application.associateApplicationWithStack(node);
4646
}
4747

48-
/**
49-
* Adds an error annotation to a node.
50-
*
51-
* @param node The scope to add the error to.
52-
* @param message The error message.
53-
*/
54-
private error(node: IConstruct, message: string): void {
55-
Annotations.of(node).addError(message);
56-
}
57-
5848
/**
5949
* Adds a warning annotation to a node.
6050
*

packages/@aws-cdk/aws-servicecatalogappregistry/lib/target-application.ts

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface TargetApplicationCommonOptions extends cdk.StackProps {
1111
* refer to it in the [AWS CDK Toolkit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html).
1212
*
1313
* @default - ApplicationAssociatorStack
14+
* @deprecated - Use `stackName` instead to control the name of the stack
1415
*/
1516
readonly stackId?: string;
1617
}
@@ -91,6 +92,8 @@ class CreateTargetApplication extends TargetApplication {
9192
}
9293
public bind(scope: Construct): BindTargetApplicationResult {
9394
const stackId = this.applicationOptions.stackId ?? 'ApplicationAssociatorStack';
95+
(this.applicationOptions.stackName as string) =
96+
this.applicationOptions.stackName || `Application-${this.applicationOptions.applicationName}-Stack`;
9497
(this.applicationOptions.description as string) =
9598
this.applicationOptions.description || 'Stack to create AppRegistry application';
9699
(this.applicationOptions.env as cdk.Environment) =
@@ -117,7 +120,11 @@ class ExistingTargetApplication extends TargetApplication {
117120
super();
118121
}
119122
public bind(scope: Construct): BindTargetApplicationResult {
123+
const arnComponents = cdk.Arn.split(this.applicationOptions.applicationArnValue, cdk.ArnFormat.SLASH_RESOURCE_SLASH_RESOURCE_NAME);
124+
const applicationId = arnComponents.resourceName;
120125
const stackId = this.applicationOptions.stackId ?? 'ApplicationAssociatorStack';
126+
(this.applicationOptions.stackName as string) =
127+
this.applicationOptions.stackName || `Application-${applicationId}-Stack`;
121128
const applicationStack = new cdk.Stack(scope, stackId, this.applicationOptions);
122129
const appRegApplication = Application.fromApplicationArn(applicationStack, 'ExistingApplication', this.applicationOptions.applicationArnValue);
123130
return {

packages/@aws-cdk/aws-servicecatalogappregistry/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"@aws-cdk/assertions": "0.0.0",
8787
"@aws-cdk/cdk-build-tools": "0.0.0",
8888
"@aws-cdk/integ-runner": "0.0.0",
89+
"@aws-cdk/integ-tests": "0.0.0",
8990
"@aws-cdk/cfn2ts": "0.0.0",
9091
"@aws-cdk/pkglint": "0.0.0",
9192
"@aws-cdk/aws-codecommit": "0.0.0",

packages/@aws-cdk/aws-servicecatalogappregistry/test/application-associator.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ describe('Scope based Associations with Application with Cross Region/Account',
139139
associateStage: false,
140140
});
141141
app.synth();
142-
Annotations.fromStack(pipelineStack).hasError('*',
142+
Annotations.fromStack(pipelineStack).hasWarning('*',
143143
'Associate Stage: SampleStage to ensure all stacks in your cdk app are associated with AppRegistry. You can use ApplicationAssociator.associateStage to associate any stage.');
144144
});
145145

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"version": "29.0.0",
3+
"files": {
4+
"c4d674e9642d6dbbd0df5c93890473101fc95bbc70de7e28d79ba771b5284de8": {
5+
"source": {
6+
"path": "ApplicationAssociatorStack.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"416623072619-us-east-1": {
11+
"bucketName": "cdk-hnb659fds-assets-416623072619-us-east-1",
12+
"objectKey": "c4d674e9642d6dbbd0df5c93890473101fc95bbc70de7e28d79ba771b5284de8.json",
13+
"region": "us-east-1",
14+
"assumeRoleArn": "arn:${AWS::Partition}:iam::416623072619:role/cdk-hnb659fds-file-publishing-role-416623072619-us-east-1"
15+
}
16+
}
17+
}
18+
},
19+
"dockerImages": {}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"Description": "Stack to create AppRegistry application",
3+
"Resources": {
4+
"DefaultCdkApplication4573D5A3": {
5+
"Type": "AWS::ServiceCatalogAppRegistry::Application",
6+
"Properties": {
7+
"Name": "AppRegistryAssociatedApplication",
8+
"Description": "Application containing stacks deployed via CDK.",
9+
"Tags": {
10+
"managedBy": "CDK_Application_Associator"
11+
}
12+
}
13+
},
14+
"AppRegistryAssociation": {
15+
"Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation",
16+
"Properties": {
17+
"Application": {
18+
"Fn::GetAtt": [
19+
"DefaultCdkApplication4573D5A3",
20+
"Id"
21+
]
22+
},
23+
"Resource": {
24+
"Ref": "AWS::StackId"
25+
},
26+
"ResourceType": "CFN_STACK"
27+
}
28+
}
29+
},
30+
"Outputs": {
31+
"DefaultCdkApplicationApplicationManagerUrl27C138EF": {
32+
"Description": "Application manager url for the application created.",
33+
"Value": "https://us-east-1.console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-AppRegistryAssociatedApplication"
34+
}
35+
},
36+
"Parameters": {
37+
"BootstrapVersion": {
38+
"Type": "AWS::SSM::Parameter::Value<String>",
39+
"Default": "/cdk-bootstrap/hnb659fds/version",
40+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
41+
}
42+
},
43+
"Rules": {
44+
"CheckBootstrapVersion": {
45+
"Assertions": [
46+
{
47+
"Assert": {
48+
"Fn::Not": [
49+
{
50+
"Fn::Contains": [
51+
[
52+
"1",
53+
"2",
54+
"3",
55+
"4",
56+
"5"
57+
],
58+
{
59+
"Ref": "BootstrapVersion"
60+
}
61+
]
62+
}
63+
]
64+
},
65+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
66+
}
67+
]
68+
}
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "29.0.0",
3+
"files": {
4+
"19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": {
5+
"source": {
6+
"path": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"Resources": {
3+
"AppRegistryAssociation": {
4+
"Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation",
5+
"Properties": {
6+
"Application": "AppRegistryAssociatedApplication",
7+
"Resource": {
8+
"Ref": "AWS::StackId"
9+
},
10+
"ResourceType": "CFN_STACK"
11+
}
12+
}
13+
},
14+
"Parameters": {
15+
"BootstrapVersion": {
16+
"Type": "AWS::SSM::Parameter::Value<String>",
17+
"Default": "/cdk-bootstrap/hnb659fds/version",
18+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
19+
}
20+
},
21+
"Rules": {
22+
"CheckBootstrapVersion": {
23+
"Assertions": [
24+
{
25+
"Assert": {
26+
"Fn::Not": [
27+
{
28+
"Fn::Contains": [
29+
[
30+
"1",
31+
"2",
32+
"3",
33+
"4",
34+
"5"
35+
],
36+
{
37+
"Ref": "BootstrapVersion"
38+
}
39+
]
40+
}
41+
]
42+
},
43+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
44+
}
45+
]
46+
}
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"29.0.0"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "29.0.0",
3+
"files": {
4+
"19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": {
5+
"source": {
6+
"path": "integ-servicecatalogappregistry-application.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"Resources": {
3+
"AppRegistryAssociation": {
4+
"Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation",
5+
"Properties": {
6+
"Application": "AppRegistryAssociatedApplication",
7+
"Resource": {
8+
"Ref": "AWS::StackId"
9+
},
10+
"ResourceType": "CFN_STACK"
11+
}
12+
}
13+
},
14+
"Parameters": {
15+
"BootstrapVersion": {
16+
"Type": "AWS::SSM::Parameter::Value<String>",
17+
"Default": "/cdk-bootstrap/hnb659fds/version",
18+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
19+
}
20+
},
21+
"Rules": {
22+
"CheckBootstrapVersion": {
23+
"Assertions": [
24+
{
25+
"Assert": {
26+
"Fn::Not": [
27+
{
28+
"Fn::Contains": [
29+
[
30+
"1",
31+
"2",
32+
"3",
33+
"4",
34+
"5"
35+
],
36+
{
37+
"Ref": "BootstrapVersion"
38+
}
39+
]
40+
}
41+
]
42+
},
43+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
44+
}
45+
]
46+
}
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": "29.0.0",
3+
"testCases": {
4+
"ApplicationAssociatorTest/DefaultTest": {
5+
"stacks": [
6+
"integ-servicecatalogappregistry-application"
7+
],
8+
"assertionStack": "ApplicationAssociatorTest/DefaultTest/DeployAssert",
9+
"assertionStackName": "ApplicationAssociatorTestDefaultTestDeployAssert2A5F2DB9"
10+
}
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "29.0.0",
3+
"files": {
4+
"19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc": {
5+
"source": {
6+
"path": "integservicecatalogappregistryapplicationresourcesStack4399A149.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "19dd33f3c17e59cafd22b9459b0a8d9bedbd42252737fedb06b2bcdbcf7809cc.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"Resources": {
3+
"AppRegistryAssociation": {
4+
"Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation",
5+
"Properties": {
6+
"Application": "AppRegistryAssociatedApplication",
7+
"Resource": {
8+
"Ref": "AWS::StackId"
9+
},
10+
"ResourceType": "CFN_STACK"
11+
}
12+
}
13+
},
14+
"Parameters": {
15+
"BootstrapVersion": {
16+
"Type": "AWS::SSM::Parameter::Value<String>",
17+
"Default": "/cdk-bootstrap/hnb659fds/version",
18+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
19+
}
20+
},
21+
"Rules": {
22+
"CheckBootstrapVersion": {
23+
"Assertions": [
24+
{
25+
"Assert": {
26+
"Fn::Not": [
27+
{
28+
"Fn::Contains": [
29+
[
30+
"1",
31+
"2",
32+
"3",
33+
"4",
34+
"5"
35+
],
36+
{
37+
"Ref": "BootstrapVersion"
38+
}
39+
]
40+
}
41+
]
42+
},
43+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
44+
}
45+
]
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)