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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +548 -0
  3. data/bin/stack_master +17 -0
  4. data/lib/stack_master.rb +159 -0
  5. data/lib/stack_master/aws_driver/cloud_formation.rb +41 -0
  6. data/lib/stack_master/aws_driver/s3.rb +68 -0
  7. data/lib/stack_master/change_set.rb +109 -0
  8. data/lib/stack_master/cli.rb +208 -0
  9. data/lib/stack_master/command.rb +57 -0
  10. data/lib/stack_master/commands/apply.rb +221 -0
  11. data/lib/stack_master/commands/delete.rb +53 -0
  12. data/lib/stack_master/commands/diff.rb +31 -0
  13. data/lib/stack_master/commands/events.rb +39 -0
  14. data/lib/stack_master/commands/init.rb +111 -0
  15. data/lib/stack_master/commands/list_stacks.rb +20 -0
  16. data/lib/stack_master/commands/outputs.rb +31 -0
  17. data/lib/stack_master/commands/resources.rb +33 -0
  18. data/lib/stack_master/commands/status.rb +46 -0
  19. data/lib/stack_master/commands/terminal_helper.rb +28 -0
  20. data/lib/stack_master/commands/validate.rb +17 -0
  21. data/lib/stack_master/config.rb +133 -0
  22. data/lib/stack_master/ctrl_c.rb +4 -0
  23. data/lib/stack_master/paged_response_accumulator.rb +29 -0
  24. data/lib/stack_master/parameter_loader.rb +49 -0
  25. data/lib/stack_master/parameter_resolver.rb +98 -0
  26. data/lib/stack_master/parameter_resolvers/ami_finder.rb +36 -0
  27. data/lib/stack_master/parameter_resolvers/env.rb +18 -0
  28. data/lib/stack_master/parameter_resolvers/latest_ami.rb +19 -0
  29. data/lib/stack_master/parameter_resolvers/latest_ami_by_tags.rb +18 -0
  30. data/lib/stack_master/parameter_resolvers/parameter_store.rb +31 -0
  31. data/lib/stack_master/parameter_resolvers/secret.rb +52 -0
  32. data/lib/stack_master/parameter_resolvers/security_group.rb +22 -0
  33. data/lib/stack_master/parameter_resolvers/sns_topic_name.rb +31 -0
  34. data/lib/stack_master/parameter_resolvers/stack_output.rb +76 -0
  35. data/lib/stack_master/prompter.rb +21 -0
  36. data/lib/stack_master/resolver_array.rb +35 -0
  37. data/lib/stack_master/security_group_finder.rb +28 -0
  38. data/lib/stack_master/sns_topic_finder.rb +26 -0
  39. data/lib/stack_master/sparkle_formation/compile_time/allowed_pattern_validator.rb +35 -0
  40. data/lib/stack_master/sparkle_formation/compile_time/allowed_values_validator.rb +37 -0
  41. data/lib/stack_master/sparkle_formation/compile_time/definitions_validator.rb +33 -0
  42. data/lib/stack_master/sparkle_formation/compile_time/empty_validator.rb +32 -0
  43. data/lib/stack_master/sparkle_formation/compile_time/max_length_validator.rb +36 -0
  44. data/lib/stack_master/sparkle_formation/compile_time/max_size_validator.rb +36 -0
  45. data/lib/stack_master/sparkle_formation/compile_time/min_length_validator.rb +36 -0
  46. data/lib/stack_master/sparkle_formation/compile_time/min_size_validator.rb +36 -0
  47. data/lib/stack_master/sparkle_formation/compile_time/number_validator.rb +35 -0
  48. data/lib/stack_master/sparkle_formation/compile_time/parameters_validator.rb +27 -0
  49. data/lib/stack_master/sparkle_formation/compile_time/state_builder.rb +32 -0
  50. data/lib/stack_master/sparkle_formation/compile_time/string_validator.rb +33 -0
  51. data/lib/stack_master/sparkle_formation/compile_time/value_builder.rb +40 -0
  52. data/lib/stack_master/sparkle_formation/compile_time/value_validator.rb +40 -0
  53. data/lib/stack_master/sparkle_formation/compile_time/value_validator_factory.rb +41 -0
  54. data/lib/stack_master/sparkle_formation/template_file.rb +115 -0
  55. data/lib/stack_master/stack.rb +105 -0
  56. data/lib/stack_master/stack_definition.rb +103 -0
  57. data/lib/stack_master/stack_differ.rb +111 -0
  58. data/lib/stack_master/stack_events/fetcher.rb +38 -0
  59. data/lib/stack_master/stack_events/presenter.rb +27 -0
  60. data/lib/stack_master/stack_events/streamer.rb +68 -0
  61. data/lib/stack_master/stack_states.rb +34 -0
  62. data/lib/stack_master/stack_status.rb +61 -0
  63. data/lib/stack_master/template_compiler.rb +30 -0
  64. data/lib/stack_master/template_compilers/cfndsl.rb +13 -0
  65. data/lib/stack_master/template_compilers/json.rb +22 -0
  66. data/lib/stack_master/template_compilers/sparkle_formation.rb +71 -0
  67. data/lib/stack_master/template_compilers/yaml.rb +14 -0
  68. data/lib/stack_master/template_utils.rb +31 -0
  69. data/lib/stack_master/test_driver/cloud_formation.rb +193 -0
  70. data/lib/stack_master/test_driver/s3.rb +34 -0
  71. data/lib/stack_master/testing.rb +9 -0
  72. data/lib/stack_master/utils.rb +50 -0
  73. data/lib/stack_master/validator.rb +33 -0
  74. data/lib/stack_master/version.rb +3 -0
  75. metadata +457 -0
@@ -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
@@ -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