Skip to content

Commit 45734e3

Browse files
authored
fix(kms): aliasName references alias itself (under feature flag) (#25822)
Fixes #25761 The existing behavior was that `alias.aliasName` was always a raw string, so properties like `keyId` and `keyArn` depended on a raw string and not a reference to the alias itself. This behavior is preserved. Under a new feature flag, `const KMS_ALIAS_NAME_REF = '@aws-cdk/aws-kms:aliasNameRef'`, we instead use a reference to the `aliasName` output itself, which means that properties that depend on `aliasName` now depend on the `alias`. In turn, the `alias` depends on the `key`. This allows the expected behavior where specifying something like `alias.keyArn()` depends on the key. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 674ec01 commit 45734e3

File tree

5 files changed

+65
-35
lines changed

5 files changed

+65
-35
lines changed

packages/aws-cdk-lib/aws-codepipeline/test/artifacts.test.ts

-2
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ describe('artifacts', () => {
264264
});
265265
});
266266

267-
/* eslint-disable @aws-cdk/no-core-construct */
268267
function validate(construct: IConstruct): string[] {
269268
try {
270269
(construct.node.root as cdk.App).synth();
@@ -276,4 +275,3 @@ function validate(construct: IConstruct): string[] {
276275
return err.message.split('\n').slice(1);
277276
}
278277
}
279-
/* eslint-enable @aws-cdk/no-core-construct */

packages/aws-cdk-lib/aws-kms/lib/alias.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { Construct } from 'constructs';
22
import { IKey } from './key';
33
import { CfnAlias } from './kms.generated';
44
import * as iam from '../../aws-iam';
5-
import { RemovalPolicy, Resource, Stack, Token, Tokenization } from '../../core';
5+
import { FeatureFlags, RemovalPolicy, Resource, Stack, Token, Tokenization } from '../../core';
6+
import { KMS_ALIAS_NAME_REF } from '../../cx-api';
67

78
const REQUIRED_ALIAS_PREFIX = 'alias/';
89
const DISALLOWED_PREFIX = REQUIRED_ALIAS_PREFIX + 'aws/';
@@ -224,7 +225,11 @@ export class Alias extends AliasBase {
224225
targetKeyId: this.aliasTargetKey.keyArn,
225226
});
226227

227-
this.aliasName = this.getResourceNameAttribute(resource.aliasName);
228+
if (FeatureFlags.of(this).isEnabled(KMS_ALIAS_NAME_REF)) {
229+
this.aliasName = this.getResourceNameAttribute(resource.ref);
230+
} else {
231+
this.aliasName = this.getResourceNameAttribute(resource.aliasName);
232+
}
228233

229234
if (props.removalPolicy) {
230235
resource.applyRemovalPolicy(props.removalPolicy);

packages/aws-cdk-lib/aws-kms/test/alias.test.ts

+41-30
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Template } from '../../assertions';
33
import * as iam from '../../aws-iam';
44
import { ArnPrincipal, PolicyStatement } from '../../aws-iam';
55
import { App, Aws, CfnOutput, Stack } from '../../core';
6+
import { KMS_ALIAS_NAME_REF } from '../../cx-api';
67
import { Alias } from '../lib/alias';
78
import { IKey, Key } from '../lib/key';
89

@@ -110,8 +111,34 @@ test('fails if alias starts with "alias/aws/"', () => {
110111
})).toThrow(/Alias cannot start with alias\/aws\/: alias\/AWS\/awesome/);
111112
});
112113

