Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(release): 2.167.2 #32177

Merged
merged 5 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.v2.alpha.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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.

### [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)

## [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)

## [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)
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

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.

### [2.167.2](https://github.com/aws/aws-cdk/compare/v2.167.1...v2.167.2) (2024-11-18)


### Bug Fixes

* **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))
* **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))
* **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))

## [2.167.1](https://github.com/aws/aws-cdk/compare/v2.167.0...v2.167.1) (2024-11-14)


Expand Down
8 changes: 7 additions & 1 deletion allowed-breaking-changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -936,4 +936,10 @@ removed:aws-cdk-lib.aws_ec2.WindowsVersion.WINDOWS_SERVER_2022_TURKISH_FULL_BASE

# null() return a [] which is invalid filter rule. It should return [null].
# Hence the return type changes from string[] to any
change-return-type:aws-cdk-lib.aws_lambda.FilterRule.null
change-return-type:aws-cdk-lib.aws_lambda.FilterRule.null


# output property was mistakenly marked as required even though it should have allowed
# for undefined, i.e optional
changed-type:@aws-cdk/cx-api.CloudFormationStackArtifact.notificationArns
changed-type:aws-cdk-lib.cx_api.CloudFormationStackArtifact.notificationArns
Original file line number Diff line number Diff line change
Expand Up @@ -742,12 +742,23 @@ class BuiltinLambdaStack extends cdk.Stack {
}
}

class NotificationArnPropStack extends cdk.Stack {
class NotificationArnsStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
new sns.Topic(this, 'topic');

const arnsFromEnv = process.env.INTEG_NOTIFICATION_ARNS;
super(parent, id, {
...props,
// comma separated list of arns.
// empty string means empty list.
// undefined means undefined
notificationArns: arnsFromEnv == '' ? [] : (arnsFromEnv ? arnsFromEnv.split(',') : undefined)
});

new cdk.CfnWaitConditionHandle(this, 'WaitConditionHandle');

}
}

class AppSyncHotswapStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
Expand Down Expand Up @@ -776,6 +787,15 @@ class AppSyncHotswapStack extends cdk.Stack {
}
}

class MetadataStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
const handle = new cdk.CfnWaitConditionHandle(this, 'WaitConditionHandle');
handle.addMetadata('Key', process.env.INTEG_METADATA_VALUE ?? 'default')

}
}

