stack_master 1.6.0-x64-mingw32
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/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
|
+

|
2
|
+
|
3
|
+
[](https://github.com/envato/stack_master/blob/master/LICENSE.md)
|
4
|
+
[](https://badge.fury.io/rb/stack_master)
|
5
|
+
[](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
|
+

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