Skip to content

Commit 39df456

Browse files
authoredFeb 12, 2019
fix(ssm): Generate correct SSM Parameter ARN (#1726)
The SSM parameter name (`resourceName` portion of it's ARN) is required to start with a `/`, which caused the presence of a doubled `//` in the generated ARN caused by the fact `sep` defaults to `/`. This change allows `sep` to be set to an empty string, allowing SSM rendering of correct SSM parameter ARNs.
1 parent 5c11680 commit 39df456

File tree

5 files changed

+45
-6
lines changed

5 files changed

+45
-6
lines changed
 

‎packages/@aws-cdk/aws-ssm/lib/parameter.ts

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export abstract class ParameterBase extends cdk.Construct implements IParameter
119119
return cdk.Stack.find(this).formatArn({
120120
service: 'ssm',
121121
resource: 'parameter',
122+
sep: '', // Sep is empty because this.parameterName starts with a / already!
122123
resourceName: this.parameterName,
123124
});
124125
}

‎packages/@aws-cdk/aws-ssm/test/integ.parameter.lit.expected.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
{
6161
"Ref": "AWS::AccountId"
6262
},
63-
":parameter/",
63+
":parameter",
6464
{
6565
"Ref": "StringParameter472EED0E"
6666
}

‎packages/@aws-cdk/aws-ssm/test/test.parameter.ts

+21
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,25 @@ export = {
100100
}));
101101
test.done();
102102
},
103+
104+
'parameterArn is crafted correctly'(test: Test) {
105+
// GIVEN
106+
const stack = new cdk.Stack();
107+
const param = new ssm.StringParameter(stack, 'Parameter', { value: 'Foo' });
108+
109+
// THEN
110+
test.deepEqual(param.node.resolve(param.parameterArn), {
111+
'Fn::Join': ['', [
112+
'arn:',
113+
{ Ref: 'AWS::Partition' },
114+
':ssm:',
115+
{ Ref: 'AWS::Region' },
116+
':',
117+
{ Ref: 'AWS::AccountId' },
118+
':parameter',
119+
{ Ref: 'Parameter9E1B4FBA' }
120+
]]
121+
});
122+
test.done();
123+
}
103124
};

‎packages/@aws-cdk/cdk/lib/cloudformation/arn.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Stack } from './stack';
1313
*
1414
* The ARN will be formatted as follows:
1515
*
16-
* arn:{partition}:{service}:{region}:{account}:{resource}{sep}}{resource-name}
16+
* arn:{partition}:{service}:{region}:{account}:{resource}{sep}{resource-name}
1717
*
1818
* The required ARN pieces that are omitted will be taken from the stack that
1919
* the 'scope' is attached to. If all ARN pieces are supplied, the supplied scope
@@ -23,12 +23,12 @@ export function arnFromComponents(components: ArnComponents, stack: Stack): stri
2323
const partition = components.partition !== undefined ? components.partition : stack.partition;
2424
const region = components.region !== undefined ? components.region : stack.region;
2525
const account = components.account !== undefined ? components.account : stack.accountId;
26+
const sep = components.sep !== undefined ? components.sep : '/';
2627

2728
const values = [ 'arn', ':', partition, ':', components.service, ':', region, ':', account, ':', components.resource ];
2829

29-
const sep = components.sep || '/';
30-
if (sep !== '/' && sep !== ':') {
31-
throw new Error('resourcePathSep may only be ":" or "/"');
30+
if (sep !== '/' && sep !== ':' && sep !== '') {
31+
throw new Error('resourcePathSep may only be ":", "/" or an empty string');
3232
}
3333

3434
if (components.resourceName != null) {
@@ -257,7 +257,7 @@ export interface ArnComponents {
257257
/**
258258
* Separator between resource type and the resource.
259259
*
260-
* Can be either '/' or ':'. Will only be used if path is defined.
260+
* Can be either '/', ':' or an empty string. Will only be used if resourceName is defined.
261261
* @default '/'
262262
*/
263263
sep?: string;

‎packages/@aws-cdk/cdk/test/cloudformation/test.arn.ts

+17
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,23 @@ export = {
6868
test.done();
6969
},
7070

71+
'resourcePathSep can be set to "" instead of the default "/"'(test: Test) {
72+
const stack = new Stack();
73+
74+
const arn = stack.formatArn({
75+
service: 'ssm',
76+
resource: 'parameter',
77+
sep: '',
78+
resourceName: '/parameter-name'
79+
});
80+
81+
const pseudo = new Aws(stack);
82+
83+
test.deepEqual(stack.node.resolve(arn),
84+
stack.node.resolve(`arn:${pseudo.partition}:ssm:${pseudo.region}:${pseudo.accountId}:parameter/parameter-name`));
85+
test.done();
86+
},
87+
7188
'fails if resourcePathSep is neither ":" nor "/"'(test: Test) {
7289
const stack = new Stack();
7390

0 commit comments

Comments
 (0)