Skip to content

Commit 3669dce

Browse files
authored
chore(release): 2.167.2 (#32177)
See CHANGELOG
2 parents d681b12 + fd68993 commit 3669dce

File tree

17 files changed

+321
-39
lines changed

17 files changed

+321
-39
lines changed

CHANGELOG.v2.alpha.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
## [2.167.2-alpha.0](https://github.com/aws/aws-cdk/compare/v2.167.1-alpha.0...v2.167.2-alpha.0) (2024-11-18)
6+
57
## [2.167.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.167.0-alpha.0...v2.167.1-alpha.0) (2024-11-14)
68

79
## [2.167.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.166.0-alpha.0...v2.167.0-alpha.0) (2024-11-13)

CHANGELOG.v2.md

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
## [2.167.2](https://github.com/aws/aws-cdk/compare/v2.167.1...v2.167.2) (2024-11-18)
6+
7+
8+
### Bug Fixes
9+
10+
* **cli:** `cdk diff` always falls back to template only diff ([#32165](https://github.com/aws/aws-cdk/issues/32165)) ([3fd9699](https://github.com/aws/aws-cdk/commit/3fd969988c599bf15b9b68d718505fcf92045b3a))
11+
* **cli:** externally managed stack notification arns are deleted on `deploy` ([#32163](https://github.com/aws/aws-cdk/issues/32163)) ([465da31](https://github.com/aws/aws-cdk/commit/465da319ea173fba8ae395b8b897607cf2075eaa))
12+
* **cli:** the LoadBalancerProvider doesn't match LBs when querying by a subset of tags ([#32164](https://github.com/aws/aws-cdk/issues/32164)) ([a0b47c5](https://github.com/aws/aws-cdk/commit/a0b47c5b530abe13b547d7263f437997148eb630))
13+
514
## [2.167.1](https://github.com/aws/aws-cdk/compare/v2.167.0...v2.167.1) (2024-11-14)
615

716

allowed-breaking-changes.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -936,4 +936,10 @@ removed:aws-cdk-lib.aws_ec2.WindowsVersion.WINDOWS_SERVER_2022_TURKISH_FULL_BASE
936936

937937
# null() return a [] which is invalid filter rule. It should return [null].
938938
# Hence the return type changes from string[] to any
939-
change-return-type:aws-cdk-lib.aws_lambda.FilterRule.null
939+
change-return-type:aws-cdk-lib.aws_lambda.FilterRule.null
940+
941+
942+
# output property was mistakenly marked as required even though it should have allowed
943+
# for undefined, i.e optional
944+
changed-type:@aws-cdk/cx-api.CloudFormationStackArtifact.notificationArns
945+
changed-type:aws-cdk-lib.cx_api.CloudFormationStackArtifact.notificationArns

packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js

+26-6
Original file line numberDiff line numberDiff line change
@@ -742,12 +742,23 @@ class BuiltinLambdaStack extends cdk.Stack {
742742
}
743743
}
744744

745-
class NotificationArnPropStack extends cdk.Stack {
745+
class NotificationArnsStack extends cdk.Stack {
746746
constructor(parent, id, props) {
747-
super(parent, id, props);
748-
new sns.Topic(this, 'topic');
747+
748+
const arnsFromEnv = process.env.INTEG_NOTIFICATION_ARNS;
749+
super(parent, id, {
750+
...props,
751+
// comma separated list of arns.
752+
// empty string means empty list.
753+
// undefined means undefined
754+
notificationArns: arnsFromEnv == '' ? [] : (arnsFromEnv ? arnsFromEnv.split(',') : undefined)
755+
});
756+
757+
new cdk.CfnWaitConditionHandle(this, 'WaitConditionHandle');
758+
749759
}
750760
}
761+
751762
class AppSyncHotswapStack extends cdk.Stack {
752763
constructor(parent, id, props) {
753764
super(parent, id, props);
@@ -776,6 +787,15 @@ class AppSyncHotswapStack extends cdk.Stack {
776787
}
777788
}
778789

790+
class MetadataStack extends cdk.Stack {
791+
constructor(parent, id, props) {
792+
super(parent, id, props);
793+
const handle = new cdk.CfnWaitConditionHandle(this, 'WaitConditionHandle');
794+
handle.addMetadata('Key', process.env.INTEG_METADATA_VALUE ?? 'default')
795+
796+
}
797+
}
798+
779799
const app = new cdk.App({
780800
context: {
781801
'@aws-cdk/core:assetHashSalt': process.env.CODEBUILD_BUILD_ID, // Force all assets to be unique, but consistent in one build
@@ -830,9 +850,7 @@ switch (stackSet) {
830850
new DockerInUseStack(app, `${stackPrefix}-docker-in-use`);
831851
new DockerStackWithCustomFile(app, `${stackPrefix}-docker-with-custom-file`);
832852

833-
new NotificationArnPropStack(app, `${stackPrefix}-notification-arn-prop`, {
834-
notificationArns: [`arn:aws:sns:${defaultEnv.region}:${defaultEnv.account}:${stackPrefix}-test-topic-prop`],
835-
});
853+
new NotificationArnsStack(app, `${stackPrefix}-notification-arns`);
836854

837855
// SSO stacks
838856
new SsoInstanceAccessControlConfig(app, `${stackPrefix}-sso-access-control`);
@@ -877,6 +895,8 @@ switch (stackSet) {
877895
new ExportValueStack(app, `${stackPrefix}-export-value-stack`);
878896

879897
new BundlingStage(app, `${stackPrefix}-bundling-stage`);
898+
899+
new MetadataStack(app, `${stackPrefix}-metadata`);
880900
break;
881901

882902
case 'stage-using-context':

packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts

+178-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
DescribeStacksCommand,
88
GetTemplateCommand,
99
ListChangeSetsCommand,
10+
UpdateStackCommand,
11+
waitUntilStackUpdateComplete,
1012
} from '@aws-sdk/client-cloudformation';
1113
import { DescribeServicesCommand } from '@aws-sdk/client-ecs';
1214
import {
@@ -633,14 +635,14 @@ integTest(
633635
const topicArn = response.TopicArn!;
634636

635637
try {
636-
await fixture.cdkDeploy('test-2', {
638+
await fixture.cdkDeploy('notification-arns', {
637639
options: ['--notification-arns', topicArn],
638640
});
639641

640642
// verify that the stack we deployed has our notification ARN
641643
const describeResponse = await fixture.aws.cloudFormation.send(
642644
new DescribeStacksCommand({
643-
StackName: fixture.fullStackName('test-2'),
645+
StackName: fixture.fullStackName('notification-arns'),
644646
}),
645647
);
646648
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
@@ -661,15 +663,110 @@ integTest('deploy with notification ARN as prop', withDefaultFixture(async (fixt
661663
const topicArn = response.TopicArn!;
662664

663665
try {
664-
await fixture.cdkDeploy('notification-arn-prop');
666+
await fixture.cdkDeploy('notification-arns', {
667+
modEnv: {
668+
INTEG_NOTIFICATION_ARNS: topicArn,
669+
670+
},
671+
});
665672

666673
// verify that the stack we deployed has our notification ARN
667674
const describeResponse = await fixture.aws.cloudFormation.send(
668675
new DescribeStacksCommand({
669-
StackName: fixture.fullStackName('notification-arn-prop'),
676+
StackName: fixture.fullStackName('notification-arns'),
677+
}),
678+
);
679+
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
680+
} finally {
681+
await fixture.aws.sns.send(
682+
new DeleteTopicCommand({
683+
TopicArn: topicArn,
684+
}),
685+
);
686+
}
687+
}));
688+
689+
// https://github.com/aws/aws-cdk/issues/32153
690+
integTest('deploy preserves existing notification arns when not specified', withDefaultFixture(async (fixture) => {
691+
const topicName = `${fixture.stackNamePrefix}-topic`;
692+
693+
const response = await fixture.aws.sns.send(new CreateTopicCommand({ Name: topicName }));
694+
const topicArn = response.TopicArn!;
695+
696+
try {
697+
await fixture.cdkDeploy('notification-arns');
698+
699+
// add notification arns externally to cdk
700+
await fixture.aws.cloudFormation.send(
701+
new UpdateStackCommand({
702+
StackName: fixture.fullStackName('notification-arns'),
703+
UsePreviousTemplate: true,
704+
NotificationARNs: [topicArn],
705+
}),
706+
);
707+
708+
await waitUntilStackUpdateComplete(
709+
{
710+
client: fixture.aws.cloudFormation,
711+
maxWaitTime: 600,
712+
},
713+
{ StackName: fixture.fullStackName('notification-arns') },
714+
);
715+
716+
// deploy again
717+
await fixture.cdkDeploy('notification-arns');
718+
719+
// make sure the notification arn is preserved
720+
const describeResponse = await fixture.aws.cloudFormation.send(
721+
new DescribeStacksCommand({
722+
StackName: fixture.fullStackName('notification-arns'),
723+
}),
724+
);
725+
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
726+
} finally {
727+
await fixture.aws.sns.send(
728+
new DeleteTopicCommand({
729+
TopicArn: topicArn,
730+
}),
731+
);
732+
}
733+
}));
734+
735+
integTest('deploy deletes ALL notification arns when empty array is passed', withDefaultFixture(async (fixture) => {
736+
const topicName = `${fixture.stackNamePrefix}-topic`;
737+
738+
const response = await fixture.aws.sns.send(new CreateTopicCommand({ Name: topicName }));
739+
const topicArn = response.TopicArn!;
740+
741+
try {
742+
await fixture.cdkDeploy('notification-arns', {
743+
modEnv: {
744+
INTEG_NOTIFICATION_ARNS: topicArn,
745+
},
746+
});
747+
748+
// make sure the arn was added
749+
let describeResponse = await fixture.aws.cloudFormation.send(
750+
new DescribeStacksCommand({
751+
StackName: fixture.fullStackName('notification-arns'),
670752
}),
671753
);
672754
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
755+
756+
// deploy again with empty array
757+
await fixture.cdkDeploy('notification-arns', {
758+
modEnv: {
759+
INTEG_NOTIFICATION_ARNS: '',
760+
},
761+
});
762+
763+
// make sure the arn was deleted
764+
describeResponse = await fixture.aws.cloudFormation.send(
765+
new DescribeStacksCommand({
766+
StackName: fixture.fullStackName('notification-arns'),
767+
}),
768+
);
769+
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([]);
673770
} finally {
674771
await fixture.aws.sns.send(
675772
new DeleteTopicCommand({
@@ -679,6 +776,43 @@ integTest('deploy with notification ARN as prop', withDefaultFixture(async (fixt
679776
}
680777
}));
681778

779+
integTest('deploy with notification ARN as prop and flag', withDefaultFixture(async (fixture) => {
780+
const topic1Name = `${fixture.stackNamePrefix}-topic1`;
781+
const topic2Name = `${fixture.stackNamePrefix}-topic1`;
782+
783+
const topic1Arn = (await fixture.aws.sns.send(new CreateTopicCommand({ Name: topic1Name }))).TopicArn!;
784+
const topic2Arn = (await fixture.aws.sns.send(new CreateTopicCommand({ Name: topic2Name }))).TopicArn!;
785+
786+
try {
787+
await fixture.cdkDeploy('notification-arns', {
788+
modEnv: {
789+
INTEG_NOTIFICATION_ARNS: topic1Arn,
790+
791+
},
792+
options: ['--notification-arns', topic2Arn],
793+
});
794+
795+
// verify that the stack we deployed has our notification ARN
796+
const describeResponse = await fixture.aws.cloudFormation.send(
797+
new DescribeStacksCommand({
798+
StackName: fixture.fullStackName('notification-arns'),
799+
}),
800+
);
801+
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topic1Arn, topic2Arn]);
802+
} finally {
803+
await fixture.aws.sns.send(
804+
new DeleteTopicCommand({
805+
TopicArn: topic1Arn,
806+
}),
807+
);
808+
await fixture.aws.sns.send(
809+
new DeleteTopicCommand({
810+
TopicArn: topic2Arn,
811+
}),
812+
);
813+
}
814+
}));
815+
682816
// NOTE: this doesn't currently work with modern-style synthesis, as the bootstrap
683817
// role by default will not have permission to iam:PassRole the created role.
684818
integTest(
@@ -1064,6 +1198,46 @@ integTest(
10641198
}),
10651199
);
10661200

1201+
integTest(
1202+
'cdk diff doesnt show resource metadata changes',
1203+
withDefaultFixture(async (fixture) => {
1204+
1205+
// GIVEN - small initial stack with default resource metadata
1206+
await fixture.cdkDeploy('metadata');
1207+
1208+
// WHEN - changing resource metadata value
1209+
const diff = await fixture.cdk(['diff', fixture.fullStackName('metadata')], {
1210+
verbose: true,
1211+
modEnv: {
1212+
INTEG_METADATA_VALUE: 'custom',
1213+
},
1214+
});
1215+
1216+
// Assert there are no changes
1217+
expect(diff).toContain('There were no differences');
1218+
}),
1219+
);
1220+
1221+
integTest(
1222+
'cdk diff shows resource metadata changes with --no-change-set',
1223+
withDefaultFixture(async (fixture) => {
1224+
1225+
// GIVEN - small initial stack with default resource metadata
1226+
await fixture.cdkDeploy('metadata');
1227+
1228+
// WHEN - changing resource metadata value
1229+
const diff = await fixture.cdk(['diff --no-change-set', fixture.fullStackName('metadata')], {
1230+
verbose: true,
1231+
modEnv: {
1232+
INTEG_METADATA_VALUE: 'custom',
1233+
},
1234+
});
1235+
1236+
// Assert there are changes
1237+
expect(diff).not.toContain('There were no differences');
1238+
}),
1239+
);
1240+
10671241
integTest('cdk diff with large changeset and custom toolkit stack name and qualifier does not fail', withoutBootstrap(async (fixture) => {
10681242
// Bootstrapping with custom toolkit stack name and qualifier
10691243
const qualifier = 'abc1111';

packages/aws-cdk-lib/core/README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,16 @@ const stack = new Stack(app, 'StackName', {
13321332
});
13331333
```
13341334

1335-
Stack events will be sent to any SNS Topics in this list.
1335+
Stack events will be sent to any SNS Topics in this list. These ARNs are added to those specified using
1336+
the `--notification-arns` command line option.
1337+
1338+
Note that in order to do delete notification ARNs entirely, you must pass an empty array ([]) instead of omitting it.
1339+
If you omit the property, no action on existing ARNs will take place.
1340+
1341+
> [!NOTICE]
1342+
> Adding the `notificationArns` property (or using the `--notification-arns` CLI options) will **override**
1343+
> any existing ARNs configured on the stack. If you have an external system managing notification ARNs,
1344+
> either migrate to use this mechanism, or avoid specfying notification ARNs with the CDK.
13361345

13371346
### CfnJson
13381347

packages/aws-cdk-lib/core/lib/stack.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ export class Stack extends Construct implements ITaggable {
376376
*
377377
* @internal
378378
*/
379-
public readonly _notificationArns: string[];
379+
public readonly _notificationArns?: string[];
380380

381381
/**
382382
* Logical ID generation strategy
@@ -471,7 +471,7 @@ export class Stack extends Construct implements ITaggable {
471471
}
472472
}
473473

474-
this._notificationArns = props.notificationArns ?? [];
474+
this._notificationArns = props.notificationArns;
475475

476476
if (!VALID_STACK_NAME_REGEX.test(this.stackName)) {
477477
throw new Error(`Stack name must match the regular expression: ${VALID_STACK_NAME_REGEX.toString()}, got '${this.stackName}'`);

packages/aws-cdk-lib/core/test/stack.test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,21 @@ describe('stack', () => {
20972097
]);
20982098
});
20992099

2100+
test('stack notification arns defaults to undefined', () => {
2101+
2102+
const app = new App({ stackTraces: false });
2103+
const stack1 = new Stack(app, 'stack1', {});
2104+
2105+
const asm = app.synth();
2106+
2107+
// It must be undefined and not [] because:
2108+
//
2109+
// - undefined => cdk ignores it entirely, as if it wasn't supported (allows external management).
2110+
// - []: => cdk manages it, and the user wants to wipe it out.
2111+
// - ['arn-1'] => cdk manages it, and the user wants to set it to ['arn-1'].
2112+
expect(asm.getStackArtifact(stack1.artifactId).notificationArns).toBeUndefined();
2113+
});
2114+
21002115
test('stack notification arns are reflected in the stack artifact properties', () => {
21012116
// GIVEN
21022117
const NOTIFICATION_ARNS = ['arn:aws:sns:bermuda-triangle-1337:123456789012:MyTopic'];

0 commit comments

Comments
 (0)