Skip to content

Commit 3f86603

Browse files
authored
fix: remove CloudFormation property renames (#973)
The construct id parameter used to be a property called `name` in the props object, and so properties called `name` were renamed to `xxxName` (where `xxx` is the name of the resource). Since we now pass names as a constructor argument, we can get rid of the properly rename mechanism. BREAKING CHANGE: if you use L1s, you may need to change some `XxxName` properties back into `Name`. These will match the CloudFormation property names. Fixes #852.
1 parent 770f9aa commit 3f86603

File tree

17 files changed

+37
-92
lines changed

17 files changed

+37
-92
lines changed

packages/@aws-cdk/aws-apigateway/lib/restapi.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ export class RestApi extends RestApiRef implements cdk.IDependable {
176176
super(parent, id);
177177

178178
const resource = new cloudformation.RestApiResource(this, 'Resource', {
179-
restApiName: props.restApiName || id,
179+
name: props.restApiName || id,
180180
description: props.description,
181181
policy: props.policy,
182182
failOnWarnings: props.failOnWarnings,

packages/@aws-cdk/aws-codebuild/lib/project.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ export class Project extends ProjectRef {
522522
encryptionKey: props.encryptionKey && props.encryptionKey.keyArn,
523523
badgeEnabled: props.badge,
524524
cache,
525-
projectName: props.projectName,
525+
name: props.projectName,
526526
});
527527

528528
this.projectArn = resource.projectArn;

packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class Pipeline extends cdk.Construct implements events.IEventRuleTarget {
9797
stages: new cdk.Token(() => this.renderStages()) as any,
9898
roleArn: this.role.roleArn,
9999
restartExecutionOnUpdate: props && props.restartExecutionOnUpdate,
100-
pipelineName: props && props.pipelineName,
100+
name: props && props.pipelineName,
101101
});
102102

103103
// this will produce a DependsOn for both the role and the policy resources.

packages/@aws-cdk/aws-events/lib/rule.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class EventRule extends EventRuleRef {
7474
super(parent, name);
7575

7676
const resource = new cloudformation.RuleResource(this, 'Resource', {
77-
ruleName: props.ruleName,
77+
name: props.ruleName,
7878
description: props.description,
7979
state: props.enabled == null ? 'ENABLED' : (props.enabled ? 'ENABLED' : 'DISABLED'),
8080
scheduleExpression: new Token(() => this.scheduleExpression),

packages/@aws-cdk/aws-kinesis/lib/stream.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ export class Stream extends StreamRef {
297297
const { streamEncryption, encryptionKey } = this.parseEncryption(props);
298298

299299
this.stream = new cloudformation.StreamResource(this, "Resource", {
300-
streamName: props.streamName,
300+
name: props.streamName,
301301
retentionPeriodHours,
302302
shardCount,
303303
streamEncryption

packages/@aws-cdk/aws-lambda/lib/alias.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class Alias extends FunctionRef {
8686
this.underlyingLambda = props.version.lambda;
8787

8888
const alias = new cloudformation.AliasResource(this, 'Resource', {
89-
aliasName: props.aliasName,
89+
name: props.aliasName,
9090
description: props.description,
9191
functionName: this.underlyingLambda.functionName,
9292
functionVersion: props.version.functionVersion,

packages/@aws-cdk/aws-route53/lib/hosted-zone.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ function toVpcProperty(vpc: ec2.VpcNetworkRef): cloudformation.HostedZoneResourc
125125
}
126126

127127
function determineHostedZoneProps(props: PublicHostedZoneProps) {
128-
const hostedZoneName = props.zoneName + '.';
128+
const name = props.zoneName + '.';
129129
const hostedZoneConfig = props.comment ? { comment: props.comment } : undefined;
130130
const queryLoggingConfig = props.queryLogsLogGroupArn ? { cloudWatchLogsLogGroupArn: props.queryLogsLogGroupArn } : undefined;
131131

132-
return { hostedZoneName, hostedZoneConfig, queryLoggingConfig };
132+
return { name, hostedZoneConfig, queryLoggingConfig };
133133
}

packages/@aws-cdk/aws-route53/lib/records/txt.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class TXTRecord extends Construct {
2323

2424
new cloudformation.RecordSetResource(this, 'Resource', {
2525
hostedZoneId: parent.hostedZoneId,
26-
recordSetName: determineFullyQualifiedDomainName(props.recordName, parent),
26+
name: determineFullyQualifiedDomainName(props.recordName, parent),
2727
type: 'TXT',
2828
resourceRecords: [recordValue],
2929
ttl: ttl.toString()

packages/@aws-cdk/aws-route53/lib/records/zone-delegation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export class ZoneDelegationRecord extends Construct {
4040

4141
new cloudformation.RecordSetResource(this, 'Resource', {
4242
hostedZoneId: parent.hostedZoneId,
43-
recordSetName: determineFullyQualifiedDomainName(props.delegatedZoneName, parent),
43+
name: determineFullyQualifiedDomainName(props.delegatedZoneName, parent),
4444
type: 'NS',
4545
ttl: ttl.toString(),
4646
comment: props.comment,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { expect, haveResource } from '@aws-cdk/assert';
2+
import cdk = require('@aws-cdk/cdk');
3+
import { Test } from 'nodeunit';
4+
import ssm = require('../lib');
5+
6+
export = {
7+
'association name is rendered properly in L1 construct'(test: Test) {
8+
// GIVEN
9+
const stack = new cdk.Stack();
10+
11+
// WHEN
12+
new ssm.cloudformation.AssociationResource(stack, 'Assoc', {
13+
name: 'document',
14+
});
15+
16+
// THEN
17+
expect(stack).to(haveResource('AWS::SSM::Association', {
18+
Name: 'document',
19+
}));
20+
test.done();
21+
}
22+
};

packages/@aws-cdk/aws-stepfunctions/lib/activity.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class Activity extends cdk.Construct implements IStepFunctionsTaskResourc
2323
super(parent, id);
2424

2525
const resource = new cloudformation.ActivityResource(this, 'Resource', {
26-
activityName: props.activityName || this.generateName()
26+
name: props.activityName || this.generateName()
2727
});
2828

2929
this.activityArn = resource.activityArn;

packages/@aws-cdk/cdk/lib/cloudformation/resource.ts

-6
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ export class Resource extends Referenceable {
8686

8787
this.resourceType = props.type;
8888
this.properties = props.properties || { };
89-
90-
// 'name' is a special property included for resource constructs and passed
91-
// as 'name', but we don't want it to be serialized into the template.
92-
if (this.properties.name) {
93-
delete this.properties.name;
94-
}
9589
}
9690

9791
/**

packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts

-16
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,6 @@ export = {
240240
test.done();
241241
},
242242

243-
'the "name" property is deleted when synthesizing into a CloudFormation resource'(test: Test) {
244-
const stack = new Stack();
245-
246-
new Resource(stack, 'Bla', {
247-
type: 'MyResource',
248-
properties: {
249-
Prop1: 'value1',
250-
name: 'Bla'
251-
}
252-
});
253-
254-
test.deepEqual(stack.toCloudFormation(), { Resources:
255-
{ Bla: { Type: 'MyResource', Properties: { Prop1: 'value1' } } } });
256-
test.done();
257-
},
258-
259243
'removal policy is a high level abstraction of deletion policy used by l2'(test: Test) {
260244
const stack = new Stack();
261245

packages/@aws-cdk/cfnspec/spec-source/500_SSM_AssociationName_patch.json

-16
This file was deleted.

packages/@aws-cdk/cfnspec/spec-source/500_SSM_AssociationName_patch.md

-9
This file was deleted.

packages/@aws-cdk/runtime-values/lib/rtv.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class RuntimeValue extends cdk.Construct {
5757
this.parameterName = `/rtv/${new cdk.AwsStackName()}/${props.package}/${name}`;
5858

5959
new ssm.cloudformation.ParameterResource(this, 'Parameter', {
60-
parameterName: this.parameterName,
60+
name: this.parameterName,
6161
type: 'String',
6262
value: props.value,
6363
});

tools/cfn2ts/lib/codegen.ts

+3-33
Original file line numberDiff line numberDiff line change
@@ -144,28 +144,13 @@ export default class CodeGenerator {
144144
private emitPropsTypeProperties(resourceName: SpecName, propertiesSpec: { [name: string]: schema.Property }): Dictionary<string> {
145145
const propertyMap: Dictionary<string> = {};
146146

147-
// Sanity check that our renamed "Name" is not going to conflict with a real property
148-
const renamedNameProperty = resourceNameProperty(resourceName);
149-
const lowerNames = Object.keys(propertiesSpec).map(s => s.toLowerCase());
150-
if (lowerNames.indexOf('name') !== -1 && lowerNames.indexOf(renamedNameProperty.toLowerCase()) !== -1) {
151-
// tslint:disable-next-line:max-line-length
152-
throw new Error(`Oh gosh, we want to rename ${resourceName.fqn}'s 'Name' property to '${renamedNameProperty}', but that property already exists! We need to find a solution to this problem.`);
153-
}
154-
155147
Object.keys(propertiesSpec).sort(propertyComparator).forEach(propName => {
156-
const originalName = propName;
157148
const propSpec = propertiesSpec[propName];
158149
const additionalDocs = resourceName.relativeName(propName).fqn;
159150

160-
if (propName.toLocaleLowerCase() === 'name') {
161-
propName = renamedNameProperty;
162-
// tslint:disable-next-line:no-console
163-
console.error(`Renamed property 'Name' of ${resourceName.fqn} to '${renamedNameProperty}'`);
164-
}
165-
166151
const resourceCodeName = genspec.CodeName.forResource(resourceName);
167152
const newName = this.emitProperty(resourceCodeName, propName, propSpec, quoteCode(additionalDocs));
168-
propertyMap[originalName] = newName;
153+
propertyMap[propName] = newName;
169154
});
170155
return propertyMap;
171156

@@ -270,10 +255,9 @@ export default class CodeGenerator {
270255
this.code.line(`super(parent, name, { type: ${resourceName.className}.resourceTypeName${propsType ? ', properties' : ''} });`);
271256
// verify all required properties
272257
if (spec.Properties) {
273-
for (const pname of Object.keys(spec.Properties)) {
274-
const prop = spec.Properties[pname];
258+
for (const propName of Object.keys(spec.Properties)) {
259+
const prop = spec.Properties[propName];
275260
if (prop.Required) {
276-
const propName = pname.toLocaleLowerCase() === 'name' ? resourceNameProperty(resourceName.specName!) : pname;
277261
this.code.line(`${CORE}.requireProperty(properties, '${genspec.cloudFormationToScriptName(propName)}', this);`);
278262
}
279263
}
@@ -633,20 +617,6 @@ function mapperNames(types: genspec.CodeName[]): string {
633617
return types.map(type => genspec.cfnMapperName(type).fqn).join(', ');
634618
}
635619

636-
/**
637-
* Return the name of the literal "name" property of a resource
638-
*
639-
* A number of resources have a "Name" property. Since Constructs already have a "Name" property
640-
* (which means something different), we must call the original property something else.
641-
*
642-
* We name it after the resource, so for a bucket the "Name" property gets renamed to "BucketName".
643-
*
644-
* (We can leave the name PascalCased, as it's going to be camelCased later).
645-
*/
646-
function resourceNameProperty(resourceName: SpecName) {
647-
return `${resourceName.resourceName}Name`;
648-
}
649-
650620
/**
651621
* Quotes a code name for inclusion in a JSDoc comment, so it will render properly
652622
* in the Sphinx output.

0 commit comments

Comments
 (0)