cfndk 0.0.7 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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