{"id":13879249,"url":"https://github.com/kickstarter/cfn-flow","last_synced_at":"2025-04-05T21:07:40.813Z","repository":{"id":26417761,"uuid":"29867985","full_name":"kickstarter/cfn-flow","owner":"kickstarter","description":"A practical workflow for AWS CloudFormation","archived":false,"fork":false,"pushed_at":"2020-04-22T03:50:03.000Z","size":127,"stargazers_count":168,"open_issues_count":9,"forks_count":13,"subscribers_count":123,"default_branch":"master","last_synced_at":"2025-03-29T20:05:10.618Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kickstarter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-26T15:46:56.000Z","updated_at":"2024-08-28T03:22:07.000Z","dependencies_parsed_at":"2022-08-29T05:54:07.808Z","dependency_job_id":null,"html_url":"https://github.com/kickstarter/cfn-flow","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kickstarter%2Fcfn-flow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kickstarter%2Fcfn-flow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kickstarter%2Fcfn-flow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kickstarter%2Fcfn-flow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kickstarter","download_url":"https://codeload.github.com/kickstarter/cfn-flow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399877,"owners_count":20932876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T08:02:15.155Z","updated_at":"2025-04-05T21:07:40.795Z","avatar_url":"https://github.com/kickstarter.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# cfn-flow\n`cfn-flow` is a command-line tool for developing [AWS CloudFormation](https://aws.amazon.com/cloudformation/) templates and deploying stacks.\n\nIt provides a *simple*, *standard*, and *flexible* process for using CloudFormation, ideal for DevOps-style organizations.\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n## Table of Contents\n\n- [Opinions](#opinions)\n- [Installation](#installation)\n- [Key concepts](#key-concepts)\n    - [Services](#services)\n    - [Environments](#environments)\n    - [Deploying](#deploying)\n    - [AWS credentials](#aws-credentials)\n- [Configuration](#configuration)\n- [UX improvements](#ux-improvements)\n    - [YAML \u003e JSON](#yaml--json)\n    - [Embedded ruby in `cfn-flow.yml`](#embedded-ruby-in-cfn-flowyml)\n- [Usage](#usage)\n  - [Working with stacks](#working-with-stacks)\n    - [Deploy (launch) a stack](#deploy-launch-a-stack)\n    - [List stacks for your service or environment](#list-stacks-for-your-service-or-environment)\n    - [Inspect a stack](#inspect-a-stack)\n    - [Show stack events](#show-stack-events)\n    - [Delete a stack](#delete-a-stack)\n  - [Common workflows](#common-workflows)\n    - [Deploying to production](#deploying-to-production)\n  - [Launching a development environment](#launching-a-development-environment)\n  - [Working with templates](#working-with-templates)\n    - [Validate templates](#validate-templates)\n    - [Publish templates to S3](#publish-templates-to-s3)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Opinions\n\n`cfn-flow` introduces a consistent, convenient workflow that encourages good template organization\nand deploy practices.\n\n1. *Optimize for happiness.* The workflow should be easy \u0026 enjoyable to use.\n2. *Optimize for onboarding.* The workflow should be simple to learn, understand, \u0026 debug.\n3. *Auditable changes.* Know who changed what when \u0026 why. Leverage git history.\n4. *Immutable releases.* The code in a release never changes. To make a change,\n   launch a new stack.\n\nThe features \u0026 implementation of `cfn-flow` itself must also be simple. This follows the Unix philosophy of \"[worse is\nbetter](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.\n\nSee [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`.\n\n## Installation\n\nVia [rubygems](https://rubygems.org/gems/cfn-flow):\n```\ngem install cfn-flow\n```\n\nThe `git` command is also needed.\n\n## Key concepts\n\n`cfn-flow` works from a directory containing a `cfn-flow.yml` config file, and a CloudFormation template.\nPresumably your app code is in the same directory, but it doesn't have to be.\n\nThere are two key concepts for `cfn-flow`: **services** and **environments**.\n\n#### Services\n\nA service comprises a set of resources that change together.\nEach service has its own `cfn-flow.yml` config file. A service\ncan be instantiated as several distinct environments.\n\nFor example, a `WebApp` service could have a CloudFormation template that\ncreates an ELB, LaunchConfig, and AutoScalingGroup resources.\n\nAll the resources in a service change together. Deploying the `WebApp`\nservice to an environment will create a new ELB, LaunchConfig, and AutoScalingGroup.\n\nResources that *do not* change across deploys are not part of the service (from\n`cfn-flow`'s perspective).\nSay all `WebApp` EC2 servers connect to a long-running RDS database. That\ndatabase is not part of the cfn-flow service because it is re-used across\ndeploys. The database is a *backing resource* the service uses; not part\nof the service itself.\n\n#### Environments\n\nAn environment is an particular instantiation of a service. For example, you\ncould deploy your `WebApp` service to both a `development` and `production` environment.\n\n`cfn-flow` is designed to support arbitrary environments like git supports\narbitrary branches.\n\n**Pro tip:** Use the `CFN_FLOW_ENVIRONMENT` environment variable in\n`cfn-flow.yml` config to use the environment in your template parameters.\nSee [Configuration](#configuration) for examples.\n\n#### Deploying\n\nDeployments consist of launching a *new stack* in a particular environment, then\nshutting down the old stack. For example:\n\n```\ncfn-flow deploy ENVIRONMENT --cleanup\n```\n\nThis follows the [red/black](http://techblog.netflix.com/2013/08/deploying-netflix-api.html)\nor [blue/green](http://martinfowler.com/bliki/BlueGreenDeployment.html)\ndeployment pattern.\n\nAfter verifying the new stack is working correctly, the deployer is expected to\ndelete the old stack.\n\nTo roll back a bad deploy, simply delete the *new* stack, while the *old*\nstack is running.\n\nAlthough CloudFormation supports updating existing stacks, `cfn-flow` prefers\nlaunching immutable stacks. Stack updates are more difficult to test than new stacks; and there's less chance of a deployment error disrupting or breaking important resources.\n\n#### AWS credentials\n\nSet your AWS credentials so they can be found by the AWS SDK for Ruby ([details here](http://docs.aws.amazon.com/AWSSdkDocsRuby/latest/DeveloperGuide/set-up-creds.html)), e.g. using the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables.\n\n## Configuration\n\n`cfn-flow` looks for `./cfn-flow.yml` for stack and template configuration.\nYou can override this path by setting the `CFN_FLOW_CONFIG_PATH` environment\nvariable to another path.\n\nHere's a minimal `cfn-flow.yml` config file:\n\n```yaml\n# Required service name\nservice: MyService\n\n# Minimal configuration for launching the stack.\nstack:\n  # Stack name uses embedded ruby to support dynamic values\n  stack_name: MyService-\u003c%= Time.now.to_i %\u003e\n  # Required: *either* template_url or template_body\n  # NB: template_body is a local path to the template\n  template_body: path/to/template.json\n  # Alternatively:\n  # template_url: https://MyS3Bucket.s3.amazonaws.com/MyPrefix/release/abc123/template.json\n```\n\nAnd here's a maximal config file:\n\n```yaml\n# Example cfn-flow.yml\n\nservice: MyService\n\n# Set the AWS region here to override or avoid setting the AWS_REGION env var\nregion: us-east-1\n\n##\n# Templates\n#\n# These define where templates will get published.\n#   $ cfn-flow publish --release my-cfn-template.json\n#   Published url: https://MyS3Bucket.s3.amazonaws.com/My/S3/Prefix/\u003cgit sha\u003e/my-cfn-template.json\ntemplates:\n  bucket: MyS3Bucket\n  s3_prefix: 'My/S3/Prefix'\n\n##\n# Stacks\n#\n# These are the arguments passed when launching a new stack.\n# It's nearly identical to the create_stack args in the ruby sdk, except\n# parameters and tags are hashes. See http://amzn.to/1M0nBuq\n\nstack:\n  # Use the CFN_FLOW_ENVIRONMENT var \u0026 git sha in stack name\n  stack_name: MyService-\u003c%= ENV['CFN_FLOW_ENVIRONMENT'] %\u003e-\u003c%= `git rev-parse --short HEAD`.chomp %\u003e\n    # NB: template_body is a local path to the template\n    template_body: path/to/template.yml\n    template_url: http://...\n    parameters:\n      # Your parameters, e.g.:\n      vpcid: vpc-1234\n      ami: ami-abcd\n\n      ##\n      # Use outputs from other stacks\n\n      # This set the `load_balancer` parameter to the value of the\n      # `elbname` output of `my-elb-stack`\n      load_balancer:\n        stack: my-elb-stack\n        output: elbname\n\n      # If you don't specify the output name, it's assumed to be same\n      # as the parameter key:\n      ssh_security_group:\n        stack: my-bastion-stack\n\n    disable_rollback: true,\n    timeout_in_minutes: 1,\n    notification_arns: [\"NotificationARN\"],\n    capabilities: [\"CAPABILITY_IAM\"], # This stack does IAM stuff\n    on_failure: \"DO_NOTHING\", # either DO_NOTHING, ROLLBACK, DELETE\n    stack_policy_body: \"StackPolicyBody\",\n    stack_policy_url: \"StackPolicyURL\",\n    tags:\n      # Whatever you want.\n      # Note that `cfn-flow` automatically adds two tags: `CfnFlowService` and `CfnFlowEnvironment`\n      TagKey: TagValue\n      # Who launched this stack\n      Deployer: \u003c%= ENV['USER'] %\u003e\n      # Tag production and development environments for accounting\n      BillingType: \u003c%= ENV['CFN_FLOW_ENVIRONMENT'] == 'production' ?  'production' : 'development' %\u003e\n```\n\n## UX improvements\n\n`cfn-flow` includes a few developer-friendly features:\n\n#### YAML \u003e JSON\n\n`cfn-flow` lets you write templates in either JSON or\n[YAML](http://www.yaml.org). YAML is a superset of JSON that allows a terser,\nless cluttered syntax, inline comments, and code re-use with anchors (like\nvariables). YAML templates are transparently converted to JSON when uploaded to\nS3 for use in CloudFormation stacks.\n\nNote that you can use JSON snippets inside YAML templates. JSON is always valid\nYAML.\n\n#### Embedded ruby in `cfn-flow.yml`\n\nTo allow dynamic/programmatic attributes, use\n[ERB](https://en.wikipedia.org/wiki/ERuby) in `cfn-flow.yml`. For example:\n\n```yaml\nstack:\n  name: my-stack-\u003c%= Time.now.to_i %\u003e\n  ...\n  parameters:\n    git_sha: \u003c%= `git rev-parse --verify HEAD`.chomp %\u003e\n```\n\n#### Use stack outputs as parameters\n`cfn-flow` lets you easily reference stack outputs as parameters for new stacks.\n\n```yaml\n# cfn-flow.yml\nstack:\n  parameters:\n    # Set my-param to the `my-param` output of `another-stack`\n    my-param:\n      stack: another-stack\n\n    # Set my-param to the `my-output` output of `another-stack`\n    my-param:\n      stack: another-stack\n      output: my-output\n```\n\n## Usage\n\nGetting help:\n\n```\n# Get help\ncfn-flow help\n\ncfn-flow help COMMAND\n# E.g.:\ncfn-flow help deploy\n```\n\nLaunch a CloudFormation stack:\n```\ncfn-flow deploy production\n```\n\n### Working with stacks\n\n`cfn-flow` automatically sets two tags on any stack it launches:\n\nName | Example value\n--- | ---\nCfnFlowService | `myapp`\nCfnFlowEnvironment | `production`\n\nThese tags let `cfn-flow` associate stacks back to services \u0026 environments.\n\n#### Deploy (launch) a stack\n\n```\ncfn-flow deploy ENVIRONMENT\n```\n\nLaunches a stack in ENVIRONMENT. E.g. `cfn-flow deploy production`\n\nAdd the `--cleanup` option to be prompted to shut down other stacks in the environment.\n\n#### List stacks for your service or environment\n\n```\ncfn-flow list [ENVIRONMENT]\n```\n\nShow all stacks running in your service, or just in an ENVIRONMENT.\n\n```\n# For example:\n$ cfn-flow list production\n\nmyapp-production-aaa (CREATE_COMPLETE)\nmyapp-production-bbb (CREATE_FAILED)\n```\n\n#### Inspect a stack\n\n```\ncfn-flow show STACK\n```\n\nShow the status of STACK.\n\n#### Show stack events\n\n```\ncfn-flow events STACK\n```\n\nList events for STACK\n\nUse the `--poll` option to poll for new events until the stack status is no\nlonger `*_IN_PROGRESS`\n\n#### Delete a stack\n\n```\ncfn-flow delete STACK\n```\n\nDeletes a stack.\n\n```\n# For example:\n$ cfn-flow delete myapp-production-aaa\n```\n\n### Common workflows\n\n#### Deploying to production\n\n```\n# Launch a new stack for the current git commit\n$ cfn-flow deploy production\nLaunching stack myapp-production-abc123\n# ... wait for it to be ready\n\n# See the other stacks\n$ cfn-deploy list production\n\nmyapp-production-abc123 CREATE_COMPLETE\nmyapp-production-xyz987 CREATE_COMPLETE\n\n# Shut down the old stack\n$ cfn-flow delete myapp-production-xyz987\n```\n\n### Launching a development environment\n\nLaunch a new stack for `myenv` environment\n\n```\ncfn-flow deploy myenv\n```\n\n### Working with templates\n\n#### Validate templates\n\n```\ncfn-flow validate TEMPLATE [...]\n```\n\nValidates CloudFormation templates; does not persist to S3.\n\n```\n# For example:\n$ cfn-flow validate path/to/template.yml\n```\n\n#### Publish templates to S3\n\n```\ncfn-flow publish TEMPLATE [...]\n```\n\nPublish templates to S3 with immutable release names, or overwrite \"dev names\"\nfor quicker testing.\n\n**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),\n (that is, stacks that include other stacks).\n\n```\n# For example:\n$ cfn-flow publish path/to/template.yml\n# validates \u0026 uploads templates to dev path\n# Env var CFN_FLOW_DEV_NAME=aaron\n# E.g. https://mybucket.s3.amazonaws.com/myprefix/dev/aaron/mytemplate.yml\n\n$ cfn-flow upload --release\n# validates \u0026 uploads templates for current git sha\n# E.g. https://mybucket.s3.amazonaws.com/myprefix/deadbeef/mytemplate.yml\n\n$ cfn-flow upload --release=v1.0.0\n# Upload templates for an arbitrary release name\n# E.g. https://mybucket.s3.amazonaws.com/myprefix/v1.0.0/mytemplate.yml\n```\n\n## License\n\nCopyright Kickstarter, Inc.\n\nReleased under an [MIT License](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkickstarter%2Fcfn-flow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkickstarter%2Fcfn-flow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkickstarter%2Fcfn-flow/lists"}