const app = new cdk.App({
context: {
'@aws-cdk/core:assetHashSalt': process.env.CODEBUILD_BUILD_ID, // Force all assets to be unique, but consistent in one build
Expand Down Expand Up @@ -830,9 +850,7 @@ switch (stackSet) {
new DockerInUseStack(app, `${stackPrefix}-docker-in-use`);
new DockerStackWithCustomFile(app, `${stackPrefix}-docker-with-custom-file`);

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

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

new BundlingStage(app, `${stackPrefix}-bundling-stage`);

new MetadataStack(app, `${stackPrefix}-metadata`);
break;

case 'stage-using-context':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
DescribeStacksCommand,
GetTemplateCommand,
ListChangeSetsCommand,
UpdateStackCommand,
waitUntilStackUpdateComplete,
} from '@aws-sdk/client-cloudformation';
import { DescribeServicesCommand } from '@aws-sdk/client-ecs';
import {
Expand Down Expand Up @@ -633,14 +635,14 @@ integTest(
const topicArn = response.TopicArn!;

try {
await fixture.cdkDeploy('test-2', {
await fixture.cdkDeploy('notification-arns', {
options: ['--notification-arns', topicArn],
});

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

try {
await fixture.cdkDeploy('notification-arn-prop');
await fixture.cdkDeploy('notification-arns', {
modEnv: {
INTEG_NOTIFICATION_ARNS: topicArn,

},
});

// verify that the stack we deployed has our notification ARN
const describeResponse = await fixture.aws.cloudFormation.send(
new DescribeStacksCommand({
StackName: fixture.fullStackName('notification-arn-prop'),
StackName: fixture.fullStackName('notification-arns'),
}),
);
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
} finally {
await fixture.aws.sns.send(
new DeleteTopicCommand({
TopicArn: topicArn,
}),
);
}
}));

// https://github.com/aws/aws-cdk/issues/32153
integTest('deploy preserves existing notification arns when not specified', withDefaultFixture(async (fixture) => {
const topicName = `${fixture.stackNamePrefix}-topic`;

const response = await fixture.aws.sns.send(new CreateTopicCommand({ Name: topicName }));
const topicArn = response.TopicArn!;

try {
await fixture.cdkDeploy('notification-arns');

// add notification arns externally to cdk
await fixture.aws.cloudFormation.send(
new UpdateStackCommand({
StackName: fixture.fullStackName('notification-arns'),
UsePreviousTemplate: true,
NotificationARNs: [topicArn],
}),
);

await waitUntilStackUpdateComplete(
{
client: fixture.aws.cloudFormation,
maxWaitTime: 600,
},
{ StackName: fixture.fullStackName('notification-arns') },
);

// deploy again
await fixture.cdkDeploy('notification-arns');

// make sure the notification arn is preserved
const describeResponse = await fixture.aws.cloudFormation.send(
new DescribeStacksCommand({
StackName: fixture.fullStackName('notification-arns'),
}),
);
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
} finally {
await fixture.aws.sns.send(
new DeleteTopicCommand({
TopicArn: topicArn,
}),
);
}
}));

integTest('deploy deletes ALL notification arns when empty array is passed', withDefaultFixture(async (fixture) => {
const topicName = `${fixture.stackNamePrefix}-topic`;

const response = await fixture.aws.sns.send(new CreateTopicCommand({ Name: topicName }));
const topicArn = response.TopicArn!;

try {
await fixture.cdkDeploy('notification-arns', {
modEnv: {
INTEG_NOTIFICATION_ARNS: topicArn,
},
});

// make sure the arn was added
let describeResponse = await fixture.aws.cloudFormation.send(
new DescribeStacksCommand({
StackName: fixture.fullStackName('notification-arns'),
}),
);
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);

// deploy again with empty array
await fixture.cdkDeploy('notification-arns', {
modEnv: {
INTEG_NOTIFICATION_ARNS: '',
},
});

// make sure the arn was deleted
describeResponse = await fixture.aws.cloudFormation.send(
new DescribeStacksCommand({
StackName: fixture.fullStackName('notification-arns'),
}),
);
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([]);
} finally {
await fixture.aws.sns.send(
new DeleteTopicCommand({
Expand All @@ -679,6 +776,43 @@ integTest('deploy with notification ARN as prop', withDefaultFixture(async (fixt
}
}));

integTest('deploy with notification ARN as prop and flag', withDefaultFixture(async (fixture) => {
const topic1Name = `${fixture.stackNamePrefix}-topic1`;
const topic2Name = `${fixture.stackNamePrefix}-topic1`;

const topic1Arn = (await fixture.aws.sns.send(new CreateTopicCommand({ Name: topic1Name }))).TopicArn!;
const topic2Arn = (await fixture.aws.sns.send(new CreateTopicCommand({ Name: topic2Name }))).TopicArn!;

try {
await fixture.cdkDeploy('notification-arns', {
modEnv: {
INTEG_NOTIFICATION_ARNS: topic1Arn,

},
options: ['--notification-arns', topic2Arn],
});

// verify that the stack we deployed has our notification ARN
const describeResponse = await fixture.aws.cloudFormation.send(
new DescribeStacksCommand({
StackName: fixture.fullStackName('notification-arns'),
}),
);
expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topic1Arn, topic2Arn]);
} finally {
await fixture.aws.sns.send(
new DeleteTopicCommand({
TopicArn: topic1Arn,
}),
);
await fixture.aws.sns.send(
new DeleteTopicCommand({
TopicArn: topic2Arn,
}),
);
}
}));

// NOTE: this doesn't currently work with modern-style synthesis, as the bootstrap
// role by default will not have permission to iam:PassRole the created role.
integTest(
Expand Down Expand Up @@ -1064,6 +1198,46 @@ integTest(
}),
);

integTest(
'cdk diff doesnt show resource metadata changes',
withDefaultFixture(async (fixture) => {

// GIVEN - small initial stack with default resource metadata
await fixture.cdkDeploy('metadata');

// WHEN - changing resource metadata value
const diff = await fixture.cdk(['diff', fixture.fullStackName('metadata')], {
verbose: true,
modEnv: {
INTEG_METADATA_VALUE: 'custom',
},
});

// Assert there are no changes
expect(diff).toContain('There were no differences');
}),
);

integTest(
'cdk diff shows resource metadata changes with --no-change-set',
withDefaultFixture(async (fixture) => {

// GIVEN - small initial stack with default resource metadata
await fixture.cdkDeploy('metadata');

// WHEN - changing resource metadata value
const diff = await fixture.cdk(['diff --no-change-set', fixture.fullStackName('metadata')], {
verbose: true,
modEnv: {
INTEG_METADATA_VALUE: 'custom',
},
});

// Assert there are changes
expect(diff).not.toContain('There were no differences');
}),
);

integTest('cdk diff with large changeset and custom toolkit stack name and qualifier does not fail', withoutBootstrap(async (fixture) => {
// Bootstrapping with custom toolkit stack name and qualifier
const qualifier = 'abc1111';
Expand Down
11 changes: 10 additions & 1 deletion packages/aws-cdk-lib/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,16 @@ const stack = new Stack(app, 'StackName', {
});
```

Stack events will be sent to any SNS Topics in this list.
Stack events will be sent to any SNS Topics in this list. These ARNs are added to those specified using
the `--notification-arns` command line option.

Note that in order to do delete notification ARNs entirely, you must pass an empty array ([]) instead of omitting it.
If you omit the property, no action on existing ARNs will take place.

> [!NOTICE]
> Adding the `notificationArns` property (or using the `--notification-arns` CLI options) will **override**
> any existing ARNs configured on the stack. If you have an external system managing notification ARNs,
> either migrate to use this mechanism, or avoid specfying notification ARNs with the CDK.

### CfnJson

Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/core/lib/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ export class Stack extends Construct implements ITaggable {
*
* @internal
*/
public readonly _notificationArns: string[];
public readonly _notificationArns?: string[];

/**
* Logical ID generation strategy
Expand Down Expand Up @@ -471,7 +471,7 @@ export class Stack extends Construct implements ITaggable {
}
}

this._notificationArns = props.notificationArns ?? [];
this._notificationArns = props.notificationArns;

if (!VALID_STACK_NAME_REGEX.test(this.stackName)) {
throw new Error(`Stack name must match the regular expression: ${VALID_STACK_NAME_REGEX.toString()}, got '${this.stackName}'`);
Expand Down
15 changes: 15 additions & 0 deletions packages/aws-cdk-lib/core/test/stack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,21 @@ describe('stack', () => {
]);
});

test('stack notification arns defaults to undefined', () => {

const app = new App({ stackTraces: false });
const stack1 = new Stack(app, 'stack1', {});

const asm = app.synth();

// It must be undefined and not [] because:
//
// - undefined => cdk ignores it entirely, as if it wasn't supported (allows external management).
// - []: => cdk manages it, and the user wants to wipe it out.
// - ['arn-1'] => cdk manages it, and the user wants to set it to ['arn-1'].
expect(asm.getStackArtifact(stack1.artifactId).notificationArns).toBeUndefined();
});

test('stack notification arns are reflected in the stack artifact properties', () => {
// GIVEN
const NOTIFICATION_ARNS = ['arn:aws:sns:bermuda-triangle-1337:123456789012:MyTopic'];
Expand Down
Loading
Loading