stack_master 1.6.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +548 -0
- data/bin/stack_master +17 -0
- data/lib/stack_master.rb +159 -0
- data/lib/stack_master/aws_driver/cloud_formation.rb +41 -0
- data/lib/stack_master/aws_driver/s3.rb +68 -0
- data/lib/stack_master/change_set.rb +109 -0
- data/lib/stack_master/cli.rb +208 -0
- data/lib/stack_master/command.rb +57 -0
- data/lib/stack_master/commands/apply.rb +221 -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 +111 -0
- data/lib/stack_master/commands/list_stacks.rb +20 -0
- data/lib/stack_master/commands/outputs.rb +31 -0
- data/lib/stack_master/commands/resources.rb +33 -0
- data/lib/stack_master/commands/status.rb +46 -0
- data/lib/stack_master/commands/terminal_helper.rb +28 -0
- data/lib/stack_master/commands/validate.rb +17 -0
- data/lib/stack_master/config.rb +133 -0
- data/lib/stack_master/ctrl_c.rb +4 -0
- data/lib/stack_master/paged_response_accumulator.rb +29 -0
- data/lib/stack_master/parameter_loader.rb +49 -0
- data/lib/stack_master/parameter_resolver.rb +98 -0
- data/lib/stack_master/parameter_resolvers/ami_finder.rb +36 -0
- data/lib/stack_master/parameter_resolvers/env.rb +18 -0
- data/lib/stack_master/parameter_resolvers/latest_ami.rb +19 -0
- data/lib/stack_master/parameter_resolvers/latest_ami_by_tags.rb +18 -0
- data/lib/stack_master/parameter_resolvers/parameter_store.rb +31 -0
- data/lib/stack_master/parameter_resolvers/secret.rb +52 -0
- data/lib/stack_master/parameter_resolvers/security_group.rb +22 -0
- data/lib/stack_master/parameter_resolvers/sns_topic_name.rb +31 -0
- data/lib/stack_master/parameter_resolvers/stack_output.rb +76 -0
- data/lib/stack_master/prompter.rb +21 -0
- data/lib/stack_master/resolver_array.rb +35 -0
- data/lib/stack_master/security_group_finder.rb +28 -0
- data/lib/stack_master/sns_topic_finder.rb +26 -0
- data/lib/stack_master/sparkle_formation/compile_time/allowed_pattern_validator.rb +35 -0
- data/lib/stack_master/sparkle_formation/compile_time/allowed_values_validator.rb +37 -0
- data/lib/stack_master/sparkle_formation/compile_time/definitions_validator.rb +33 -0
- data/lib/stack_master/sparkle_formation/compile_time/empty_validator.rb +32 -0
- data/lib/stack_master/sparkle_formation/compile_time/max_length_validator.rb +36 -0
- data/lib/stack_master/sparkle_formation/compile_time/max_size_validator.rb +36 -0
- data/lib/stack_master/sparkle_formation/compile_time/min_length_validator.rb +36 -0
- data/lib/stack_master/sparkle_formation/compile_time/min_size_validator.rb +36 -0
- data/lib/stack_master/sparkle_formation/compile_time/number_validator.rb +35 -0
- data/lib/stack_master/sparkle_formation/compile_time/parameters_validator.rb +27 -0
- data/lib/stack_master/sparkle_formation/compile_time/state_builder.rb +32 -0
- data/lib/stack_master/sparkle_formation/compile_time/string_validator.rb +33 -0
- data/lib/stack_master/sparkle_formation/compile_time/value_builder.rb +40 -0
- data/lib/stack_master/sparkle_formation/compile_time/value_validator.rb +40 -0
- data/lib/stack_master/sparkle_formation/compile_time/value_validator_factory.rb +41 -0
- data/lib/stack_master/sparkle_formation/template_file.rb +115 -0
- data/lib/stack_master/stack.rb +105 -0
- data/lib/stack_master/stack_definition.rb +103 -0
- data/lib/stack_master/stack_differ.rb +111 -0
- data/lib/stack_master/stack_events/fetcher.rb +38 -0
- data/lib/stack_master/stack_events/presenter.rb +27 -0
- data/lib/stack_master/stack_events/streamer.rb +68 -0
- data/lib/stack_master/stack_states.rb +34 -0
- data/lib/stack_master/stack_status.rb +61 -0
- data/lib/stack_master/template_compiler.rb +30 -0
- data/lib/stack_master/template_compilers/cfndsl.rb +13 -0
- data/lib/stack_master/template_compilers/json.rb +22 -0
- data/lib/stack_master/template_compilers/sparkle_formation.rb +71 -0
- data/lib/stack_master/template_compilers/yaml.rb +14 -0
- data/lib/stack_master/template_utils.rb +31 -0
- data/lib/stack_master/test_driver/cloud_formation.rb +193 -0
- data/lib/stack_master/test_driver/s3.rb +34 -0
- data/lib/stack_master/testing.rb +9 -0
- data/lib/stack_master/utils.rb +50 -0
- data/lib/stack_master/validator.rb +33 -0
- data/lib/stack_master/version.rb +3 -0
- metadata +457 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8047714e53694bdbdc5df17e1251890f837ce9e8
|
4
|
+
data.tar.gz: 91b1ddd6984d7db56c4f753a30746586d771b044
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4e1e69e10b0b9ec16ab50a8d9b8aaebe7cb0ca19e2e8a68c9273e9902106846d66fbb57c2cc6357414c3e9b08759d732335b0bd2cb965c2f714187f4fc7195c9
|
7
|
+
data.tar.gz: 272c24b02149e636e06f6c4a8f5178e7e7efcd1746eed8b743974c94c6d397233b359989b817b318213235728b350011018168cdd559ab3012e22ed9f9c8ce07
|
data/README.md
ADDED
@@ -0,0 +1,548 @@
|
|
1
|
+
![StackMaster](/logo.png?raw=true)
|
2
|
+
|
3
|
+
[![License MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/envato/stack_master/blob/master/LICENSE.md)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/stack_master.svg)](https://badge.fury.io/rb/stack_master)
|
5
|
+
[![Build Status](https://travis-ci.org/envato/stack_master.svg?branch=master)](https://travis-ci.org/envato/stack_master)
|
6
|
+
|
7
|
+
StackMaster is a CLI tool to manage [CloudFormation](https://aws.amazon.com/cloudformation/) stacks, with the following features:
|
8
|
+
|
9
|
+
- Synchronous visibility into stack updates. See exactly what is changing and
|
10
|
+
what will happen before agreeing to apply a change.
|
11
|
+
- Dynamic parameter resolvers.
|
12
|
+
- Template compiler support for YAML and [SparkleFormation](http://www.sparkleformation.io).
|
13
|
+
|
14
|
+
Stack updates can cause a lot of damage if applied blindly. StackMaster helps
|
15
|
+
with this by providing the operator with as much information about the proposed
|
16
|
+
change as possible before asking for confirmation to continue. That information
|
17
|
+
includes:
|
18
|
+
|
19
|
+
- Template body and parameter diffs.
|
20
|
+
- [Change
|
21
|
+
sets](https://aws.amazon.com/blogs/aws/new-change-sets-for-aws-cloudformation/)
|
22
|
+
are displayed for review.
|
23
|
+
- Once the diffs & change set have been reviewed, the change can be applied and
|
24
|
+
stack events monitored.
|
25
|
+
- Stack events will be displayed until an end state is reached.
|
26
|
+
|
27
|
+
Stack parameters can be dynamically resolved at runtime using one of the
|
28
|
+
built in parameter resolvers. Parameters can be sourced from GPG encrypted YAML
|
29
|
+
files, other stacks outputs, by querying various AWS APIs to get resource ARNs,
|
30
|
+
etc.
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
System-wide: `gem install stack_master`
|
35
|
+
|
36
|
+
With bundler:
|
37
|
+
|
38
|
+
- Add `gem 'stack_master'` to your Gemfile.
|
39
|
+
- Run `bundle install`
|
40
|
+
- Run `bundle exec stack_master init` to generate a directory structure and stack_master.yml file
|
41
|
+
|
42
|
+
## Configuration
|
43
|
+
|
44
|
+
Stacks are defined inside a `stack_master.yml` YAML file. When running
|
45
|
+
`stack_master`, it is assumed that this file will exist in the current working
|
46
|
+
directory, or that the file is passed in with `--config
|
47
|
+
/path/to/stack_master.yml`. Here's an example configuration file:
|
48
|
+
|
49
|
+
```
|
50
|
+
region_aliases:
|
51
|
+
production: us-east-1
|
52
|
+
staging: ap-southeast-2
|
53
|
+
stack_defaults:
|
54
|
+
tags:
|
55
|
+
application: my-awesome-app
|
56
|
+
role_arn: service_role_arn
|
57
|
+
region_defaults:
|
58
|
+
us-east-1:
|
59
|
+
secret_file: production.yml.gpg
|
60
|
+
tags:
|
61
|
+
environment: production
|
62
|
+
notification_arns:
|
63
|
+
- test_arn
|
64
|
+
ap-southeast-2:
|
65
|
+
secret_file: staging.yml.gpg
|
66
|
+
tags:
|
67
|
+
environment: staging
|
68
|
+
stacks:
|
69
|
+
production:
|
70
|
+
myapp-vpc:
|
71
|
+
template: myapp_vpc.rb
|
72
|
+
tags:
|
73
|
+
purpose: front-end
|
74
|
+
myapp-db:
|
75
|
+
template: myapp_db.rb
|
76
|
+
stack_policy_file: db_stack_policy.json
|
77
|
+
tags:
|
78
|
+
purpose: back-end
|
79
|
+
myapp-web:
|
80
|
+
template: myapp_web.rb
|
81
|
+
tags:
|
82
|
+
purpose: front-end
|
83
|
+
staging:
|
84
|
+
myapp-vpc:
|
85
|
+
template: myapp_vpc.rb
|
86
|
+
tags:
|
87
|
+
purpose: front-end
|
88
|
+
myapp-db:
|
89
|
+
template: myapp_db.rb
|
90
|
+
tags:
|
91
|
+
purpose: back-end
|
92
|
+
myapp-web:
|
93
|
+
template: myapp_web.rb
|
94
|
+
tags:
|
95
|
+
purpose: front-end
|
96
|
+
eu-central-1:
|
97
|
+
myapp-vpc:
|
98
|
+
template: myapp_vpc.rb
|
99
|
+
tags:
|
100
|
+
purpose: vpc
|
101
|
+
```
|
102
|
+
|
103
|
+
## S3
|
104
|
+
|
105
|
+
StackMaster can optionally use S3 to store the templates before creating a stack.
|
106
|
+
This requires you to configure an S3 bucket in stack_master.yml:
|
107
|
+
|
108
|
+
```yaml
|
109
|
+
stack_defaults:
|
110
|
+
s3:
|
111
|
+
bucket: my_bucket_name
|
112
|
+
prefix: cfn_templates/my-awesome-app
|
113
|
+
region: us-west-2
|
114
|
+
```
|
115
|
+
|
116
|
+
Additional files can be configured to be uploaded to S3 alongside the templates:
|
117
|
+
```yaml
|
118
|
+
stacks:
|
119
|
+
production:
|
120
|
+
myapp-vpc:
|
121
|
+
template: myapp_vpc.rb
|
122
|
+
files:
|
123
|
+
- userdata.sh
|
124
|
+
```
|
125
|
+
## Directories
|
126
|
+
|
127
|
+
- `templates` - CloudFormation, SparkleFormation or CfnDsl templates.
|
128
|
+
- `parameters` - Parameters as YAML files.
|
129
|
+
- `secrets` - GPG encrypted secret files.
|
130
|
+
- `policies` - Stack policy JSON files.
|
131
|
+
|
132
|
+
## Templates
|
133
|
+
|
134
|
+
StackMaster supports CloudFormation templates in plain JSON or YAML. Any `.yml` or `.yaml` file will be processed as
|
135
|
+
YAML, while any `.json` file will be processed as JSON.
|
136
|
+
|
137
|
+
### Ruby DSLs
|
138
|
+
By default, any template ending with `.rb` will be processed as a [SparkleFormation](https://github.com/sparkleformation/sparkle_formation)
|
139
|
+
template. However, if you want to use [CfnDsl](https://github.com/stevenjack/cfndsl) templates you can add
|
140
|
+
the following lines to your `stack_master.yml`.
|
141
|
+
|
142
|
+
```
|
143
|
+
template_compilers:
|
144
|
+
rb: cfndsl
|
145
|
+
```
|
146
|
+
|
147
|
+
## Parameters
|
148
|
+
|
149
|
+
Parameters are loaded from multiple YAML files, merged from the following lookup paths from bottom to top:
|
150
|
+
|
151
|
+
- parameters/[stack_name].yaml
|
152
|
+
- parameters/[stack_name].yml
|
153
|
+
- parameters/[region]/[underscored_stack_name].yaml
|
154
|
+
- parameters/[region]/[underscored_stack_name].yml
|
155
|
+
- parameters/[region_alias]/[underscored_stack_name].yaml
|
156
|
+
- parameters/[region_alias]/[underscored_stack_name].yml
|
157
|
+
|
158
|
+
A simple parameter file could look like this:
|
159
|
+
|
160
|
+
```
|
161
|
+
key_name: myapp-us-east-1
|
162
|
+
```
|
163
|
+
|
164
|
+
### Compile Time Parameters
|
165
|
+
|
166
|
+
Compile time parameters can be used for [SparkleFormation](http://www.sparkleformation.io) templates. It conforms and
|
167
|
+
allows you to use the [Compile Time Parameters](http://www.sparkleformation.io/docs/sparkle_formation/compile-time-parameters.html) feature.
|
168
|
+
|
169
|
+
A simple example looks like this
|
170
|
+
|
171
|
+
```
|
172
|
+
vpc_cidr: 10.0.0.0/16
|
173
|
+
compile_time_parameters:
|
174
|
+
subnet_cidrs:
|
175
|
+
- 10.0.0.0/28
|
176
|
+
- 10.0.2.0/28
|
177
|
+
```
|
178
|
+
|
179
|
+
Keys in parameter files are automatically converted to camel case.
|
180
|
+
|
181
|
+
## Parameter Resolvers
|
182
|
+
|
183
|
+
Parameter values can be sourced dynamically using parameter resolvers.
|
184
|
+
|
185
|
+
One benefit of using parameter resolvers instead of hard coding values like VPC
|
186
|
+
IDs and resource ARNs is that the same configuration works cross
|
187
|
+
region/account, even though the resolved values will be different.
|
188
|
+
|
189
|
+
### Stack Output
|
190
|
+
|
191
|
+
The stack output parameter resolver looks up outputs from other stacks in the
|
192
|
+
same or different region. The expected format is `[(region|region-alias):]stack-name/(OutputName|output_name)`.
|
193
|
+
|
194
|
+
```yaml
|
195
|
+
vpc_id:
|
196
|
+
# Output from a stack in the same region
|
197
|
+
stack_output: my-vpc-stack/VpcId
|
198
|
+
|
199
|
+
bucket_name:
|
200
|
+
# Output from a stack in a different region
|
201
|
+
stack_output: us-east-1:init-bucket/bucket_name
|
202
|
+
|
203
|
+
zone_name:
|
204
|
+
# Output from a stack in a different region using its alias
|
205
|
+
stack_output: global:hosted-zone/ZoneName
|
206
|
+
```
|
207
|
+
|
208
|
+
This is the most used parameter resolver because it enables stacks to be split
|
209
|
+
up into their separated concerns (VPC, web, database etc) with outputs feeding
|
210
|
+
into parameters of dependent stacks.
|
211
|
+
|
212
|
+
### Secret
|
213
|
+
|
214
|
+
Note: This resolver is not supported on Windows, you can instead use the [Parameter Store](#parameter-store).
|
215
|
+
|
216
|
+
The secret parameters resolver expects a `secret_file` to be defined in the
|
217
|
+
stack definition which is a GPG encrypted YAML file. Once decrypted and parsed,
|
218
|
+
the value provided to the secret resolver is used to lookup the associated key
|
219
|
+
in the secret file. A common use case for this is to store database passwords.
|
220
|
+
|
221
|
+
stack_master.yml:
|
222
|
+
|
223
|
+
```yaml
|
224
|
+
stacks:
|
225
|
+
us-east-1:
|
226
|
+
my_app:
|
227
|
+
template: my_app.json
|
228
|
+
secret_file: production.yml.gpg
|
229
|
+
```
|
230
|
+
|
231
|
+
secrets/production.yml.gpg, when decrypted:
|
232
|
+
|
233
|
+
```yaml
|
234
|
+
db_password: my-password
|
235
|
+
```
|
236
|
+
|
237
|
+
parameters/my_app.yml:
|
238
|
+
|
239
|
+
```yaml
|
240
|
+
db_password:
|
241
|
+
secret: db_password
|
242
|
+
```
|
243
|
+
|
244
|
+
### Parameter Store
|
245
|
+
|
246
|
+
An alternative to the secrets store, uses the AWS SSM Parameter store to protect
|
247
|
+
secrets. Expects a parameter of either `String` or `SecureString` type to be present in the
|
248
|
+
same region as the stack. You can store the parameter using a command like this
|
249
|
+
|
250
|
+
`aws ssm put-parameter --region <region> --name <parameter name> --value <secret> --type (String|SecureString)`
|
251
|
+
|
252
|
+
When doing so make sure you don't accidentally store the secret in your `.bash_history` and
|
253
|
+
you will likely want to set the parameter to NoEcho in your template.
|
254
|
+
|
255
|
+
```yaml
|
256
|
+
db_password:
|
257
|
+
parameter_store: ssm_parameter_name
|
258
|
+
```
|
259
|
+
|
260
|
+
### Security Group
|
261
|
+
|
262
|
+
Looks up a security group by name and returns the ARN.
|
263
|
+
|
264
|
+
```yaml
|
265
|
+
ssh_sg:
|
266
|
+
security_group: SSHSecurityGroup
|
267
|
+
```
|
268
|
+
|
269
|
+
### Security Groups
|
270
|
+
|
271
|
+
An array of security group names can also be provided.
|
272
|
+
```yaml
|
273
|
+
ssh_sg:
|
274
|
+
security_groups:
|
275
|
+
- SSHSecurityGroup
|
276
|
+
- WebAccessSecurityGroup
|
277
|
+
```
|
278
|
+
|
279
|
+
### SNS Topic
|
280
|
+
|
281
|
+
Looks up an SNS topic by name and returns the ARN.
|
282
|
+
|
283
|
+
```yaml
|
284
|
+
notification_topic:
|
285
|
+
sns_topic_name: PagerDuty
|
286
|
+
```
|
287
|
+
|
288
|
+
### Latest AMI by Tag
|
289
|
+
|
290
|
+
Looks up the latest AMI ID by a given set of tags.
|
291
|
+
|
292
|
+
```yaml
|
293
|
+
web_ami:
|
294
|
+
latest_ami_by_tags: role=web,application=myapp
|
295
|
+
```
|
296
|
+
|
297
|
+
Note that the corresponding array resolver is named `latest_amis_by_tags`.
|
298
|
+
|
299
|
+
### Latest AMI by attribute
|
300
|
+
|
301
|
+
Looks up the latest AMI ID by a given set of attributes. By default it will only return AMIs from the account the stack is created in, but you can specify the account ID or [certain keywords mentioned in the aws documentation](http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-DescribeImages.html)
|
302
|
+
|
303
|
+
This selects the latest wily hvm AMI from Ubuntu (using the account id):
|
304
|
+
|
305
|
+
```yaml
|
306
|
+
bastion_ami:
|
307
|
+
latest_ami:
|
308
|
+
owners: 099720109477
|
309
|
+
filters:
|
310
|
+
name: ubuntu/images/hvm/ubuntu-wily-15.10-amd64-server-*
|
311
|
+
```
|
312
|
+
|
313
|
+
A set of possible attributes is available in the [AWS documentation](https://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Client.html#describe_images-instance_method).
|
314
|
+
|
315
|
+
Any value can be an array of possible matches.
|
316
|
+
|
317
|
+
### Environment Variable
|
318
|
+
|
319
|
+
Lookup an environment variable:
|
320
|
+
|
321
|
+
```yaml
|
322
|
+
db_username:
|
323
|
+
env: DB_USERNAME
|
324
|
+
```
|
325
|
+
|
326
|
+
### Custom parameter resolvers
|
327
|
+
|
328
|
+
New parameter resolvers can be created in a separate gem.
|
329
|
+
|
330
|
+
To create a resolver named my_resolver:
|
331
|
+
* Create a new gem using your favorite tool
|
332
|
+
* The gem structure must contain the following path:
|
333
|
+
```
|
334
|
+
lib/stack_master/parameter_resolvers/my_resolver.rb
|
335
|
+
```
|
336
|
+
* That file needs to contain a class named `StackMaster::ParameterResolvers::MyResolver`
|
337
|
+
that implements a `resolve` method and an initializer taking 2 parameters :
|
338
|
+
```ruby
|
339
|
+
module StackMaster
|
340
|
+
module ParameterResolvers
|
341
|
+
class MyResolver < Resolver
|
342
|
+
array_resolver # Also create a MyResolvers resolver to handle arrays
|
343
|
+
|
344
|
+
def initialize(config, stack_definition)
|
345
|
+
@config = config
|
346
|
+
@stack_definition = stack_definition
|
347
|
+
end
|
348
|
+
|
349
|
+
def resolve(value)
|
350
|
+
value
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
```
|
356
|
+
* Note that the filename and classname are both derived from the resolver name
|
357
|
+
passed in the parameter file. In our case, the parameters YAML would look like:
|
358
|
+
```yaml
|
359
|
+
vpc_id:
|
360
|
+
my_resolver: dummy_value
|
361
|
+
```
|
362
|
+
|
363
|
+
## Resolver Arrays
|
364
|
+
|
365
|
+
Most resolvers support taking an array of values that will each be resolved.
|
366
|
+
Unless stated otherwise in the documentation, the array version of the
|
367
|
+
resolver will be named with the [pluralized](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-pluralize)
|
368
|
+
name of the original resolver.
|
369
|
+
|
370
|
+
When creating a new resolver, one can automatically create the array resolver by adding a `array_resolver` statement
|
371
|
+
in the class definition, with an optional class name if different from the default one.
|
372
|
+
```
|
373
|
+
module StackMaster
|
374
|
+
module ParameterResolvers
|
375
|
+
class MyResolver < Resolver
|
376
|
+
array_resolver class_name: 'MyCustomArrayResolver'
|
377
|
+
...
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
```
|
382
|
+
In that example, using the array resolver would look like:
|
383
|
+
```
|
384
|
+
my_parameter:
|
385
|
+
my_custom_array_resolver:
|
386
|
+
- value1
|
387
|
+
- value2
|
388
|
+
```
|
389
|
+
|
390
|
+
Array parameter values can include nested parameter resolvers.
|
391
|
+
|
392
|
+
For example, given the following parameter definition:
|
393
|
+
```
|
394
|
+
my_parameter:
|
395
|
+
- stack_output: my-stack/output # value resolves to 'value1'
|
396
|
+
- value2
|
397
|
+
```
|
398
|
+
The parameter value will resolve to:
|
399
|
+
```
|
400
|
+
my_parameter: 'value1,value2'
|
401
|
+
```
|
402
|
+
|
403
|
+
## ERB Template Files in SparkleFormation templates
|
404
|
+
|
405
|
+
An extension to SparkleFormation is the `user_data_file!` method, which evaluates templates in `templates/user_data/[file_name]`. Most of the usual SparkleFormation methods are available in user data templates. Example:
|
406
|
+
|
407
|
+
```
|
408
|
+
# templates/user_data/app.erb
|
409
|
+
REGION=<%= region! %>
|
410
|
+
ROLE=<%= role %>
|
411
|
+
```
|
412
|
+
|
413
|
+
And used like this in SparkleFormation templates:
|
414
|
+
|
415
|
+
```
|
416
|
+
# templates/app.rb
|
417
|
+
user_data user_data_file!('app.erb', role: :worker)
|
418
|
+
```
|
419
|
+
|
420
|
+
You can also use the `joined_file!` method which evaluates templates in `templates/config/[file_name]`. It is similar to `user_data_file!` but doesn't do base64 encoding. Example:
|
421
|
+
|
422
|
+
```
|
423
|
+
# templates/config/someconfig.conf.erb
|
424
|
+
my_variable=<%= ref!(:foo) %>
|
425
|
+
my_other_variable=<%= account_id! %>
|
426
|
+
```
|
427
|
+
|
428
|
+
```
|
429
|
+
# templates/ecs_task.rb
|
430
|
+
container_definitions array!(
|
431
|
+
-> {
|
432
|
+
command array!(
|
433
|
+
"-e",
|
434
|
+
joined_file!('someconfig.conf.erb')
|
435
|
+
)
|
436
|
+
...
|
437
|
+
}
|
438
|
+
)
|
439
|
+
```
|
440
|
+
|
441
|
+
## Compiler Options & Alternate Template Directories
|
442
|
+
|
443
|
+
StackMaster allows you to separate your stack definitions and parameters from your templates by way of a `template_dir` key in your stack_master.yml.
|
444
|
+
You can also pass compiler-specific options to the template compiler to further customize SparkleFormation or CfnDsl's behavior. Combining the 2 lets you move your SFN templates away from your stack definitions. For example, if your project is laid out as:
|
445
|
+
|
446
|
+
```
|
447
|
+
project-root
|
448
|
+
|-- envs
|
449
|
+
|-- env-1
|
450
|
+
|-- stack_master.yml
|
451
|
+
|-- env-2
|
452
|
+
|-- stack_master.yml
|
453
|
+
|-- sparkle
|
454
|
+
|-- templates
|
455
|
+
|-- my-stack.rb
|
456
|
+
```
|
457
|
+
|
458
|
+
Your env-1/stack_master.yml files can reference common templates by setting:
|
459
|
+
|
460
|
+
```
|
461
|
+
template_dir: ../../sparkle/templates
|
462
|
+
stack_defaults:
|
463
|
+
compiler_options:
|
464
|
+
sparkle_path: ../../sparkle
|
465
|
+
|
466
|
+
stacks:
|
467
|
+
us-east-1:
|
468
|
+
my-stack:
|
469
|
+
template: my-stack.rb
|
470
|
+
```
|
471
|
+
|
472
|
+
### Loading SparklePacks
|
473
|
+
|
474
|
+
[SparklePacks](http://www.sparkleformation.io/docs/sparkle_formation/sparkle-packs.html) can be pre-loaded using compiler options. This requires the name of a rubygem to `require` followed by the name of the SparklePack, which is usually the same name as the Gem.
|
475
|
+
|
476
|
+
```yaml
|
477
|
+
stacks:
|
478
|
+
us-east-1
|
479
|
+
my-stack:
|
480
|
+
template: my-stack-with-dynamic.rb
|
481
|
+
compiler_options:
|
482
|
+
sparkle_packs:
|
483
|
+
- vpc-sparkle-pack
|
484
|
+
```
|
485
|
+
|
486
|
+
The template can then simply load a dynamic from the sparkle pack like so:
|
487
|
+
|
488
|
+
```ruby
|
489
|
+
SparkleFormation.new(:my_stack_with_dynamic) do
|
490
|
+
dynamic!(:sparkle_pack_dynamic)
|
491
|
+
end
|
492
|
+
```
|
493
|
+
|
494
|
+
Note though that if a dynamic with the same name exists in your `templates/dynamics/` directory it will get loaded since it has higher precedence.
|
495
|
+
|
496
|
+
## Commands
|
497
|
+
|
498
|
+
```bash
|
499
|
+
stack_master help # Display up to date docs on the commands available
|
500
|
+
stack_master init # Initialises a directory structure and stack_master.yml file
|
501
|
+
stack_master list # Lists stack definitions
|
502
|
+
stack_master apply [region-or-alias] [stack-name] # Create or update a stack
|
503
|
+
stack_master apply [region-or-alias] [stack-name] [region-or-alias] [stack-name] # Create or update multiple stacks
|
504
|
+
stack_master apply [region-or-alias] # Create or update stacks in the given region
|
505
|
+
stack_master apply # Create or update all stacks
|
506
|
+
stack_master --changed apply # Create or update all stacks that have changed
|
507
|
+
stack_master --yes apply [region-or-alias] [stack-name] # Create or update a stack non-interactively (forcing yes)
|
508
|
+
stack_master diff [region-or-alias] [stack-name] # Display a stack template and parameter diff
|
509
|
+
stack_master delete [region-or-alias] [stack-name] # Delete a stack
|
510
|
+
stack_master events [region-or-alias] [stack-name] # Display events for a stack
|
511
|
+
stack_master outputs [region-or-alias] [stack-name] # Display outputs for a stack
|
512
|
+
stack_master resources [region-or-alias] [stack-name] # Display outputs for a stack
|
513
|
+
stack_master status # Displays the status of each stack
|
514
|
+
```
|
515
|
+
|
516
|
+
## Applying updates
|
517
|
+
|
518
|
+
The apply command does the following:
|
519
|
+
|
520
|
+
- Compiles the proposed stack template and resolves parameters.
|
521
|
+
- Fetches the current state of the stack from CloudFormation.
|
522
|
+
- Displays a diff of the current stack and the proposed stack.
|
523
|
+
- Creates a change set and displays the actions that CloudFormation will take
|
524
|
+
to perform the update (if the stack already exists).
|
525
|
+
- Asks if the update should continue.
|
526
|
+
- If yes, the API calls are made to update or create the stack.
|
527
|
+
- Stack events are displayed until CloudFormation has finished applying the changes.
|
528
|
+
|
529
|
+
Demo:
|
530
|
+
|
531
|
+
![Apply Demo](/apply_demo.gif?raw=true)
|
532
|
+
|
533
|
+
## Maintainers
|
534
|
+
|
535
|
+
- [Steve Hodgkiss](https://github.com/stevehodgkiss)
|
536
|
+
- [Glen Stampoultzis](https://github.com/gstamp)
|
537
|
+
|
538
|
+
## License
|
539
|
+
|
540
|
+
StackMaster uses the MIT license. See [LICENSE.txt](https://github.com/envato/stack_master/blob/master/LICENSE.txt) for details.
|
541
|
+
|
542
|
+
## Contributing
|
543
|
+
|
544
|
+
1. Fork it ( http://github.com/envato/stack_master/fork )
|
545
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
546
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
547
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
548
|
+
5. Create new Pull Request
|