stack_master 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +208 -0
- data/Rakefile +11 -0
- data/apply_demo.gif +0 -0
- data/bin/stack_master +16 -0
- data/example/simple/Gemfile +3 -0
- data/example/simple/parameters/myapp_vpc.yml +1 -0
- data/example/simple/parameters/myapp_web.yml +2 -0
- data/example/simple/stack_master.yml +13 -0
- data/example/simple/templates/myapp_vpc.rb +39 -0
- data/example/simple/templates/myapp_web.rb +16 -0
- data/features/apply.feature +241 -0
- data/features/delete.feature +43 -0
- data/features/diff.feature +191 -0
- data/features/events.feature +38 -0
- data/features/init.feature +6 -0
- data/features/outputs.feature +49 -0
- data/features/region_aliases.feature +66 -0
- data/features/resources.feature +45 -0
- data/features/stack_defaults.feature +88 -0
- data/features/status.feature +124 -0
- data/features/step_definitions/stack_steps.rb +50 -0
- data/features/support/env.rb +14 -0
- data/lib/stack_master.rb +81 -0
- data/lib/stack_master/aws_driver/cloud_formation.rb +56 -0
- data/lib/stack_master/cli.rb +164 -0
- data/lib/stack_master/command.rb +13 -0
- data/lib/stack_master/commands/apply.rb +104 -0
- data/lib/stack_master/commands/delete.rb +53 -0
- data/lib/stack_master/commands/diff.rb +31 -0
- data/lib/stack_master/commands/events.rb +39 -0
- data/lib/stack_master/commands/init.rb +109 -0
- data/lib/stack_master/commands/list_stacks.rb +16 -0
- data/lib/stack_master/commands/outputs.rb +27 -0
- data/lib/stack_master/commands/resources.rb +33 -0
- data/lib/stack_master/commands/status.rb +47 -0
- data/lib/stack_master/commands/validate.rb +17 -0
- data/lib/stack_master/config.rb +86 -0
- data/lib/stack_master/ctrl_c.rb +4 -0
- data/lib/stack_master/parameter_loader.rb +17 -0
- data/lib/stack_master/parameter_resolver.rb +45 -0
- data/lib/stack_master/parameter_resolvers/secret.rb +42 -0
- data/lib/stack_master/parameter_resolvers/security_group.rb +20 -0
- data/lib/stack_master/parameter_resolvers/sns_topic_name.rb +29 -0
- data/lib/stack_master/parameter_resolvers/stack_output.rb +53 -0
- data/lib/stack_master/prompter.rb +14 -0
- data/lib/stack_master/security_group_finder.rb +29 -0
- data/lib/stack_master/sns_topic_finder.rb +27 -0
- data/lib/stack_master/stack.rb +96 -0
- data/lib/stack_master/stack_definition.rb +49 -0
- data/lib/stack_master/stack_differ.rb +80 -0
- data/lib/stack_master/stack_events/fetcher.rb +45 -0
- data/lib/stack_master/stack_events/presenter.rb +27 -0
- data/lib/stack_master/stack_events/streamer.rb +55 -0
- data/lib/stack_master/stack_states.rb +34 -0
- data/lib/stack_master/template_compiler.rb +21 -0
- data/lib/stack_master/test_driver/cloud_formation.rb +139 -0
- data/lib/stack_master/testing.rb +7 -0
- data/lib/stack_master/utils.rb +31 -0
- data/lib/stack_master/validator.rb +25 -0
- data/lib/stack_master/version.rb +3 -0
- data/logo.png +0 -0
- data/script/buildkite/bundle.sh +5 -0
- data/script/buildkite/clean.sh +3 -0
- data/script/buildkite_rspec.sh +27 -0
- data/spec/fixtures/parameters/myapp_vpc.yml +1 -0
- data/spec/fixtures/stack_master.yml +35 -0
- data/spec/fixtures/templates/myapp_vpc.json +1 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/stack_master/commands/apply_spec.rb +92 -0
- data/spec/stack_master/commands/delete_spec.rb +40 -0
- data/spec/stack_master/commands/init_spec.rb +17 -0
- data/spec/stack_master/commands/status_spec.rb +38 -0
- data/spec/stack_master/commands/validate_spec.rb +26 -0
- data/spec/stack_master/config_spec.rb +81 -0
- data/spec/stack_master/parameter_loader_spec.rb +81 -0
- data/spec/stack_master/parameter_resolver_spec.rb +58 -0
- data/spec/stack_master/parameter_resolvers/secret_spec.rb +66 -0
- data/spec/stack_master/parameter_resolvers/security_group_spec.rb +17 -0
- data/spec/stack_master/parameter_resolvers/sns_topic_name_spec.rb +43 -0
- data/spec/stack_master/parameter_resolvers/stack_output_spec.rb +77 -0
- data/spec/stack_master/security_group_finder_spec.rb +49 -0
- data/spec/stack_master/sns_topic_finder_spec.rb +25 -0
- data/spec/stack_master/stack_definition_spec.rb +37 -0
- data/spec/stack_master/stack_differ_spec.rb +34 -0
- data/spec/stack_master/stack_events/fetcher_spec.rb +65 -0
- data/spec/stack_master/stack_events/presenter_spec.rb +18 -0
- data/spec/stack_master/stack_events/streamer_spec.rb +33 -0
- data/spec/stack_master/stack_spec.rb +157 -0
- data/spec/stack_master/template_compiler_spec.rb +48 -0
- data/spec/stack_master/test_driver/cloud_formation_spec.rb +24 -0
- data/spec/stack_master/utils_spec.rb +30 -0
- data/spec/stack_master/validator_spec.rb +38 -0
- data/stack_master.gemspec +38 -0
- data/stacktemplates/parameter_region.yml +3 -0
- data/stacktemplates/parameter_stack_name.yml +3 -0
- data/stacktemplates/stack.json.erb +20 -0
- data/stacktemplates/stack_master.yml.erb +6 -0
- metadata +427 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
data/apply_demo.gif
ADDED
Binary file
|
data/bin/stack_master
ADDED
@@ -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 @@
|
|
1
|
+
vpc_az_1: ap-southeast-2a
|
@@ -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
|