README.md in cfn-flow-0.8.0 vs README.md in cfn-flow-0.9.0

- old
+ new

@@ -1,60 +1,78 @@ # cfn-flow -`cfn-flow` is an command-line tool for developing [AWS CloudFormation](https://aws.amazon.com/cloudformation/) templates and deploying stacks. +`cfn-flow` is a command-line tool for developing [AWS CloudFormation](https://aws.amazon.com/cloudformation/) templates and deploying stacks. It provides a *simple*, *standard*, and *flexible* process for using CloudFormation, ideal for DevOps-style organizations. -#### Opinions +<!-- START doctoc generated TOC please keep comment here to allow auto update --> +<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> +## Table of Contents +- [Opinions](#opinions) +- [Installation](#installation) +- [Key concepts](#key-concepts) + - [Services](#services) + - [Environments](#environments) + - [Deploying](#deploying) + - [AWS credentials](#aws-credentials) +- [Configuration](#configuration) +- [UX improvements](#ux-improvements) + - [YAML > JSON](#yaml--json) + - [Embedded ruby in `cfn-flow.yml`](#embedded-ruby-in-cfn-flowyml) +- [Usage](#usage) + - [Working with stacks](#working-with-stacks) + - [Deploy (launch) a stack](#deploy-launch-a-stack) + - [List stacks for your service or environment](#list-stacks-for-your-service-or-environment) + - [Inspect a stack](#inspect-a-stack) + - [Show stack events](#show-stack-events) + - [Delete a stack](#delete-a-stack) + - [Common workflows](#common-workflows) + - [Deploying to production](#deploying-to-production) + - [Launching a development environment](#launching-a-development-environment) + - [Working with templates](#working-with-templates) + - [Validate templates](#validate-templates) + - [Publish templates to S3](#publish-templates-to-s3) +- [License](#license) + +<!-- END doctoc generated TOC please keep comment here to allow auto update --> + +## Opinions + `cfn-flow` introduces a consist, convenient workflow that encourages good template organization and deploy practices. -1. *Optimize for happiness.* The workflow should be easy and enjoyable to use. -2. *Optimize for onboarding.* The workflow should be simple to learn & understand. -3. *Auditable changes.* Know who changed what when. Leverage git history. +1. *Optimize for happiness.* The workflow should be easy & enjoyable to use. +2. *Optimize for onboarding.* The workflow should be simple to learn, understand, & debug. +3. *Auditable changes.* Know who changed what when & why. Leverage git history. 4. *Immutable releases.* The code in a release never changes. To make a change, launch a new stack. The features & implementation of `cfn-flow` itself must also be simple. This follows the Unix philosophy of "[worse is better](http://www.jwz.org/doc/worse-is-better.html)". `cfn-flow` values a simple design and implementation, and being composable with other workflows over handling every edge case out of the box. +See [this introductory blog post](https://www.kickstarter.com/backing-and-hacking/introducing-cfn-flow-a-practical-workflow-for-aws-cloudformation) for our motivation behind `cfn-flow`. + ## Installation Via [rubygems](https://rubygems.org/gems/cfn-flow): ``` gem install cfn-flow ``` The `git` command is also needed. -## Usage +## Key concepts -``` -# Get help -cfn-flow help - -cfn-flow help COMMAND -# E.g.: -cfn-flow help deploy -``` - -Launch a CloudFormation stack: -``` -cfn-flow deploy production -``` - -## How it works - `cfn-flow` works from a directory containing a `cfn-flow.yml` config file, and a CloudFormation template. Presumably your app code is in the same directory, but it doesn't have to be. There are two key concepts for `cfn-flow`: **services** and **environments**. #### Services -A service is a name for your project and comprises a set of resources that -change together. Each service has it's own `cfn-flow.yml` config file. A service +A service comprises a set of resources that change together. +Each service has its own `cfn-flow.yml` config file. A service can be instantiated as several distinct environments. For example, a `WebApp` service could have a CloudFormation template that creates an ELB, LaunchConfig, and AutoScalingGroup resources. @@ -62,11 +80,11 @@ service to an environment will create a new ELB, LaunchConfig, and AutoScalingGroup. Resources that *do not* change across deploys are not part of the service (from `cfn-flow`'s perspective). Say all `WebApp` EC2 servers connect to a long-running RDS database. That -database is not part of the cfn-flow service because it should re-used across +database is not part of the cfn-flow service because it is re-used across deploys. The database is a *backing resource* the service uses; not part of the service itself. #### Environments @@ -74,12 +92,13 @@ could deploy your `WebApp` service to both a `development` and `production` environment. `cfn-flow` is designed to support arbitrary environments like git supports arbitrary branches. -Then `CFN_FLOW_ENVIRONMENT` environment variable can be used in -`cfn-flow.yml` to use the environment in your template parameters. +**Pro tip:** Use the `CFN_FLOW_ENVIRONMENT` environment variable in +`cfn-flow.yml` config to use the environment in your template parameters. +See [Configuration](#configuration) for examples. #### Deploying Deployments consist of launching a *new stack* in a particular environment, then shutting down the old stack. For example: @@ -129,11 +148,10 @@ ``` And here's a maximal config file: ```yaml ---- # Example cfn-flow.yml service: MyService # Set the AWS region here to override or avoid setting the AWS_REGION env var @@ -155,18 +173,34 @@ # These are the arguments passed when launching a new stack. # It's nearly identical to the create_stack args in the ruby sdk, except # parameters and tags are hashes. See http://amzn.to/1M0nBuq stack: - stack_name: MyService-<%= Time.now.to_i %> + # Use the CFN_FLOW_ENVIRONMENT var & git sha in stack name + stack_name: MyService-<%= ENV['CFN_FLOW_ENVIRONMENT'] %>-<%= `git rev-parse --short HEAD`.chomp %> # NB: template_body is a local path to the template template_body: path/to/template.yml template_url: http://... parameters: # Your parameters, e.g.: vpcid: vpc-1234 ami: ami-abcd + + ## + # Use outputs from other stacks + + # This set the `load_balancer` parameter to the value of the + # `elbname` output of `my-elb-stack` + load_balancer: + stack: my-elb-stack + output: elbname + + # If you don't specify the output name, it's assumed to be same + # as the parameter key: + ssh_security_group: + stack: my-bastion-stack + disable_rollback: true, timeout_in_minutes: 1, notification_arns: ["NotificationARN"], capabilities: ["CAPABILITY_IAM"], # This stack does IAM stuff on_failure: "DO_NOTHING", # either DO_NOTHING, ROLLBACK, DELETE @@ -180,11 +214,11 @@ Deployer: <%= ENV['USER'] %> # Tag production and development environments for accounting BillingType: <%= ENV['CFN_FLOW_ENVIRONMENT'] == 'production' ? 'production' : 'development' %> ``` -### UX improvements: +## UX improvements `cfn-flow` includes a few developer-friendly features: #### YAML > JSON @@ -197,23 +231,56 @@ Note that you can use JSON snippets inside YAML templates. JSON is always valid YAML. #### Embedded ruby in `cfn-flow.yml` -To allow dynamic/programatic attributes, use +To allow dynamic/programmatic attributes, use [ERB](https://en.wikipedia.org/wiki/ERuby) in `cfn-flow.yml`. For example: ```yaml stack: name: my-stack-<%= Time.now.to_i %> ... parameters: git_sha: <%= `git rev-parse --verify HEAD`.chomp %> ``` +#### Use stack outputs as parameters +`cfn-flow` lets you easily reference stack outputs as parameters for new stacks. + +```yaml +# cfn-flow.yml +stack: + parameters: + # Set my-param to the `my-param` output of `another-stack` + my-param: + stack: another-stack + + # Set my-param to the `my-output` output of `another-stack` + my-param: + stack: another-stack + output: my-output +``` + ## Usage +Getting help: + +``` +# Get help +cfn-flow help + +cfn-flow help COMMAND +# E.g.: +cfn-flow help deploy +``` + +Launch a CloudFormation stack: +``` +cfn-flow deploy production +``` + ### Working with stacks `cfn-flow` automatically sets two tags on any stack it launches: Name | Example value @@ -221,46 +288,68 @@ CfnFlowService | `myapp` CfnFlowEnvironment | `production` These tags let `cfn-flow` associate stacks back to services & environments. -#### `cfn-flow deploy ENVIRONMENT` +#### Deploy (launch) a stack +``` +cfn-flow deploy ENVIRONMENT +``` + Launches a stack in ENVIRONMENT. E.g. `cfn-flow deploy production` Add the `--cleanup` option to be prompted to shut down other stacks in the environment. -#### `cfn-flow list ENVIRONMENT` +#### List stacks for your service or environment -Show running stacks for ENVIRONMENT. +``` +cfn-flow list [ENVIRONMENT] +``` +Show all stacks running in your service, or just in an ENVIRONMENT. + ``` +# For example: $ cfn-flow list production myapp-production-aaa (CREATE_COMPLETE) myapp-production-bbb (CREATE_FAILED) ``` -#### `cfn-flow delete STACK` +#### Inspect a stack -Deletes a stack. - ``` -$ cfn-flow delete myapp-production-aaa +cfn-flow show STACK ``` -#### `cfn-flow show STACK` - Show the status of STACK. -#### `cfn-flow events STACK` +#### Show stack events +``` +cfn-flow events STACK +``` + List events for STACK -Use the `--tail` option to poll for new events until the stack status is no +Use the `--poll` option to poll for new events until the stack status is no longer `*_IN_PROGRESS` +#### Delete a stack + +``` +cfn-flow delete STACK +``` + +Deletes a stack. + +``` +# For example: +$ cfn-flow delete myapp-production-aaa +``` + ### Common workflows #### Deploying to production ``` @@ -287,25 +376,36 @@ cfn-flow deploy myenv ``` ### Working with templates -#### `cfn-flow validate` +#### Validate templates ``` -# Runs validate-template on all templates. -# returns an error on any failure. -# does not persist to S3 +cfn-flow validate TEMPLATE [...] +``` +Validates CloudFormation templates; does not persist to S3. + +``` +# For example: $ cfn-flow validate path/to/template.yml ``` -#### `cfn-flow publish` +#### Publish templates to S3 +``` +cfn-flow publish TEMPLATE [...] +``` + Publish templates to S3 with immutable release names, or overwrite "dev names" -for quicker testing. *This is only needed if you want to use nested stack resources.* +for quicker testing. +**Note:** Publishing to S3 is only needed if you want to use [nested stack resources](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html), + (that is, stacks that lainclude other stacks). + ``` +# For example: $ cfn-flow publish path/to/template.yml # validates & uploads templates to dev path # Env var CFN_FLOW_DEV_NAME=aaron # E.g. https://mybucket.s3.amazonaws.com/myprefix/dev/aaron/mytemplate.yml