stack_master 1.6.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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