cfndk 0.0.7 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +79 -0
  3. data/.gitignore +1 -1
  4. data/.rspec +2 -0
  5. data/.rspec_parallel +6 -0
  6. data/.simplecov +9 -0
  7. data/Gemfile +11 -1
  8. data/Gemfile.lock +815 -0
  9. data/README.md +269 -76
  10. data/bin/cfndk +3 -18
  11. data/cfndk.gemspec +15 -6
  12. data/docker/Dockerfile +8 -0
  13. data/docker/build.sh +3 -0
  14. data/docker/cfndk.sh +14 -0
  15. data/lib/cfndk.rb +36 -0
  16. data/lib/cfndk/change_set_command.rb +103 -0
  17. data/lib/cfndk/command.rb +125 -119
  18. data/lib/cfndk/config_file_loadable.rb +13 -0
  19. data/lib/cfndk/credential_provider_chain.rb +12 -42
  20. data/lib/cfndk/credential_resolvable.rb +10 -0
  21. data/lib/cfndk/diff.rb +38 -0
  22. data/lib/cfndk/global_config.rb +46 -0
  23. data/lib/cfndk/key_pair.rb +66 -14
  24. data/lib/cfndk/key_pair_command.rb +60 -0
  25. data/lib/cfndk/key_pairs.rb +22 -5
  26. data/lib/cfndk/logger.rb +12 -3
  27. data/lib/cfndk/stack.rb +427 -126
  28. data/lib/cfndk/stack_command.rb +128 -0
  29. data/lib/cfndk/stacks.rb +48 -22
  30. data/lib/cfndk/subcommand_help_returnable.rb +16 -0
  31. data/lib/cfndk/template_packager.rb +210 -0
  32. data/lib/cfndk/uuid.rb +10 -0
  33. data/lib/cfndk/version.rb +1 -1
  34. data/skel/cfndk.yml +4 -0
  35. data/spec/.gitignore +1 -0
  36. data/spec/cfndk_change_set_create_spec.rb +436 -0
  37. data/spec/cfndk_change_set_destroy_spec.rb +160 -0
  38. data/spec/cfndk_change_set_execute_spec.rb +179 -0
  39. data/spec/cfndk_change_set_report_spec.rb +107 -0
  40. data/spec/cfndk_change_set_spec.rb +37 -0
  41. data/spec/cfndk_create_spec.rb +504 -0
  42. data/spec/cfndk_destroy_spec.rb +148 -0
  43. data/spec/cfndk_keypiar_spec.rb +397 -0
  44. data/spec/cfndk_report_spec.rb +164 -0
  45. data/spec/cfndk_spec.rb +103 -0
  46. data/spec/cfndk_stack_create_spec.rb +814 -0
  47. data/spec/cfndk_stack_destroy_spec.rb +225 -0
  48. data/spec/cfndk_stack_report_spec.rb +181 -0
  49. data/spec/cfndk_stack_spec.rb +133 -0
  50. data/spec/cfndk_stack_update_spec.rb +553 -0
  51. data/spec/fixtures/big_vpc.yaml +533 -0
  52. data/spec/fixtures/empty_resource.yaml +2 -0
  53. data/spec/fixtures/iam.json +8 -0
  54. data/spec/fixtures/iam.yaml +38 -0
  55. data/spec/fixtures/iam_different.json +8 -0
  56. data/spec/fixtures/invalid_vpc.yaml +21 -0
  57. data/spec/fixtures/lambda_function/index.js +4 -0
  58. data/spec/fixtures/lambda_function/lambda_function.json +4 -0
  59. data/spec/fixtures/lambda_function/lambda_function.yaml +28 -0
  60. data/spec/fixtures/nested_stack.json +35 -0
  61. data/spec/fixtures/nested_stack.yaml +20 -0
  62. data/spec/fixtures/serverless_function/index.js +4 -0
  63. data/spec/fixtures/serverless_function/serverless_function.json +4 -0
  64. data/spec/fixtures/serverless_function/serverless_function.yaml +21 -0
  65. data/spec/fixtures/sg.json +8 -0
  66. data/spec/fixtures/sg.yaml +27 -0
  67. data/spec/fixtures/sg_different.yaml +22 -0
  68. data/spec/fixtures/stack.json +8 -0
  69. data/spec/fixtures/stack.template.json +39 -0
  70. data/spec/fixtures/stack.yaml +22 -0
  71. data/spec/fixtures/vpc.json +8 -0
  72. data/spec/fixtures/vpc.template.json +40 -0
  73. data/spec/fixtures/vpc.yaml +21 -0
  74. data/spec/fixtures/vpc_different.yaml +21 -0
  75. data/spec/spec_helper.rb +14 -0
  76. data/spec/support/aruba.rb +6 -0
  77. data/vagrant/Vagrantfile +89 -0
  78. metadata +259 -31
