README.md in kumo_keisei-3.0.4 vs README.md in kumo_keisei-3.0.5.pre.alpha1
- old
+ new
@@ -20,16 +20,172 @@
$ gem install kumo_keisei
## Usage
+### Basic Usage
+
+The basic usage will give you a CloudFormation stack named `{application}-{type}-{environment}`. The default type is `nodes`
+
```ruby
-stack_name = "my_awesome_stack"
-template = "./cloudformation/environment_template.json"
-template_params = "./cloudformation/environments/production/params.json"
+application_name = "myapp"
+environment_name = "production"
+my_stack = KumoKeisei::Stack.new(stack_name, environment_name)
-KumoKeisei::CloudFormationStack.new(stack_name, template, template_params).apply!
+stack_config = {
+ config_path: File.join('/app', 'env', 'config'),
+ template_path: File.join('/app', 'env', 'cloudformation', 'myapp.json'),
+}
+
+my_stack.apply! stack_config
```
+
+### Changing the stack type
+
+Specify the `type` in an options object passed to the `KumoKeisei::Stack` constructor. For example the following will give you a `myapp-vpc-production` stack e.g:
+```ruby
+vpc_stack_options = {
+ type: 'vpc'
+}
+vpc_stack = KumoKeisei::Stack.new('myapp', 'production', vpc_stack_options)
+```
+
+### Timeouts
+
+You can tune each of the timeouts by passing options to the Stack constructor:
+```ruby
+stack_options = {
+ confirmation_timeout: 0.5,
+ waiter_delay: 20,
+ waiter_attempts: 90,
+}
+
+KumoKeisei::Stack.new(stack_name, environment_name, stack_options)
+```
+
+*confirmation_timeout*: how long to wait for a user to confirm delete actions
+*waiter_delay*: how long to wait between checking Cfn for completion of delete and update actions
+*waiter_attempts*: how many times to retry checking that a Cfn delete or update was successful
+
+### CloudFormation Templates, Parameter Templates and Configuration Files
+
+The **CloudFormation Template** is a json file (e.g. app.json) describing a related set of Amazon resources using the [CloudFormation DSL](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/gettingstarted.templatebasics.html). You pass the location by specifying the `template_path` in the object passed to `apply!`,
+
+The **Parameter Template** is a file prescribing the Cfn parameters [Embedded Ruby](http://www.stuartellis.eu/articles/erb/) form. It must be in the same folder holding the CloudFormation Template, named `{app_name}.yml.erb`.
+
+The **Configuration Files** are a set of files in `yml` format prescribing configuration values for a given environment. They must be in the folder given by `config_path`, in the form of `{environment}.yml` and `{environment}_secrets.yml`
+
+[KumoKi](https://github.com/redbubble/kumo_ki_gem) will be used to decrypt the _secrets_ files.
+
+### Configuration Hierarchy
+
+Configuration will be loaded from the following sources:
+
+1. `common.yml` and `common_secrets.yml` if they exist.
+2. `{environment}.yml` and `{environment}_secrets.yml` or `development.yml` and `development_secrets.yml` if environment specific config does not exist.
+
+### Injecting Configuration
+
+You can also inject configuration at run time by adding it to the object provided to the `apply!` call:
+
+```ruby
+stack_config = {
+ config_path: File.join('/app', 'env', 'config'),
+ template_path: File.join('/app', 'env', 'cloudformation', 'myapp.json'),
+ injected_config: {
+ 'Seed' => random_seed,
+ }
+}
+stack.apply!(stack_config)
+```
+
+### Getting the configuration without an `apply!`
+
+If you need to inspect the configuration without applying a stack, call `config`:
+```ruby
+stack_config = {
+ config_path: File.join('/app', 'env', 'config'),
+ template_path: File.join('/app', 'env', 'cloudformation', 'myapp.json'),
+ injected_config: {
+ 'Seed' => random_seed,
+ }
+}
+marshalled_config = stack.config(stack_config)
+if marshalled_config('DB_HOST').start_with? '192.' then
+ ...
+```
+
+## Upgrading from `KumoKeisei::CloudFormationStack` to `KumoKeisei::Stack`
+
+`KumoKeisei::CloudFormationStack` is deprecated and should be replaced with a `KumoKeisei::Stack` which encompasses an environment object (`KumoKeisei::EnvironmentConfig`).
+
+Previously you would have to construct your own `EnvironmentConfig` which would marshal it's configuration, then instantiate a `CloudFormationStack` and conduct operations on it.
+
+E.g. `apply-env`:
+```ruby
+require_relative '../env/cloudformation_stack'
+
+environment_name = ARGV.fetch(0) rescue raise("Error! No environment name given!")
+
+stack = CloudFormationStack.new(environment_name)
+stack.apply
+```
+and `environment_config.rb`:
+```ruby
+require 'kumo_keisei'
+
+class CloudFormationStack
+
+ APP_NAME = "fooapp"
+
+ attr_reader :env_name
+
+ def initialize(env_name)
+ @stacks = {}
+ @env_name = env_name
+ end
+
+ def env_vars
+ {}
+ end
+
+ def apply
+ # Inject the VPC and Subnets into the application's environment config
+ foo_config = KumoKeisei::EnvironmentConfig.new(
+ env_name: env_name,
+ config_dir_path: File.expand_path(File.join("..", "..", "env", "config"), __FILE__)
+ )
+
+ foo_stack = create_stack(:foo, foo_config)
+ foo_stack.apply!
+ end
+ ...
+ def create_stack(stack_name, environment_config)
+ raise "Stack '#{ stack_name }' already exists!" if @stacks[stack_name]
+ params_template_erb = params_template(stack_name)
+ stack_values = cf_params_json(get_stack_params(params_template_erb, environment_config))
+ write_stack_params_file(stack_values, stack_name)
+ @stacks[stack_name] = KumoKeisei::CloudFormationStack.new(stack_names[stack_name], "./env/cloudformation/#{stack_name}.json", stack_file_params_file_path(stack_name))
+ end
+ ...
+```
+
+With the new `Stack` object, all you need to do is pass in the location of the template and config as in the above section. New `apply-env`:
+```ruby
+require 'kumo_keisei'
+
+environment_name = ARGV.fetch(0) rescue raise("Error! No environment name given!")
+
+stack_config = {
+ config_path: File.join('/app', 'env', 'config'),
+ template_path: File.join('/app', 'env', 'cloudformation', 'fooapp.json'),
+}
+
+stack = KumoKeisei::Stack.new('fooapp', environment_name)
+stack.apply!(stack_config)
+```
+
+
## Dependencies
#### Ruby Versions