114+
test('keyId includes reference to alias under feature flag', () => {
115+
// GIVEN
116+
const stack = new Stack();
117+
stack.node.setContext(KMS_ALIAS_NAME_REF, true);
118+
119+
const myKey = new Key(stack, 'MyKey', {
120+
enableKeyRotation: true,
121+
enabled: true,
122+
});
123+
const myAlias = new Alias(stack, 'MyAlias', {
124+
targetKey: myKey,
125+
aliasName: 'alias/myAlias',
126+
});
127+
128+
// WHEN
129+
new AliasOutputsConstruct(stack, 'AliasOutputsConstruct', myAlias);
130+
131+
// THEN - keyId includes reference to the alias itself
132+
Template.fromStack(stack).hasOutput('OutId', {
133+
Value: {
134+
Ref: 'MyAlias9A08CB8C',
135+
},
136+
});
137+
});
138+
113139
test('can be used wherever a key is expected', () => {
114140
const stack = new Stack();
141+
stack.node.setContext(KMS_ALIAS_NAME_REF, false);
115142

116143
const myKey = new Key(stack, 'MyKey', {
117144
enableKeyRotation: true,
@@ -122,21 +149,7 @@ test('can be used wherever a key is expected', () => {
122149
aliasName: 'alias/myAlias',
123150
});
124151

125-
/* eslint-disable @aws-cdk/no-core-construct */
126-
class MyConstruct extends Construct {
127-
constructor(scope: Construct, id: string, key: IKey) {
128-
super(scope, id);
129-
130-
new CfnOutput(stack, 'OutId', {
131-
value: key.keyId,
132-
});
133-
new CfnOutput(stack, 'OutArn', {
134-
value: key.keyArn,
135-
});
136-
}
137-
}
138-
new MyConstruct(stack, 'MyConstruct', myAlias);
139-
/* eslint-enable @aws-cdk/no-core-construct */
152+
new AliasOutputsConstruct(stack, 'AliasOutputsConstruct', myAlias);
140153

141154
Template.fromStack(stack).hasOutput('OutId', {
142155
Value: 'alias/myAlias',
@@ -161,21 +174,7 @@ test('imported alias by name - can be used where a key is expected', () => {
161174

162175
const myAlias = Alias.fromAliasName(stack, 'MyAlias', 'alias/myAlias');
163176

164-
/* eslint-disable @aws-cdk/no-core-construct */
165-
class MyConstruct extends Construct {
166-
constructor(scope: Construct, id: string, key: IKey) {
167-
super(scope, id);
168-
169-
new CfnOutput(stack, 'OutId', {
170-
value: key.keyId,
171-
});
172-
new CfnOutput(stack, 'OutArn', {
173-
value: key.keyArn,
174-
});
175-
}
176-
}
177-
new MyConstruct(stack, 'MyConstruct', myAlias);
178-
/* eslint-enable @aws-cdk/no-core-construct */
177+
new AliasOutputsConstruct(stack, 'AliasOutputsConstruct', myAlias);
179178

180179
Template.fromStack(stack).hasOutput('OutId', {
181180
Value: 'alias/myAlias',
@@ -358,3 +357,15 @@ test('does not add alias if starts with token', () => {
358357
});
359358
});
360359

360+
class AliasOutputsConstruct extends Construct {
361+
constructor(scope: Construct, id: string, key: IKey) {
362+
super(scope, id);
363+
364+
new CfnOutput(scope, 'OutId', {
365+
value: key.keyId,
366+
});
367+
new CfnOutput(scope, 'OutArn', {
368+
value: key.keyArn,
369+
});
370+
}
371+
}

packages/aws-cdk-lib/core/lib/feature-flags.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as cxapi from '../../cx-api';
44
/**
55
* Features that are implemented behind a flag in order to preserve backwards
66
* compatibility for existing apps. The list of flags are available in the
7-
* `@aws-cdk/cx-api` module.
7+
* `aws-cdk-lib/cx-api` module.
88
*
99
* The state of the flag for this application is stored as a CDK context variable.
1010
*/

packages/aws-cdk-lib/cx-api/lib/features.ts

+16
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export const REDSHIFT_COLUMN_ID = '@aws-cdk/aws-redshift:columnId';
8686
export const ENABLE_EMR_SERVICE_POLICY_V2 = '@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2';
8787
export const EC2_RESTRICT_DEFAULT_SECURITY_GROUP = '@aws-cdk/aws-ec2:restrictDefaultSecurityGroup';
8888
export const APIGATEWAY_REQUEST_VALIDATOR_UNIQUE_ID = '@aws-cdk/aws-apigateway:requestValidatorUniqueId';
89+
export const KMS_ALIAS_NAME_REF = '@aws-cdk/aws-kms:aliasNameRef';
8990

9091
export const FLAGS: Record<string, FlagInfo> = {
9192
//////////////////////////////////////////////////////////////////////
@@ -788,6 +789,21 @@ export const FLAGS: Record<string, FlagInfo> = {
788789
introducedIn: { v2: 'V2·NEXT' },
789790
recommendedValue: true,
790791
},
792+
793+
//////////////////////////////////////////////////////////////////////
794+
[KMS_ALIAS_NAME_REF]: {
795+
type: FlagType.BugFix,
796+
summary: 'KMS Alias name and keyArn will have implicit reference to KMS Key',
797+
detailsMd: `
798+
This flag allows an implicit dependency to be created between KMS Alias and KMS Key
799+
when referencing key.aliasName or key.keyArn.
800+
801+
If the flag is not set then a raw string is passed as the Alias name and no
802+
implicit dependencies will be set.
803+
`,
804+
introducedIn: { v2: 'V2·NEXT' },
805+
recommendedValue: true,
806+
},
791807
};
792808

793809
const CURRENT_MV = 'v2';

0 commit comments

Comments
 (0)