@@ -0,0 +1,504 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'CFnDK', type: :aruba do
4
+ before(:each) { set_environment_variable('AWS_REGION', ENV['AWS_REGION']) }
5
+ before(:each) { set_environment_variable('AWS_PROFILE', ENV['AWS_PROFILE']) }
6
+ before(:each) { set_environment_variable('AWS_ACCESS_KEY_ID', ENV["AWS_ACCESS_KEY_ID#{ENV['TEST_ENV_NUMBER']}"]) }
7
+ before(:each) { set_environment_variable('AWS_SECRET_ACCESS_KEY', ENV["AWS_SECRET_ACCESS_KEY#{ENV['TEST_ENV_NUMBER']}"]) }
8
+ describe 'bin/cfndk' do
9
+ before(:each) { setup_aruba }
10
+ let(:file) { 'cfndk.yml' }
11
+ let(:file2) { 'cfndk2.yml' }
12
+ let(:pem) { 'test.pem' }
13
+ let(:uuid) { '38437346-c75c-47c5-83b4-d504f85e275b' }
14
+
15
+ describe 'create', create: true do
16
+ context 'without cfndk.yml' do
17
+ before(:each) { run_command('cfndk create') }
18
+ it 'displays file does not exist error and status code = 1' do
19
+ aggregate_failures do
20
+ expect(last_command_started).to have_exit_status(1)
21
+ expect(last_command_started).to have_output(/ERROR RuntimeError: File does not exist./)
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'with cfndk2.yml' do
27
+ yaml = <<-"YAML"
28
+ keypairs:
29
+ YAML
30
+ before(:each) { write_file(file2, yaml) }
31
+ context 'when -c cfndk2.yml and empty keypairs' do
32
+ before(:each) { run_command("cfndk create -c=#{file2}") }
33
+ it 'displays empty keypair log' do
34
+ aggregate_failures do
35
+ expect(last_command_started).to be_successfully_executed
36
+ expect(last_command_started).to have_output(/INFO create.../)
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'when --config-path cfndk2.yml and empty keypairs' do
42
+ before(:each) { run_command("cfndk create --config-path=#{file2}") }
43
+ it 'displays empty keypair log' do
44
+ aggregate_failures do
45
+ expect(last_command_started).to be_successfully_executed
46
+ expect(last_command_started).to have_output(/INFO create.../)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'with cfndk.yml' do
53
+ context 'when cfndk.yml is empty' do
54
+ before(:each) { touch(file) }
55
+ before(:each) { run_command('cfndk create') }
56
+ it 'displays File is empty error and status code = 1' do
57
+ aggregate_failures do
58
+ expect(last_command_started).to have_exit_status(1)
59
+ expect(last_command_started).to have_output(/ERROR File is empty./)
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'with keyparis:', keypairs: true do
65
+ context 'without keypair' do
66
+ before(:each) { write_file(file, 'keypairs:') }
67
+ before(:each) { run_command('cfndk create') }
68
+ it do
69
+ aggregate_failures do
70
+ expect(last_command_started).to be_successfully_executed
71
+ expect(last_command_started).to have_output(/INFO create.../)
72
+ end
73
+ end
74
+ end
75
+
76
+ context 'with a keypair' do
77
+ yaml = <<-"YAML"
78
+ keypairs:
79
+ Test:
80
+ YAML
81
+ before(:each) { write_file(file, yaml) }
82
+ before(:each) { run_command('cfndk create') }
83
+ it do
84
+ aggregate_failures do
85
+ expect(last_command_started).to be_successfully_executed
86
+ expect(last_command_started).to have_output(/INFO creating keypair: Test/)
87
+ expect(last_command_started).to have_output(/INFO created keypair: Test/)
88
+ end
89
+ end
90
+ after(:each) { run_command('cfndk destroy -f') }
91
+ end
92
+
93
+ context 'with two keypairs' do
94
+ yaml = <<-"YAML"
95
+ keypairs:
96
+ Foo:
97
+ Bar:
98
+ YAML
99
+ before(:each) { write_file(file, yaml) }
100
+ before(:each) { run_command('cfndk create') }
101
+ it do
102
+ aggregate_failures do
103
+ expect(last_command_started).to be_successfully_executed
104
+ expect(last_command_started).to have_output(/INFO creating keypair: Foo/)
105
+ expect(last_command_started).to have_output(/INFO created keypair: Foo/)
106
+ expect(last_command_started).to have_output(/INFO creating keypair: Bar/)
107
+ expect(last_command_started).to have_output(/INFO created keypair: Bar/)
108
+ end
109
+ end
110
+ after(:each) { run_command('cfndk destroy -f') }
111
+ end
112
+
113
+ context 'with a keypair and a key_file' do
114
+ context 'without UUID', uuid: true do
115
+ context 'without append_uuid' do
116
+ yaml = <<-"YAML"
117
+ keypairs:
118
+ Test:
119
+ key_file: test.pem
120
+ YAML
121
+ before(:each) { write_file(file, yaml) }
122
+ before(:each) { run_command('cfndk create') }
123
+ it do
124
+ aggregate_failures do
125
+ expect(last_command_started).to be_successfully_executed
126
+ expect(last_command_started).to have_output(/INFO create.../)
127
+ expect(last_command_started).to have_output(/INFO creating keypair: Test$/)
128
+ expect(last_command_started).to have_output(/INFO created keypair: Test$/)
129
+ expect(last_command_started).to have_output(/create key file: #{pem}$/)
130
+ expect(pem).to be_an_existing_file
131
+ expect(pem).to have_file_content(/-----END RSA PRIVATE KEY-----/)
132
+ end
133
+ end
134
+ after(:each) { run_command('cfndk destroy -f') }
135
+ end
136
+
137
+ context 'with append_uuid' do
138
+ yaml = <<-"YAML"
139
+ keypairs:
140
+ Test:
141
+ key_file: test<%= append_uuid %>.pem
142
+ YAML
143
+ before(:each) { write_file(file, yaml) }
144
+ before(:each) { run_command('cfndk create') }
145
+ it do
146
+ aggregate_failures do
147
+ expect(last_command_started).to be_successfully_executed
148
+ expect(last_command_started).to have_output(/INFO create.../)
149
+ expect(last_command_started).to have_output(/INFO creating keypair: Test$/)
150
+ expect(last_command_started).to have_output(/INFO created keypair: Test$/)
151
+ expect(last_command_started).to have_output(/create key file: #{pem}/)
152
+ expect(pem).to be_an_existing_file
153
+ expect(pem).to have_file_content(/-----END RSA PRIVATE KEY-----/)
154
+ end
155
+ end
156
+ after(:each) { run_command('cfndk destroy -f') }
157
+ end
158
+ end
159
+
160
+ context 'with UUID', uuid: true do
161
+ yaml = <<-"YAML"
162
+ keypairs:
163
+ Test:
164
+ key_file: test<%= append_uuid %>.pem
165
+ YAML
166
+ before(:each) { write_file(file, yaml) }
167
+ context 'when -u 38437346-c75c-47c5-83b4-d504f85e275b' do
168
+ before(:each) { run_command("cfndk create -u=#{uuid}") }
169
+ it do
170
+ aggregate_failures do
171
+ expect(last_command_started).to be_successfully_executed
172
+ expect(last_command_started).to have_output(/INFO create.../)
173
+ expect(last_command_started).to have_output(/INFO creating keypair: Test-#{uuid}/)
174
+ expect(last_command_started).to have_output(/INFO created keypair: Test-#{uuid}/)
175
+ expect(last_command_started).to have_output(/create key file: test-#{uuid}.pem/)
176
+ expect("test-#{uuid}.pem").to be_an_existing_file
177
+ expect("test-#{uuid}.pem").to have_file_content(/-----END RSA PRIVATE KEY-----/)
178
+ end
179
+ end
180
+ after(:each) { run_command("cfndk destroy -u=#{uuid} -f") }
181
+ end
182
+ end
183
+ end
184
+ context 'with keypairs' do
185
+ yaml = <<-"YAML"
186
+ keypairs:
187
+ Test1:
188
+ Test2:
189
+ Test3:
190
+ YAML
191
+ before(:each) { write_file(file, yaml) }
192
+ context 'without UUID' do
193
+ before(:each) { run_command('cfndk create') }
194
+ it do
195
+ aggregate_failures do
196
+ expect(last_command_started).to be_successfully_executed
197
+ expect(last_command_started).to have_output(/INFO create.../)
198
+ expect(last_command_started).to have_output(/INFO creating keypair: Test1/)
199
+ expect(last_command_started).to have_output(/INFO created keypair: Test1/)
200
+ expect(last_command_started).to have_output(/INFO creating keypair: Test2/)
201
+ expect(last_command_started).to have_output(/INFO created keypair: Test2/)
202
+ expect(last_command_started).to have_output(/INFO creating keypair: Test3/)
203
+ expect(last_command_started).to have_output(/INFO created keypair: Test3/)
204
+ end
205
+ end
206
+ after(:each) { run_command('cfndk destroy -f') }
207
+ end
208
+ context 'with UUID' do
209
+ context 'when env CFNDK_UUID=38437346-c75c-47c5-83b4-d504f85e275b' do
210
+ before(:each) { set_environment_variable('CFNDK_UUID', uuid) }
211
+ before(:each) { run_command('cfndk create') }
212
+ it do
213
+ aggregate_failures do
214
+ expect(last_command_started).to be_successfully_executed
215
+ expect(last_command_started).to have_output(/INFO create.../)
216
+ expect(last_command_started).to have_output(/INFO creating keypair: Test1-#{uuid}/)
217
+ expect(last_command_started).to have_output(/INFO created keypair: Test1-#{uuid}/)
218
+ expect(last_command_started).to have_output(/INFO creating keypair: Test2-#{uuid}/)
219
+ expect(last_command_started).to have_output(/INFO created keypair: Test2-#{uuid}/)
220
+ expect(last_command_started).to have_output(/INFO creating keypair: Test3-#{uuid}/)
221
+ expect(last_command_started).to have_output(/INFO created keypair: Test3-#{uuid}/)
222
+ end
223
+ end
224
+ after(:each) { run_command('cfndk destroy -f') }
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ context 'with stacks:', stacks: true do
231
+ context 'without stack' do
232
+ before(:each) { write_file(file, 'stacks:') }
233
+ before(:each) { run_command('cfndk create') }
234
+ it do
235
+ aggregate_failures do
236
+ expect(last_command_started).to be_successfully_executed
237
+ expect(last_command_started).to have_output(/INFO create.../)
238
+ end
239
+ end
240
+ end
241
+
242
+ context 'with a stack', aaa: true do
243
+ yaml = <<-"YAML"
244
+ stacks:
245
+ Test:
246
+ template_file: vpc.yaml
247
+ parameter_input: vpc.json
248
+ timeout_in_minutes: 2
249
+ YAML
250
+ before(:each) { write_file(file, yaml) }
251
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
252
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
253
+ before(:each) { run_command_and_stop('cfndk create') }
254
+ it 'displays created log and stack exist' do
255
+ aggregate_failures do
256
+ expect(last_command_started).to be_successfully_executed
257
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
258
+ expect(last_command_started).to have_output(/INFO creating stack: Test$/)
259
+ expect(last_command_started).to have_output(/INFO created stack: Test$/)
260
+ expect(cloudformation_stack('Test')).to exist
261
+ expect(cloudformation_stack('Test').stack_name).to eq('Test')
262
+ expect(cloudformation_stack('Test').stack_status).to eq('CREATE_COMPLETE')
263
+ expect(cloudformation_stack('Test').timeout_in_minutes).to eq(2)
264
+ expect(cloudformation_stack('Test').parameters[0].parameter_value).to eq('sample')
265
+ expect(cloudformation_stack('Test').tags[0].key).to eq('origina_name')
266
+ expect(cloudformation_stack('Test').tags[0].value).to eq('Test')
267
+ end
268
+ end
269
+ after(:each) { run_command('cfndk destroy -f') }
270
+ end
271
+ context 'with two stacks' do
272
+ yaml = <<-"YAML"
273
+ stacks:
274
+ Test:
275
+ template_file: vpc.yaml
276
+ parameter_input: vpc.json
277
+ timeout_in_minutes: 2
278
+ Test2:
279
+ template_file: sg.yaml
280
+ parameter_input: sg.json
281
+ depends:
282
+ - Test
283
+ YAML
284
+
285
+ before(:each) { write_file(file, yaml) }
286
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
287
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
288
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
289
+ before(:each) { copy('%/sg.json', 'sg.json') }
290
+ before(:each) { run_command('cfndk create') }
291
+ it do
292
+ aggregate_failures do
293
+ expect(last_command_started).to be_successfully_executed
294
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
295
+ expect(last_command_started).to have_output(/INFO creating stack: Test$/)
296
+ expect(last_command_started).to have_output(/INFO created stack: Test$/)
297
+ expect(last_command_started).to have_output(/INFO validate stack: Test2$/)
298
+ expect(last_command_started).to have_output(/INFO creating stack: Test2$/)
299
+ expect(last_command_started).to have_output(/INFO created stack: Test2$/)
300
+ end
301
+ end
302
+ after(:each) { run_command('cfndk destroy -f') }
303
+ end
304
+ context 'when invalid dependency', dependency: true do
305
+ yaml = <<-"YAML"
306
+ stacks:
307
+ Test:
308
+ template_file: vpc.yaml
309
+ parameter_input: vpc.json
310
+ timeout_in_minutes: 2
311
+ depends:
312
+ - Test2
313
+ Test2:
314
+ template_file: sg.yaml
315
+ parameter_input: sg.json
316
+ YAML
317
+
318
+ before(:each) { write_file(file, yaml) }
319
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
320
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
321
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
322
+ before(:each) { copy('%/sg.json', 'sg.json') }
323
+ before(:each) { run_command('cfndk create') }
324
+ it do
325
+ aggregate_failures do
326
+ expect(last_command_started).to have_exit_status(1)
327
+ expect(last_command_started).to have_output(/ERROR Aws::Waiters::Errors::FailureStateError: stopped waiting, encountered a failure state$/)
328
+ end
329
+ end
330
+ after(:each) { run_command('cfndk destroy -f') }
331
+ end
332
+ context 'when cyclic dependency', dependency: true do
333
+ yaml = <<-"YAML"
334
+ stacks:
335
+ Test:
336
+ template_file: vpc.yaml
337
+ parameter_input: vpc.json
338
+ timeout_in_minutes: 2
339
+ depends:
340
+ - Test2
341
+ Test2:
342
+ template_file: sg.yaml
343
+ parameter_input: sg.json
344
+ depends:
345
+ - Test
346
+ YAML
347
+
348
+ before(:each) { write_file(file, yaml) }
349
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
350
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
351
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
352
+ before(:each) { copy('%/sg.json', 'sg.json') }
353
+ before(:each) { run_command('cfndk create') }
354
+ it do
355
+ aggregate_failures do
356
+ expect(last_command_started).to have_exit_status(1)
357
+ expect(last_command_started).to have_output(/ERROR RuntimeError: There are cyclic dependency or stack doesn't exist. unprocessed_stack: Test,Test2$/)
358
+ end
359
+ end
360
+ after(:each) { run_command('cfndk destroy -f') }
361
+ end
362
+ context 'when requires capabilities without capabilities', capabilities: true do
363
+ yaml = <<-"YAML"
364
+ stacks:
365
+ Test:
366
+ template_file: iam.yaml
367
+ parameter_input: iam.json
368
+ timeout_in_minutes: 2
369
+ YAML
370
+
371
+ before(:each) { write_file(file, yaml) }
372
+ before(:each) { copy('%/iam.yaml', 'iam.yaml') }
373
+ before(:each) { copy('%/iam.json', 'iam.json') }
374
+ before(:each) { run_command('cfndk create') }
375
+ it do
376
+ aggregate_failures do
377
+ expect(last_command_started).to have_exit_status(1)
378
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::InsufficientCapabilitiesException: Requires capabilities : \[CAPABILITY_NAMED_IAM\]/)
379
+ end
380
+ end
381
+ after(:each) { run_command('cfndk destroy -f') }
382
+ end
383
+ context 'when success with capabilities', capabilities: true do
384
+ yaml = <<-"YAML"
385
+ stacks:
386
+ Test:
387
+ template_file: iam.yaml
388
+ parameter_input: iam.json
389
+ capabilities:
390
+ - CAPABILITY_NAMED_IAM
391
+ timeout_in_minutes: 3
392
+ YAML
393
+
394
+ before(:each) { write_file(file, yaml) }
395
+ before(:each) { copy('%/iam.yaml', 'iam.yaml') }
396
+ before(:each) { copy('%/iam.json', 'iam.json') }
397
+ before(:each) { run_command('cfndk create') }
398
+ it do
399
+ aggregate_failures do
400
+ expect(last_command_started).to be_successfully_executed
401
+ expect(last_command_started).to have_output(/INFO created stack: Test$/)
402
+ end
403
+ end
404
+ after(:each) { run_command('cfndk destroy -f') }
405
+ end
406
+ context 'with UUID', uuid: true do
407
+ context 'when -u 38437346-c75c-47c5-83b4-d504f85e275b', aaa: true do
408
+ yaml = <<-"YAML"
409
+ stacks:
410
+ Test:
411
+ template_file: vpc.yaml
412
+ parameter_input: vpc.json
413
+ parameters:
414
+ VpcName: sample<%= append_uuid%>
415
+ timeout_in_minutes: 2
416
+ Test2:
417
+ template_file: sg.yaml
418
+ parameter_input: sg.json
419
+ parameters:
420
+ VpcName: sample<%= append_uuid%>
421
+ depends:
422
+ - Test
423
+ YAML
424
+ before(:each) { write_file(file, yaml) }
425
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
426
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
427
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
428
+ before(:each) { copy('%/sg.json', 'sg.json') }
429
+ before(:each) { run_command_and_stop("cfndk create -u=#{uuid}") }
430
+ it 'displays created logs and stacks exist' do
431
+ aggregate_failures do
432
+ expect(last_command_started).to be_successfully_executed
433
+ expect(last_command_started).to have_output(/INFO validate stack: Test-#{uuid}$/)
434
+ expect(last_command_started).to have_output(/INFO creating stack: Test-#{uuid}$/)
435
+ expect(last_command_started).to have_output(/INFO created stack: Test-#{uuid}$/)
436
+ expect(last_command_started).to have_output(/INFO validate stack: Test2-#{uuid}$/)
437
+ expect(last_command_started).to have_output(/INFO creating stack: Test2-#{uuid}$/)
438
+ expect(last_command_started).to have_output(/INFO created stack: Test2-#{uuid}$/)
439
+ expect(cloudformation_stack("Test-#{uuid}")).to exist
440
+ expect(cloudformation_stack("Test-#{uuid}").stack_name).to eq("Test-#{uuid}")
441
+ expect(cloudformation_stack("Test-#{uuid}").stack_status).to eq('CREATE_COMPLETE')
442
+ expect(cloudformation_stack("Test-#{uuid}").timeout_in_minutes).to eq(2)
443
+ expect(cloudformation_stack("Test-#{uuid}").parameters[0].parameter_value).to eq("sample-#{uuid}")
444
+ expect(cloudformation_stack("Test-#{uuid}").tags[0].key).to eq('origina_name')
445
+ expect(cloudformation_stack("Test-#{uuid}").tags[0].value).to eq('Test')
446
+ expect(cloudformation_stack("Test-#{uuid}").tags[1].key).to eq('UUID')
447
+ expect(cloudformation_stack("Test-#{uuid}").tags[1].value).to eq(uuid)
448
+ expect(cloudformation_stack("Test2-#{uuid}")).to exist
449
+ expect(cloudformation_stack("Test2-#{uuid}").stack_name).to eq("Test2-#{uuid}")
450
+ expect(cloudformation_stack("Test2-#{uuid}").stack_status).to eq('CREATE_COMPLETE')
451
+ expect(cloudformation_stack("Test2-#{uuid}").parameters[0].parameter_value).to eq("sample-#{uuid}")
452
+ expect(cloudformation_stack("Test2-#{uuid}").tags[0].key).to eq('origina_name')
453
+ expect(cloudformation_stack("Test2-#{uuid}").tags[0].value).to eq('Test2')
454
+ expect(cloudformation_stack("Test2-#{uuid}").tags[1].key).to eq('UUID')
455
+ expect(cloudformation_stack("Test2-#{uuid}").tags[1].value).to eq(uuid)
456
+ end
457
+ end
458
+ after(:each) { run_command("cfndk destroy -f -u=#{uuid}") }
459
+ end
460
+ context 'when env CFNDK_UUID=38437346-c75c-47c5-83b4-d504f85e275b' do
461
+ before(:each) { set_environment_variable('CFNDK_UUID', uuid) }
462
+ context 'with two stacks' do
463
+ yaml = <<-"YAML"
464
+ stacks:
465
+ Test:
466
+ template_file: vpc.yaml
467
+ parameter_input: vpc.json
468
+ parameters:
469
+ VpcName: sample<%= append_uuid%>
470
+ timeout_in_minutes: 2
471
+ Test2:
472
+ template_file: sg.yaml
473
+ parameter_input: sg.json
474
+ parameters:
475
+ VpcName: sample<%= append_uuid%>
476
+ depends:
477
+ - Test
478
+ YAML
479
+ before(:each) { write_file(file, yaml) }
480
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
481
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
482
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
483
+ before(:each) { copy('%/sg.json', 'sg.json') }
484
+ before(:each) { run_command('cfndk create') }
485
+ it do
486
+ aggregate_failures do
487
+ expect(last_command_started).to be_successfully_executed
488
+ expect(last_command_started).to have_output(/INFO validate stack: Test-#{uuid}$/)
489
+ expect(last_command_started).to have_output(/INFO creating stack: Test-#{uuid}$/)
490
+ expect(last_command_started).to have_output(/INFO created stack: Test-#{uuid}$/)
491
+ expect(last_command_started).to have_output(/INFO validate stack: Test2-#{uuid}$/)
492
+ expect(last_command_started).to have_output(/INFO creating stack: Test2-#{uuid}$/)
493
+ expect(last_command_started).to have_output(/INFO created stack: Test2-#{uuid}$/)
494
+ end
495
+ end
496
+ after(:each) { run_command('cfndk destroy -f') }
497
+ end
498
+ end
499
+ end
500
+ end
501
+ end
502
+ end
503
+ end
504
+ end