1
+ // tslint:disable: max-line-length
2
+
1
3
import { expect , haveResource } from '@aws-cdk/assert' ;
2
4
import iam = require( '@aws-cdk/aws-iam' ) ;
3
5
import kms = require( '@aws-cdk/aws-kms' ) ;
@@ -36,7 +38,7 @@ export = {
36
38
37
39
// THEN
38
40
test . throws ( ( ) => new ssm . StringParameter ( stack , 'Parameter' , { allowedPattern : '^Bar$' , stringValue : 'FooBar' } ) ,
39
- / d o e s n o t m a t c h t h e s p e c i f i e d a l l o w e d P a t t e r n / ) ;
41
+ / d o e s n o t m a t c h t h e s p e c i f i e d a l l o w e d P a t t e r n / ) ;
40
42
test . done ( ) ;
41
43
} ,
42
44
@@ -46,9 +48,9 @@ export = {
46
48
47
49
// THEN
48
50
test . doesNotThrow ( ( ) => {
49
- new ssm . StringParameter ( stack , 'Parameter' , {
50
- allowedPattern : '^Bar$' ,
51
- stringValue : cdk . Lazy . stringValue ( { produce : ( ) => 'Foo!' } ) ,
51
+ new ssm . StringParameter ( stack , 'Parameter' , {
52
+ allowedPattern : '^Bar$' ,
53
+ stringValue : cdk . Lazy . stringValue ( { produce : ( ) => 'Foo!' } ) ,
52
54
} ) ;
53
55
} ) ;
54
56
test . done ( ) ;
@@ -83,7 +85,7 @@ export = {
83
85
84
86
// THEN
85
87
test . throws ( ( ) => new ssm . StringListParameter ( stack , 'Parameter' , { stringListValue : [ 'Foo,Bar' ] } ) ,
86
- / c a n n o t c o n t a i n t h e ' , ' c h a r a c t e r / ) ;
88
+ / c a n n o t c o n t a i n t h e ' , ' c h a r a c t e r / ) ;
87
89
test . done ( ) ;
88
90
} ,
89
91
@@ -93,7 +95,7 @@ export = {
93
95
94
96
// THEN
95
97
test . throws ( ( ) => new ssm . StringListParameter ( stack , 'Parameter' , { allowedPattern : '^(Foo|Bar)$' , stringListValue : [ 'Foo' , 'FooBar' ] } ) ,
96
- / d o e s n o t m a t c h t h e s p e c i f i e d a l l o w e d P a t t e r n / ) ;
98
+ / d o e s n o t m a t c h t h e s p e c i f i e d a l l o w e d P a t t e r n / ) ;
97
99
test . done ( ) ;
98
100
} ,
99
101
@@ -130,6 +132,24 @@ export = {
130
132
test . done ( ) ;
131
133
} ,
132
134
135
+ 'parameterName that includes a "/" must be fully qualified (i.e. begin with "/") as well' ( test : Test ) {
136
+ // GIVEN
137
+ const stack = new cdk . Stack ( ) ;
138
+
139
+ // THEN
140
+ test . throws ( ( ) => new ssm . StringParameter ( stack , 'myParam' , {
141
+ stringValue : 'myValue' ,
142
+ parameterName : 'path/to/parameter' ,
143
+ } ) , / P a r a m e t e r n a m e s m u s t b e f u l l y q u a l i f i e d / ) ;
144
+
145
+ test . throws ( ( ) => new ssm . StringListParameter ( stack , 'myParam2' , {
146
+ stringListValue : [ 'foo' , 'bar' ] ,
147
+ parameterName : 'path/to/parameter2'
148
+ } ) , / P a r a m e t e r n a m e s m u s t b e f u l l y q u a l i f i e d \( i f t h e y i n c l u d e \" \/ \" t h e y m u s t a l s o b e g i n w i t h a \" \/ \" \) \: p a t h \/ t o \/ p a r a m e t e r 2 / ) ;
149
+
150
+ test . done ( ) ;
151
+ } ,
152
+
133
153
'StringParameter.fromStringParameterName' ( test : Test ) {
134
154
// GIVEN
135
155
const stack = new Stack ( ) ;
@@ -139,14 +159,14 @@ export = {
139
159
140
160
// THEN
141
161
test . deepEqual ( stack . resolve ( param . parameterArn ) , {
142
- 'Fn::Join' : [ '' , [
162
+ 'Fn::Join' : [ '' , [
143
163
'arn:' ,
144
164
{ Ref : 'AWS::Partition' } ,
145
165
':ssm:' ,
146
166
{ Ref : 'AWS::Region' } ,
147
167
':' ,
148
168
{ Ref : 'AWS::AccountId' } ,
149
- ':parameter/MyParamName' ] ]
169
+ ':parameter/MyParamName' ] ]
150
170
} ) ;
151
171
test . deepEqual ( stack . resolve ( param . parameterName ) , 'MyParamName' ) ;
152
172
test . deepEqual ( stack . resolve ( param . parameterType ) , 'String' ) ;
@@ -174,14 +194,14 @@ export = {
174
194
175
195
// THEN
176
196
test . deepEqual ( stack . resolve ( param . parameterArn ) , {
177
- 'Fn::Join' : [ '' , [
197
+ 'Fn::Join' : [ '' , [
178
198
'arn:' ,
179
199
{ Ref : 'AWS::Partition' } ,
180
200
':ssm:' ,
181
201
{ Ref : 'AWS::Region' } ,
182
202
':' ,
183
203
{ Ref : 'AWS::AccountId' } ,
184
- ':parameter/MyParamName' ] ]
204
+ ':parameter/MyParamName' ] ]
185
205
} ) ;
186
206
test . deepEqual ( stack . resolve ( param . parameterName ) , 'MyParamName' ) ;
187
207
test . deepEqual ( stack . resolve ( param . parameterType ) , 'String' ) ;
@@ -201,14 +221,14 @@ export = {
201
221
202
222
// THEN
203
223
test . deepEqual ( stack . resolve ( param . parameterArn ) , {
204
- 'Fn::Join' : [ '' , [
224
+ 'Fn::Join' : [ '' , [
205
225
'arn:' ,
206
226
{ Ref : 'AWS::Partition' } ,
207
227
':ssm:' ,
208
228
{ Ref : 'AWS::Region' } ,
209
229
':' ,
210
230
{ Ref : 'AWS::AccountId' } ,
211
- ':parameter/MyParamName' ] ]
231
+ ':parameter/MyParamName' ] ]
212
232
} ) ;
213
233
test . deepEqual ( stack . resolve ( param . parameterName ) , 'MyParamName' ) ;
214
234
test . deepEqual ( stack . resolve ( param . parameterType ) , 'SecureString' ) ;
@@ -348,25 +368,25 @@ export = {
348
368
349
369
// THEN
350
370
test . deepEqual ( stack . resolve ( param . parameterArn ) , {
351
- 'Fn::Join' : [ '' , [
371
+ 'Fn::Join' : [ '' , [
352
372
'arn:' ,
353
373
{ Ref : 'AWS::Partition' } ,
354
374
':ssm:' ,
355
375
{ Ref : 'AWS::Region' } ,
356
376
':' ,
357
377
{ Ref : 'AWS::AccountId' } ,
358
- ':parameter/MyParamName' ] ]
378
+ ':parameter/MyParamName' ] ]
359
379
} ) ;
360
380
test . deepEqual ( stack . resolve ( param . parameterName ) , 'MyParamName' ) ;
361
381
test . deepEqual ( stack . resolve ( param . parameterType ) , 'StringList' ) ;
362
- test . deepEqual ( stack . resolve ( param . stringListValue ) , { 'Fn::Split' : [ ',' , '{{resolve:ssm:MyParamName}}' ] } ) ;
382
+ test . deepEqual ( stack . resolve ( param . stringListValue ) , { 'Fn::Split' : [ ',' , '{{resolve:ssm:MyParamName}}' ] } ) ;
363
383
test . done ( ) ;
364
384
} ,
365
385
366
386
'fromLookup will use the SSM context provider to read value during synthesis' ( test : Test ) {
367
387
// GIVEN
368
388
const app = new App ( ) ;
369
- const stack = new Stack ( app , 'my-staq' , { env : { region : 'us-east-1' , account : '12344' } } ) ;
389
+ const stack = new Stack ( app , 'my-staq' , { env : { region : 'us-east-1' , account : '12344' } } ) ;
370
390
371
391
// WHEN
372
392
const value = ssm . StringParameter . valueFromLookup ( stack , 'my-param-name' ) ;
@@ -450,38 +470,104 @@ export = {
450
470
'rendering of parameter arns' ( test : Test ) {
451
471
const stack = new Stack ( ) ;
452
472
const param = new CfnParameter ( stack , 'param' ) ;
453
- const expectedA = { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/bam' ] ] } ;
454
- const expectedB = { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'param' } ] ] } ;
473
+ const expectedA = { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/bam' ] ] } ;
474
+ const expectedB = { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'param' } ] ] } ;
475
+ const expectedC = { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter' , { Ref : 'param' } ] ] } ;
455
476
let i = 0 ;
456
477
457
478
// WHEN
458
479
const case1 = ssm . StringParameter . fromStringParameterName ( stack , `p${ i ++ } ` , 'bam' ) ;
459
480
const case2 = ssm . StringParameter . fromStringParameterName ( stack , `p${ i ++ } ` , '/bam' ) ;
460
- const case3 = ssm . StringParameter . fromStringParameterName ( stack , `p${ i ++ } ` , param . valueAsString ) ;
461
481
const case4 = ssm . StringParameter . fromStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : 'bam' } ) ;
462
482
const case5 = ssm . StringParameter . fromStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : '/bam' } ) ;
463
- const case6 = ssm . StringParameter . fromStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString } ) ;
483
+ const case6 = ssm . StringParameter . fromStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , simpleName : true } ) ;
464
484
const case7 = ssm . StringParameter . fromSecureStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : 'bam' , version : 10 } ) ;
465
485
const case8 = ssm . StringParameter . fromSecureStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : '/bam' , version : 10 } ) ;
466
- const case9 = ssm . StringParameter . fromSecureStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , version : 10 } ) ;
486
+ const case9 = ssm . StringParameter . fromSecureStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , version : 10 , simpleName : false } ) ;
487
+
488
+ // auto-generated name is always generated as a "simple name" (not/a/path)
467
489
const case10 = new ssm . StringParameter ( stack , `p${ i ++ } ` , { stringValue : 'value' } ) ;
468
490
491
+ // explicitly named physical name gives us a hint on how to render the ARN
492
+ const case11 = new ssm . StringParameter ( stack , `p${ i ++ } ` , { parameterName : '/foo/bar' , stringValue : 'hello' } ) ;
493
+ const case12 = new ssm . StringParameter ( stack , `p${ i ++ } ` , { parameterName : 'simple-name' , stringValue : 'hello' } ) ;
494
+
495
+ const case13 = new ssm . StringListParameter ( stack , `p${ i ++ } ` , { stringListValue : [ 'hello' , 'world' ] } ) ;
496
+ const case14 = new ssm . StringListParameter ( stack , `p${ i ++ } ` , { parameterName : '/not/simple' , stringListValue : [ 'hello' , 'world' ] } ) ;
497
+ const case15 = new ssm . StringListParameter ( stack , `p${ i ++ } ` , { parameterName : 'simple' , stringListValue : [ 'hello' , 'world' ] } ) ;
498
+
469
499
// THEN
470
500
test . deepEqual ( stack . resolve ( case1 . parameterArn ) , expectedA ) ;
471
501
test . deepEqual ( stack . resolve ( case2 . parameterArn ) , expectedA ) ;
472
- test . deepEqual ( stack . resolve ( case3 . parameterArn ) , expectedB ) ;
473
502
test . deepEqual ( stack . resolve ( case4 . parameterArn ) , expectedA ) ;
474
503
test . deepEqual ( stack . resolve ( case5 . parameterArn ) , expectedA ) ;
475
504
test . deepEqual ( stack . resolve ( case6 . parameterArn ) , expectedB ) ;
476
505
test . deepEqual ( stack . resolve ( case7 . parameterArn ) , expectedA ) ;
477
506
test . deepEqual ( stack . resolve ( case8 . parameterArn ) , expectedA ) ;
478
- test . deepEqual ( stack . resolve ( case9 . parameterArn ) , expectedB ) ;
479
- test . deepEqual ( stack . resolve ( case10 . parameterArn ) , {
480
- 'Fn::Join' : [ '' , [
481
- 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'p97A508212' }
482
- ]
483
- ] } ) ;
507
+ test . deepEqual ( stack . resolve ( case9 . parameterArn ) , expectedC ) ;
508
+
509
+ // new ssm.Parameters determine if "/" is needed based on the posture of `parameterName`.
510
+ test . deepEqual ( stack . resolve ( case10 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'p81BB0F6FE' } ] ] } ) ;
511
+ test . deepEqual ( stack . resolve ( case11 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter' , { Ref : 'p97A508212' } ] ] } ) ;
512
+ test . deepEqual ( stack . resolve ( case12 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'p107D6B8AB0' } ] ] } ) ;
513
+ test . deepEqual ( stack . resolve ( case13 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'p118A9CB02C' } ] ] } ) ;
514
+ test . deepEqual ( stack . resolve ( case14 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter' , { Ref : 'p129BE4CE91' } ] ] } ) ;
515
+ test . deepEqual ( stack . resolve ( case15 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'p1326A2AEC4' } ] ] } ) ;
516
+
517
+ test . done ( ) ;
518
+ } ,
519
+
520
+ 'if parameterName is a token separator must be specified' ( test : Test ) {
521
+ // GIVEN
522
+ const stack = new Stack ( ) ;
523
+ const param = new CfnParameter ( stack , 'param' ) ;
524
+ let i = 0 ;
525
+
526
+ // WHEN
527
+ const p1 = new ssm . StringParameter ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , stringValue : 'foo' , simpleName : true } ) ;
528
+ const p2 = new ssm . StringParameter ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , stringValue : 'foo' , simpleName : false } ) ;
529
+ const p3 = new ssm . StringListParameter ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , stringListValue : [ 'foo' ] , simpleName : false } ) ;
530
+
531
+ // THEN
532
+ test . deepEqual ( stack . resolve ( p1 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter/' , { Ref : 'p0B02A8F65' } ] ] } ) ;
533
+ test . deepEqual ( stack . resolve ( p2 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter' , { Ref : 'p1E43AD5AC' } ] ] } ) ;
534
+ test . deepEqual ( stack . resolve ( p3 . parameterArn ) , { 'Fn::Join' : [ '' , [ 'arn:' , { Ref : 'AWS::Partition' } , ':ssm:' , { Ref : 'AWS::Region' } , ':' , { Ref : 'AWS::AccountId' } , ':parameter' , { Ref : 'p2C1903AEB' } ] ] } ) ;
535
+
536
+ test . done ( ) ;
537
+ } ,
538
+
539
+ 'fails if name is a token and no explicit separator' ( test : Test ) {
540
+ // GIVEN
541
+ const stack = new Stack ( ) ;
542
+ const param = new CfnParameter ( stack , 'param' ) ;
543
+ let i = 0 ;
484
544
545
+ // THEN
546
+ const expected = / U n a b l e t o d e t e r m i n e A R N s e p a r a t o r f o r S S M p a r a m e t e r s i n c e t h e p a r a m e t e r n a m e i s a n u n r e s o l v e d t o k e n . U s e " f r o m A t t r i b u t e s " a n d s p e c i f y " s i m p l e N a m e " e x p l i c i t l y / ;
547
+ test . throws ( ( ) => ssm . StringParameter . fromStringParameterName ( stack , `p${ i ++ } ` , param . valueAsString ) , expected ) ;
548
+ test . throws ( ( ) => ssm . StringParameter . fromSecureStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , version : 1 } ) , expected ) ;
549
+ test . throws ( ( ) => new ssm . StringParameter ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , stringValue : 'foo' } ) , expected ) ;
550
+ test . throws ( ( ) => new ssm . StringParameter ( stack , `p${ i ++ } ` , { parameterName : param . valueAsString , stringValue : 'foo' } ) , expected ) ;
551
+ test . done ( ) ;
552
+ } ,
553
+
554
+ 'fails if simpleName is wrong based on a concrete physical name' ( test : Test ) {
555
+ // GIVEN
556
+ const stack = new Stack ( ) ;
557
+ let i = 0 ;
558
+
559
+ // THEN
560
+ test . throws ( ( ) => ssm . StringParameter . fromStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : 'simple' , simpleName : false } ) , / P a r a m e t e r n a m e " s i m p l e " i s a s i m p l e n a m e , b u t " s i m p l e N a m e " w a s e x p l i c i t l y s e t t o f a l s e . E i t h e r o m i t i t o r s e t i t t o t r u e / ) ;
561
+ test . throws ( ( ) => ssm . StringParameter . fromStringParameterAttributes ( stack , `p${ i ++ } ` , { parameterName : '/foo/bar' , simpleName : true } ) , / P a r a m e t e r n a m e " \/ f o o \/ b a r " i s n o t a s i m p l e n a m e , b u t " s i m p l e N a m e " w a s e x p l i c i t l y s e t t o t r u e . E i t h e r o m i t i t o r s e t i t t o f a l s e / ) ;
562
+ test . done ( ) ;
563
+ } ,
564
+
565
+ 'fails if parameterName is undefined and simpleName is "false"' ( test : Test ) {
566
+ // GIVEN
567
+ const stack = new Stack ( ) ;
568
+
569
+ // THEN
570
+ test . throws ( ( ) => new ssm . StringParameter ( stack , 'p' , { simpleName : false , stringValue : 'foo' } ) , / I f " p a r a m e t e r N a m e " i s n o t e x p l i c i t l y d e f i n e d , " s i m p l e N a m e " m u s t b e " t r u e " o r u n d e f i n e d s i n c e a u t o - g e n e r a t e d p a r a m e t e r n a m e s a l w a y s h a v e s i m p l e n a m e s / ) ;
485
571
test . done ( ) ;
486
572
}
487
573
} ;
0 commit comments