stack_master 0.0.1

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 (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +208 -0
  7. data/Rakefile +11 -0
  8. data/apply_demo.gif +0 -0
  9. data/bin/stack_master +16 -0
  10. data/example/simple/Gemfile +3 -0
  11. data/example/simple/parameters/myapp_vpc.yml +1 -0
  12. data/example/simple/parameters/myapp_web.yml +2 -0
  13. data/example/simple/stack_master.yml +13 -0
  14. data/example/simple/templates/myapp_vpc.rb +39 -0
  15. data/example/simple/templates/myapp_web.rb +16 -0
  16. data/features/apply.feature +241 -0
  17. data/features/delete.feature +43 -0
  18. data/features/diff.feature +191 -0
  19. data/features/events.feature +38 -0
  20. data/features/init.feature +6 -0
  21. data/features/outputs.feature +49 -0
  22. data/features/region_aliases.feature +66 -0
  23. data/features/resources.feature +45 -0
  24. data/features/stack_defaults.feature +88 -0
  25. data/features/status.feature +124 -0
  26. data/features/step_definitions/stack_steps.rb +50 -0
  27. data/features/support/env.rb +14 -0
  28. data/lib/stack_master.rb +81 -0
  29. data/lib/stack_master/aws_driver/cloud_formation.rb +56 -0
  30. data/lib/stack_master/cli.rb +164 -0
  31. data/lib/stack_master/command.rb +13 -0
  32. data/lib/stack_master/commands/apply.rb +104 -0
  33. data/lib/stack_master/commands/delete.rb +53 -0
  34. data/lib/stack_master/commands/diff.rb +31 -0
  35. data/lib/stack_master/commands/events.rb +39 -0
  36. data/lib/stack_master/commands/init.rb +109 -0
  37. data/lib/stack_master/commands/list_stacks.rb +16 -0
  38. data/lib/stack_master/commands/outputs.rb +27 -0
  39. data/lib/stack_master/commands/resources.rb +33 -0
  40. data/lib/stack_master/commands/status.rb +47 -0
  41. data/lib/stack_master/commands/validate.rb +17 -0
  42. data/lib/stack_master/config.rb +86 -0
  43. data/lib/stack_master/ctrl_c.rb +4 -0
  44. data/lib/stack_master/parameter_loader.rb +17 -0
  45. data/lib/stack_master/parameter_resolver.rb +45 -0
  46. data/lib/stack_master/parameter_resolvers/secret.rb +42 -0
  47. data/lib/stack_master/parameter_resolvers/security_group.rb +20 -0
  48. data/lib/stack_master/parameter_resolvers/sns_topic_name.rb +29 -0
  49. data/lib/stack_master/parameter_resolvers/stack_output.rb +53 -0
  50. data/lib/stack_master/prompter.rb +14 -0
  51. data/lib/stack_master/security_group_finder.rb +29 -0
  52. data/lib/stack_master/sns_topic_finder.rb +27 -0
  53. data/lib/stack_master/stack.rb +96 -0
  54. data/lib/stack_master/stack_definition.rb +49 -0
  55. data/lib/stack_master/stack_differ.rb +80 -0
  56. data/lib/stack_master/stack_events/fetcher.rb +45 -0
  57. data/lib/stack_master/stack_events/presenter.rb +27 -0
  58. data/lib/stack_master/stack_events/streamer.rb +55 -0
  59. data/lib/stack_master/stack_states.rb +34 -0
  60. data/lib/stack_master/template_compiler.rb +21 -0
  61. data/lib/stack_master/test_driver/cloud_formation.rb +139 -0
  62. data/lib/stack_master/testing.rb +7 -0
  63. data/lib/stack_master/utils.rb +31 -0
  64. data/lib/stack_master/validator.rb +25 -0
  65. data/lib/stack_master/version.rb +3 -0
  66. data/logo.png +0 -0
  67. data/script/buildkite/bundle.sh +5 -0
  68. data/script/buildkite/clean.sh +3 -0
  69. data/script/buildkite_rspec.sh +27 -0
  70. data/spec/fixtures/parameters/myapp_vpc.yml +1 -0
  71. data/spec/fixtures/stack_master.yml +35 -0
  72. data/spec/fixtures/templates/myapp_vpc.json +1 -0
  73. data/spec/spec_helper.rb +99 -0
  74. data/spec/stack_master/commands/apply_spec.rb +92 -0
  75. data/spec/stack_master/commands/delete_spec.rb +40 -0
  76. data/spec/stack_master/commands/init_spec.rb +17 -0
  77. data/spec/stack_master/commands/status_spec.rb +38 -0
  78. data/spec/stack_master/commands/validate_spec.rb +26 -0
  79. data/spec/stack_master/config_spec.rb +81 -0
  80. data/spec/stack_master/parameter_loader_spec.rb +81 -0
  81. data/spec/stack_master/parameter_resolver_spec.rb +58 -0
  82. data/spec/stack_master/parameter_resolvers/secret_spec.rb +66 -0
  83. data/spec/stack_master/parameter_resolvers/security_group_spec.rb +17 -0
  84. data/spec/stack_master/parameter_resolvers/sns_topic_name_spec.rb +43 -0
  85. data/spec/stack_master/parameter_resolvers/stack_output_spec.rb +77 -0
  86. data/spec/stack_master/security_group_finder_spec.rb +49 -0
  87. data/spec/stack_master/sns_topic_finder_spec.rb +25 -0
  88. data/spec/stack_master/stack_definition_spec.rb +37 -0
  89. data/spec/stack_master/stack_differ_spec.rb +34 -0
  90. data/spec/stack_master/stack_events/fetcher_spec.rb +65 -0
  91. data/spec/stack_master/stack_events/presenter_spec.rb +18 -0
  92. data/spec/stack_master/stack_events/streamer_spec.rb +33 -0
  93. data/spec/stack_master/stack_spec.rb +157 -0
  94. data/spec/stack_master/template_compiler_spec.rb +48 -0
  95. data/spec/stack_master/test_driver/cloud_formation_spec.rb +24 -0
  96. data/spec/stack_master/utils_spec.rb +30 -0
  97. data/spec/stack_master/validator_spec.rb +38 -0
  98. data/stack_master.gemspec +38 -0
  99. data/stacktemplates/parameter_region.yml +3 -0
  100. data/stacktemplates/parameter_stack_name.yml +3 -0
  101. data/stacktemplates/stack.json.erb +20 -0
  102. data/stacktemplates/stack_master.yml.erb +6 -0
  103. metadata +427 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: be7dbbbfb5ac18598037c53174655253fef33f73
4
+ data.tar.gz: e1b2cb9dd3846993f497dc51a606053fc7670907
5
+ SHA512:
6
+ metadata.gz: 5fea5f38e52302091b2ab880cb59ca68ad9e60547a8f09b7eceb52611aa23475b4c3131fa62b9074580264315f7a75c0796c9fe9bebb1fd535c63c11ebe7d130
7
+ data.tar.gz: 4442a6772b1a8efd992660b9ba720f73208935a1bb0f5760a5e4b2b8ea5d4a1c3675964f4f4c3288d968bf45d3c752c4b05fba49f8487894f995e8cfc4537dbb
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /spec/examples.txt
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in stack_master.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Steve Hodgkiss
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,208 @@
1
+ ![StackMaster](/logo.png?raw=true)
2
+
3
+ StackMaster is a sure-footed way of creating, updating and keeping track of
4
+ Amazon (AWS) CloudFormation stacks.
5
+
6
+ - See the changes you are making to a stack before you apply them
7
+ - Connect stacks
8
+ - Keep secrets secret
9
+ - Customise stacks in different environments
10
+ - Apply descriptive labels to regions
11
+
12
+ StackMaster provides an easy command line interface to managing CloudFormation
13
+ stacks defined with templates specified in either the
14
+ [SparkleFormation](http://www.sparkleformation.io) DSL or standard JSON format.
15
+
16
+ ## Installation
17
+
18
+ System-wide: `gem install stack_master`
19
+
20
+ With bundler:
21
+
22
+ - Add `gem 'stack_master'` to your Gemfile.
23
+ - Run `bundle install`
24
+ - Run `bundle exec stack_master init` to generate a directory structure and stack_master.yml file
25
+
26
+ ## Configuration
27
+
28
+ Stacks are defined inside a `stack_master.yml` YAML file. When running
29
+ `stack_master`, it is assumed that this file will exist in the current working
30
+ directory, or that the file is passed in with `--config
31
+ /path/to/stack_master.yml`. Here's an example configuration file:
32
+
33
+ ```
34
+ region_aliases:
35
+ production: us-east-1
36
+ staging: ap-southeast-2
37
+ stack_defaults:
38
+ tags:
39
+ application: my-awesome-app
40
+ region_defaults:
41
+ us-east-1:
42
+ secret_file: production.yml.gpg
43
+ tags:
44
+ environment: production
45
+ notification_arns:
46
+ - test_arn
47
+ ap-southeast-2:
48
+ secret_file: staging.yml.gpg
49
+ tags:
50
+ environment: staging
51
+ stacks:
52
+ production:
53
+ myapp-vpc:
54
+ template: myapp_vpc.rb
55
+ myapp-db:
56
+ template: myapp_db.rb
57
+ stack_policy_file: db_stack_policy.json
58
+ myapp-web:
59
+ template: myapp_web.rb
60
+ staging:
61
+ myapp-vpc:
62
+ template: myapp_vpc.rb
63
+ myapp-db:
64
+ template: myapp_db.rb
65
+ myapp-web:
66
+ template: myapp_web.rb
67
+ eu-central-1:
68
+ myapp-vpc:
69
+ template: myapp_vpc.rb
70
+ ```
71
+
72
+ ## Directories
73
+
74
+ - `templates` - CloudFormation or SparkleFormation templates.
75
+ - `polices` - Stack policies.
76
+ - `parameters` - Parameters as YAML files.
77
+ - `secrets` - GPG encrypted secret files.
78
+
79
+ ## Parameters
80
+
81
+ Parameters are loaded from multiple YAML files, merged from the following lookup paths:
82
+
83
+ - parameters/[stack_name].yml
84
+ - parameters/[region]/[stack_name].yml
85
+ - parameters/[region_alias]/[stack_name].yml
86
+
87
+ A simple parameter file could look like this:
88
+
89
+ ```
90
+ key_name: myapp-us-east-1
91
+ ```
92
+
93
+ Keys in parameter files are automatically converted to camel case.
94
+
95
+ ## Parameter Resolvers
96
+
97
+ Parameter resolvers enable dynamic resolution of parameter values. A parameter
98
+ using a resolver will be a hash with one key where the key is the name of the
99
+ resolver.
100
+
101
+ One benefit of using resolvers instead of hard coding values like VPC ID's and
102
+ resource ARNs is that the same configuration works cross region, even though
103
+ the resolved values will be different.
104
+
105
+ ### Stack Output
106
+
107
+ The stack output parameter resolver looks up outputs from other stacks in the
108
+ same region. The expected format is `[stack-name]/[OutputName]`.
109
+
110
+ ```yaml
111
+ vpc_id:
112
+ stack_output: my-vpc-stack/VpcId
113
+ ```
114
+
115
+ ### Secret
116
+
117
+ The secret parameters resolver expects a `secret_file` to be defined in the
118
+ stack definition which is a GPG encrypted YAML file. Once decrypted and parsed,
119
+ the value provided to the secret resolver is used to lookup the associated key
120
+ in the secret file. A common use case for this is to store database passwords.
121
+
122
+ stack_master.yml:
123
+
124
+ ```yaml
125
+ stacks:
126
+ us-east-1:
127
+ my_app:
128
+ template: my_app.json
129
+ secret_file: production.yml.gpg
130
+ ```
131
+
132
+ secrets/production.yml.gpg, when decrypted:
133
+
134
+ ```yaml
135
+ db_password: my-password
136
+ ```
137
+
138
+ parameters/my_app.yml:
139
+
140
+ ```yaml
141
+ db_password:
142
+ secret: db_password
143
+ ```
144
+
145
+ ### Security Group
146
+
147
+ Looks up a security group by name and returns the ARN.
148
+
149
+ ```yaml
150
+ ssh_sg:
151
+ security_group: SSHSecurityGroup
152
+ ```
153
+
154
+ ### SNS Topic
155
+
156
+ Looks up an SNS topic by name and returns the ARN.
157
+
158
+ ```yaml
159
+ notification_topic:
160
+ sns_topic: PagerDuty
161
+ ```
162
+
163
+ ## Commands
164
+
165
+ ```bash
166
+ stack_master help # Display up to date docs on the commands available
167
+ stack_master init # Initialises a directory structure and stack_master.yml file
168
+ stack_master list # Lists stack definitions
169
+ stack_master apply [region-or-alias] [stack-name] # Create or update a stack
170
+ stack_master diff [region-or-alias] [stack-name] # Display a stack tempalte and parameter diff
171
+ stack_master delete [region-or-alias] [stack-name] # Delete a stack
172
+ stack_master events [region-or-alias] [stack-name] # Display events for a stack
173
+ stack_master outputs [region-or-alias] [stack-name] # Display outputs for a stack
174
+ stack_master resources [region-or-alias] [stack-name] # Display outputs for a stack
175
+ stack_master status # Displays the status of each stacks
176
+ ```
177
+
178
+ ## Applying updates
179
+
180
+ The apply command does the following:
181
+
182
+ - Builds the proposed stack json and resolves parameters.
183
+ - Fetches the current state of the stack from CloudFormation.
184
+ - Displays a diff of the current stack and the proposed stack.
185
+ - Asks if the update should continue.
186
+ - If yes, the API call is made to update or create the stack.
187
+ - Stack events are displayed until CloudFormation has finished applying the changes.
188
+
189
+ Demo:
190
+
191
+ ![Apply Demo](/apply_demo.gif?raw=true)
192
+
193
+ ## Maintainers
194
+
195
+ - [Steve Hodgkiss](https://github.com/stevehodgkiss)
196
+ - [Glen Stampoultzis](https://github.com/gstamp)
197
+
198
+ ## License
199
+
200
+ StackMaster uses the MIT license. See [LICENSE.txt](https://github.com/envato/stack_master/blob/master/LICENSE.txt) for details.
201
+
202
+ ## Contributing
203
+
204
+ 1. Fork it ( http://github.com/envato/stack_master/fork )
205
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
206
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
207
+ 4. Push to the branch (`git push origin my-new-feature`)
208
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'bundler/setup'
3
+
4
+ task :environment do
5
+ require 'stack_master'
6
+ end
7
+
8
+ task :console => :environment do
9
+ require 'pry'
10
+ binding.pry
11
+ end
Binary file
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'stack_master'
5
+
6
+ if ENV['STUB_AWS'] == 'true'
7
+ require 'stack_master/testing'
8
+ end
9
+
10
+ trap("SIGINT") { raise StackMaster::CtrlC }
11
+
12
+ begin
13
+ StackMaster::CLI.new(ARGV.dup).execute!
14
+ rescue StackMaster::CtrlC
15
+ StackMaster.stdout.puts "Exiting..."
16
+ end
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'stack_master', path: '../../'
@@ -0,0 +1 @@
1
+ vpc_az_1: ap-southeast-2a
@@ -0,0 +1,2 @@
1
+ VpcId:
2
+ stack_output: myapp-vpc/VpcId
@@ -0,0 +1,13 @@
1
+ stack_defaults:
2
+ tags:
3
+ application: my-awesome-app
4
+ region_defaults:
5
+ ap_southeast_2:
6
+ tags:
7
+ environment: production
8
+ stacks:
9
+ ap_southeast_2:
10
+ myapp_vpc:
11
+ template: myapp_vpc.rb
12
+ myapp_web:
13
+ template: myapp_web.rb
@@ -0,0 +1,39 @@
1
+ SparkleFormation.new(:myapp_vpc) do
2
+ description "A test VPC template"
3
+
4
+ resources.vpc do
5
+ type 'AWS::EC2::VPC'
6
+ properties do
7
+ cidr_block '10.200.0.0/16'
8
+ end
9
+ end
10
+
11
+ parameters.vpc_az_1 do
12
+ description 'VPC AZ 1'
13
+ type 'AWS::EC2::AvailabilityZone::Name'
14
+ end
15
+
16
+ resources.public_subnet do
17
+ type 'AWS::EC2::Subnet'
18
+ properties do
19
+ vpc_id ref!(:vpc)
20
+ cidr_block '10.200.1.0/24'
21
+ availability_zone ref!(:vpc_az_1)
22
+ tags _array(
23
+ { Key: 'Name', Value: 'PublicSubnet' },
24
+ { Key: 'network', Value: 'public' }
25
+ )
26
+ end
27
+ end
28
+
29
+ outputs do
30
+ vpc_id do
31
+ description 'VPC ID'
32
+ value ref!(:vpc)
33
+ end
34
+ public_subnet do
35
+ description 'Public subnet'
36
+ value ref!(:public_subnet)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ SparkleFormation.new(:myapp_web) do
2
+ description "Test web template"
3
+
4
+ parameters.vpc_id do
5
+ description 'VPC ID'
6
+ type 'String'
7
+ end
8
+
9
+ resources.web_sg do
10
+ type 'AWS::EC2::SecurityGroup'
11
+ properties do
12
+ group_description 'Security group for web instances'
13
+ vpc_id ref!(:vpc_id)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,241 @@
1
+ Feature: Apply command
2
+
3
+ Background:
4
+ Given a file named "stack_master.yml" with:
5
+ """
6
+ stacks:
7
+ us_east_1:
8
+ myapp_vpc:
9
+ template: myapp_vpc.rb
10
+ myapp_web:
11
+ template: myapp_web.rb
12
+ """
13
+ And a directory named "parameters"
14
+ And a file named "parameters/myapp_vpc.yml" with:
15
+ """
16
+ KeyName: my-key
17
+ """
18
+ And a directory named "templates"
19
+ And a file named "templates/myapp_vpc.rb" with:
20
+ """
21
+ SparkleFormation.new(:myapp_vpc) do
22
+ description "Test template"
23
+ set!('AWSTemplateFormatVersion', '2010-09-09')
24
+
25
+ parameters.key_name do
26
+ description 'Key name'
27
+ type 'String'
28
+ end
29
+
30
+ resources.vpc do
31
+ type 'AWS::EC2::VPC'
32
+ properties do
33
+ cidr_block '10.200.0.0/16'
34
+ end
35
+ end
36
+
37
+ outputs do
38
+ vpc_id do
39
+ description 'A VPC ID'
40
+ value ref!(:vpc)
41
+ end
42
+ end
43
+ end
44
+ """
45
+ And a file named "templates/myapp_web.rb" with:
46
+ """
47
+ SparkleFormation.new(:myapp_web) do
48
+ description "Test template"
49
+ set!('AWSTemplateFormatVersion', '2010-09-09')
50
+
51
+ parameters.vpc_id do
52
+ description 'VPC ID'
53
+ type 'AWS::EC2::VPC::Id'
54
+ end
55
+
56
+ resources.test_sg do
57
+ type 'AWS::EC2::SecurityGroup'
58
+ properties do
59
+ group_description 'Test SG'
60
+ vpc_id ref!(:vpc_id)
61
+ end
62
+ end
63
+ end
64
+ """
65
+ And I set the environment variables to:
66
+ | variable | value |
67
+ | STUB_AWS | true |
68
+
69
+ Scenario: Run apply and create a new stack
70
+ Given I set the environment variables to:
71
+ | variable | value |
72
+ | ANSWER | y |
73
+ And I stub the following stack events:
74
+ | stack_id | event_id | stack_name | logical_resource_id | resource_status | resource_type | timestamp |
75
+ | 1 | 1 | myapp-vpc | TestSg | CREATE_COMPLETE | AWS::EC2::SecurityGroup | 2020-10-29 00:00:00 |
76
+ | 1 | 1 | myapp-vpc | myapp-vpc | CREATE_COMPLETE | AWS::CloudFormation::Stack | 2020-10-29 00:00:00 |
77
+ When I run `stack_master apply us-east-1 myapp-vpc --trace` interactively
78
+ And the output should contain all of these lines:
79
+ | Stack diff: |
80
+ | + "Vpc": { |
81
+ | Parameters diff: |
82
+ | KeyName: my-key |
83
+ | 2020-10-29 00:00:00 +1100 myapp-vpc AWS::CloudFormation::Stack CREATE_COMPLETE |
84
+ Then the exit status should be 0
85
+
86
+ Scenario: Run apply and don't create the stack
87
+ Given I set the environment variables to:
88
+ | variable | value |
89
+ | ANSWER | n |
90
+ When I run `stack_master apply us-east-1 myapp-vpc --trace` interactively
91
+ And the output should contain all of these lines:
92
+ | Stack diff: |
93
+ | + "Vpc": { |
94
+ | Parameters diff: |
95
+ | KeyName: my-key |
96
+ | aborted |
97
+ And the output should not contain all of these lines:
98
+ | 2020-10-29 00:00:00 +1100 myapp-vpc AWS::CloudFormation::Stack CREATE_COMPLETE |
99
+ Then the exit status should be 0
100
+
101
+ Scenario: Run apply on an existing stack
102
+ Given I set the environment variables to:
103
+ | variable | value |
104
+ | ANSWER | y |
105
+ And I stub the following stack events:
106
+ | stack_id | event_id | stack_name | logical_resource_id | resource_status | resource_type | timestamp |
107
+ | 1 | 1 | myapp-vpc | TestSg | CREATE_COMPLETE | AWS::EC2::SecurityGroup | 2020-10-29 00:00:00 |
108
+ | 1 | 1 | myapp-vpc | myapp-vpc | CREATE_COMPLETE | AWS::CloudFormation::Stack | 2020-10-29 00:00:00 |
109
+ And I stub the following stacks:
110
+ | stack_id | stack_name | parameters | region |
111
+ | 1 | myapp-vpc | KeyName=my-key | us-east-1 |
112
+ And I stub a template for the stack "myapp-vpc":
113
+ """
114
+ {
115
+ "Description": "Test template",
116
+ "AWSTemplateFormatVersion": "2010-09-09",
117
+ "Parameters": {
118
+ "KeyName": {
119
+ "Description": "Key Name",
120
+ "Type": "String"
121
+ }
122
+ },
123
+ "Resources": {
124
+ "TestSg": {
125
+ "Type": "AWS::EC2::SecurityGroup",
126
+ "Properties": {
127
+ "GroupDescription": "Test SG",
128
+ "VpcId": {
129
+ "Ref": "VpcId"
130
+ }
131
+ }
132
+ },
133
+ "TestSg2": {
134
+ "Type": "AWS::EC2::SecurityGroup",
135
+ "Properties": {
136
+ "GroupDescription": "Test SG 2",
137
+ "VpcId": {
138
+ "Ref": "VpcId"
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ """
145
+ When I run `stack_master apply us-east-1 myapp-vpc --trace` interactively
146
+ And the output should contain all of these lines:
147
+ | Stack diff: |
148
+ | - "TestSg2": { |
149
+ | Parameters diff: No changes |
150
+ Then the exit status should be 0
151
+
152
+ Scenario: Create a stack using a stack output resolver
153
+ Given I set the environment variables to:
154
+ | variable | value |
155
+ | ANSWER | y |
156
+ And a file named "parameters/myapp_web.yml" with:
157
+ """
158
+ VpcId:
159
+ stack_output: myapp-vpc/VpcId
160
+ """
161
+ And I stub the following stack events:
162
+ | stack_id | event_id | stack_name | logical_resource_id | resource_status | resource_type | timestamp |
163
+ | 1 | 1 | myapp-web | TestSg | CREATE_COMPLETE | AWS::EC2::SecurityGroup | 2020-10-29 00:00:00 |
164
+ | 1 | 1 | myapp-web | myapp-web | CREATE_COMPLETE | AWS::CloudFormation::Stack | 2020-10-29 00:00:00 |
165
+ And I stub the following stacks:
166
+ | stack_id | stack_name | region | outputs |
167
+ | 1 | myapp-vpc | us-east-1 | VpcId=vpc-xxxxxx |
168
+ When I run `stack_master apply us-east-1 myapp-web --trace` interactively
169
+ And the output should contain all of these lines:
170
+ | Stack diff: |
171
+ | + "TestSg": { |
172
+ | Parameters diff: |
173
+ | VpcId: vpc-xxxxxx |
174
+ | 2020-10-29 00:00:00 +1100 myapp-web AWS::CloudFormation::Stack CREATE_COMPLETE |
175
+ Then the exit status should be 0
176
+
177
+ Scenario: Create a stack with a notification ARN and a stack update policy
178
+ Given a file named "stack_master.yml" with:
179
+ """
180
+ stacks:
181
+ us_east_1:
182
+ myapp_vpc:
183
+ template: myapp_vpc.rb
184
+ notification_arns:
185
+ - test_arn
186
+ stack_policy_file: no_rds_replacement.json
187
+ """
188
+ And a file named "policies/no_rds_replacement.json" with:
189
+ """
190
+ {}
191
+ """
192
+ And I set the environment variables to:
193
+ | variable | value |
194
+ | ANSWER | y |
195
+ And I stub the following stack events:
196
+ | stack_id | event_id | stack_name | logical_resource_id | resource_status | resource_type | timestamp |
197
+ | 1 | 1 | myapp-vpc | TestSg | CREATE_COMPLETE | AWS::EC2::SecurityGroup | 2020-10-29 00:00:00 |
198
+ | 1 | 1 | myapp-vpc | myapp-vpc | CREATE_COMPLETE | AWS::CloudFormation::Stack | 2020-10-29 00:00:00 |
199
+ And I stub the following stacks:
200
+ | stack_id | stack_name | parameters | region |
201
+ | 1 | myapp-vpc | KeyName=my-key | us-east-1 |
202
+ And I stub a template for the stack "myapp-vpc":
203
+ """
204
+ {
205
+ "Description": "Test template",
206
+ "AWSTemplateFormatVersion": "2010-09-09",
207
+ "Parameters": {
208
+ "KeyName": {
209
+ "Description": "Key Name",
210
+ "Type": "String"
211
+ }
212
+ },
213
+ "Resources": {
214
+ "TestSg": {
215
+ "Type": "AWS::EC2::SecurityGroup",
216
+ "Properties": {
217
+ "GroupDescription": "Test SG",
218
+ "VpcId": {
219
+ "Ref": "VpcId"
220
+ }
221
+ }
222
+ },
223
+ "TestSg2": {
224
+ "Type": "AWS::EC2::SecurityGroup",
225
+ "Properties": {
226
+ "GroupDescription": "Test SG 2",
227
+ "VpcId": {
228
+ "Ref": "VpcId"
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+ """
235
+ When I run `stack_master apply us-east-1 myapp-vpc --trace` interactively
236
+ Then the stack "myapp-vpc" should have a policy with the following:
237
+ """
238
+ {}
239
+ """
240
+ And the stack "myapp-vpc" should contain this notification ARN "test_arn"
241
+ Then the exit status should be 0