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.
- 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
|
+

|
|
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
|
+

|
|
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
|