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