cfn-flow 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +133 -0
- data/Rakefile +18 -0
- data/bin/cfn-flow +3 -0
- data/lib/cfn-flow/template.rb +59 -0
- data/lib/cfn-flow/version.rb +3 -0
- data/lib/cfn-flow.rb +143 -0
- data/spec/sqs.template +66 -0
- data/spec/sqs.yml +62 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9b11eb9cc9a03afce395768b4e29f5b59764646f
|
4
|
+
data.tar.gz: 18fa02cf2b9834e8ab4c870d23ecb548dfd7a064
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 81a7ce12e778b4b5beb6fd566143900ec6a9803b19f56a9b4b4700dd65d4128a792ec9f48be6a3741c329f24ad5a7c3023a2288c4a80014c836a86348910266a
|
7
|
+
data.tar.gz: 01491f61b53acc8ece495146a7e8b9864f96dd897ec7fc4465ce97910d773ba88fd04da9952abd9db7a1314eeb3630ae533276b465b0b67866354163166b9365
|
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# cfn-flow
|
2
|
+
An opinionated command-line workflow for developing AWS CloudFormation templates. Track template changes in git and upload versioned releases to AWS S3.
|
3
|
+
|
4
|
+
#### Opinions
|
5
|
+
|
6
|
+
1. *Optimize for onboarding.* The workflow should be simple to learn & understand.
|
7
|
+
2. *Optimize for happiness.* The workflow should be easy and enjoyable to use.
|
8
|
+
3. *Auditable history.* Know who changed what when. Leverage git for auditing.
|
9
|
+
4. *Immutable releases.* The code in a release never changes.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Via [rubygems](https://rubygems.org/gems/cfn-flow):
|
14
|
+
```
|
15
|
+
gem install cfn-flow
|
16
|
+
```
|
17
|
+
|
18
|
+
The `git` command is also needed.
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Poke around:
|
23
|
+
```
|
24
|
+
cfn-flow help
|
25
|
+
```
|
26
|
+
|
27
|
+
#### Dev mode (default)
|
28
|
+
|
29
|
+
Dev mode allows you to quickly test template changes.
|
30
|
+
`cfn-flow` validates all templates and uploads them to your personal prefix, overwriting existing templates.
|
31
|
+
|
32
|
+
Dev mode does not verify that your local changes are
|
33
|
+
committed to git (as opposed to release mode).
|
34
|
+
|
35
|
+
You should use dev mode for testing & verifying changes in non-production stacks.
|
36
|
+
|
37
|
+
```
|
38
|
+
# Set a personal name to prefix your templates.
|
39
|
+
export CFN_FLOW_DEV_NAME=aaron
|
40
|
+
|
41
|
+
# Validate and upload all CloudFormation templates in your working directory to
|
42
|
+
s3://my-bucket/dev/aaron/*
|
43
|
+
# NB that this overwrites existing templates in your CFN_FLOW_DEV_NAME
|
44
|
+
namespace.
|
45
|
+
|
46
|
+
cfn-init
|
47
|
+
```
|
48
|
+
|
49
|
+
You can launch or update test stacks using your dev template path to quickly test your
|
50
|
+
template changes.
|
51
|
+
|
52
|
+
#### Release mode
|
53
|
+
|
54
|
+
Release mode publishes your templates to a versioned S3 path, and pushes a git
|
55
|
+
tag of the version.
|
56
|
+
|
57
|
+
```
|
58
|
+
# uploads templates to `s3://my-bucket/release/1.0.0/*` and pushes a 1.0.0 git
|
59
|
+
tag
|
60
|
+
cfn-flow --release 1.0.0
|
61
|
+
```
|
62
|
+
|
63
|
+
Release mode ensures there are no uncommitted changes in your git working
|
64
|
+
directory, and pushes a `1.0.0` git tag.
|
65
|
+
|
66
|
+
Inspecting the differences between releases is possible using `git log` and `git
|
67
|
+
diff`.
|
68
|
+
|
69
|
+
## Configuration
|
70
|
+
|
71
|
+
You can configure cfn-flow defaults by creating a `cfn-flow.yml` file in same
|
72
|
+
directory you run `cfn-flow` (presumably the root of your project).
|
73
|
+
|
74
|
+
Settings in the configuration file are overridden by environment variables. And
|
75
|
+
environment variables are overridden by command line arguments.
|
76
|
+
|
77
|
+
```
|
78
|
+
# cfn-flow.yml in the root of your project
|
79
|
+
# All options in this config can be overridden with command line arguments
|
80
|
+
---
|
81
|
+
# S3 bucket where templates are uploaded. No default.
|
82
|
+
# Override with CFN_FLOW_BUCKET
|
83
|
+
bucket: 'my-s3-bucket'
|
84
|
+
|
85
|
+
# S3 path prefix. Default: none
|
86
|
+
# Override with CFN_FLOW_TO
|
87
|
+
to: my/project/prefix
|
88
|
+
|
89
|
+
# Local path in which to recursively search for templates. Default: .
|
90
|
+
# Override with CFN_FLOW_FROM
|
91
|
+
from: my/local/prefix
|
92
|
+
|
93
|
+
# AWS Region
|
94
|
+
# Override with AWS_REGION
|
95
|
+
region: us-east-1 # AWS region
|
96
|
+
```
|
97
|
+
|
98
|
+
#### AWS credentials
|
99
|
+
|
100
|
+
AWS credentials can only be set using the
|
101
|
+
`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables; or by
|
102
|
+
using an EC2 instance's IAM role.
|
103
|
+
|
104
|
+
|
105
|
+
## Sweet Features
|
106
|
+
|
107
|
+
#### YAML > JSON
|
108
|
+
|
109
|
+
`cfn-flow` lets you write templates in either JSON or
|
110
|
+
[YAML](http://www.yaml.org). YAML is a superset of JSON that allows a terser,
|
111
|
+
less cluttered syntax, inline comments, and code re-use with variables. YAML
|
112
|
+
templates are transparently converted to JSON when uploaded to S3 for use in
|
113
|
+
CloudFormation stacks.
|
114
|
+
|
115
|
+
#### Use versions in nested stack template URLs
|
116
|
+
|
117
|
+
`cfn-flow` works great with [nested stack
|
118
|
+
resources](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html). Use [Fn::Join](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-join.html) to construct the `TemplateURL` from a parameter:
|
119
|
+
|
120
|
+
```
|
121
|
+
{
|
122
|
+
"Type" : "AWS::CloudFormation::Stack",
|
123
|
+
"Properties" : {
|
124
|
+
"TemplateURL" : {
|
125
|
+
"Fn::Join" : [ ":",r
|
126
|
+
[ "https://s3.amazonaws.com/my-bucket", {"Ref": "prefix"}, "my-template.json" ]
|
127
|
+
]
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
```
|
132
|
+
|
133
|
+
While testing, set the `prefix` parameter to dev prefix like `dev/aaron`. When you're confident your changes work, release them with cfn-flow and change the `prefix` parameter to `release/1.0.0` for production.
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
namespace :test do
|
6
|
+
Rake::TestTask.new(:units) do |t|
|
7
|
+
t.pattern = "spec/*_spec.rb"
|
8
|
+
end
|
9
|
+
|
10
|
+
Rake::TestTask.new(:integration) do |t|
|
11
|
+
t.pattern = "spec/integration/*_spec.rb"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Run tests'
|
16
|
+
task :test => %w[test:units test:integration]
|
17
|
+
|
18
|
+
task :default => :test
|
data/bin/cfn-flow
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
class CfnFlow::Template
|
2
|
+
attr_reader :from, :prefix, :bucket
|
3
|
+
def initialize(from:, prefix:, bucket:)
|
4
|
+
@from, @prefix, @bucket = from, prefix, bucket
|
5
|
+
end
|
6
|
+
|
7
|
+
def yaml?
|
8
|
+
from.end_with?('.yml')
|
9
|
+
end
|
10
|
+
|
11
|
+
def json?
|
12
|
+
! yaml?
|
13
|
+
end
|
14
|
+
|
15
|
+
# Determine if this file is a CFN template
|
16
|
+
def is_cfn_template?
|
17
|
+
from_data.is_a?(Hash) && from_data.key?('Resources')
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate!
|
21
|
+
cfn.validate_template(template_body: to_json)
|
22
|
+
end
|
23
|
+
|
24
|
+
def key
|
25
|
+
# Replace leading './' in from, rename *.yml to *.json
|
26
|
+
File.join(prefix, from.sub(/\A\.\//, '').sub(/\.yml\Z/, '.json'))
|
27
|
+
end
|
28
|
+
|
29
|
+
def upload!
|
30
|
+
s3_object.put(body: to_json)
|
31
|
+
end
|
32
|
+
|
33
|
+
def url
|
34
|
+
s3_object.public_url
|
35
|
+
end
|
36
|
+
|
37
|
+
def from_data
|
38
|
+
# We *could* load JSON as YAML, but that would generate confusing errors
|
39
|
+
# in the case of a JSON syntax error.
|
40
|
+
@from_data ||= yaml? ? YAML.load_file(from) : MultiJson.load(File.read(from))
|
41
|
+
rescue
|
42
|
+
puts "Error loading #{from}"
|
43
|
+
raise $!
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_json
|
47
|
+
@to_json ||= MultiJson.dump(from_data, pretty: true)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def cfn
|
52
|
+
@cfn ||= Aws::CloudFormation::Client.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def s3_object
|
56
|
+
@s3_object ||= Aws::S3::Object.new(bucket, key)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/cfn-flow.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'aws-sdk'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
class CfnFlow < Thor
|
7
|
+
class GitError < StandardError; end
|
8
|
+
|
9
|
+
require 'cfn-flow/template'
|
10
|
+
def self.shared_options
|
11
|
+
|
12
|
+
method_option :bucket, type: :string, desc: 'S3 bucket for templates'
|
13
|
+
method_option :to, type: :string, desc: 'S3 path prefix for templates'
|
14
|
+
method_option :from, type: :string, desc: 'Local source directory for templates'
|
15
|
+
method_option 'dev-name', type: :string, desc: 'Personal development prefix'
|
16
|
+
method_option :region, type: :string, desc: 'AWS Region'
|
17
|
+
|
18
|
+
method_option :verbose, type: :boolean, desc: 'Verbose output', default: false
|
19
|
+
end
|
20
|
+
|
21
|
+
no_commands do
|
22
|
+
def load_config
|
23
|
+
defaults = { 'from' => '.' }
|
24
|
+
file_config = begin
|
25
|
+
YAML.load_file('./cfn-flow.yml')
|
26
|
+
rescue Errno::ENOENT
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
env_config = {
|
30
|
+
'bucket' => ENV['CFN_FLOW_BUCKET'],
|
31
|
+
'to' => ENV['CFN_FLOW_TO'],
|
32
|
+
'from' => ENV['CFN_FLOW_FROM'],
|
33
|
+
'dev-name' => ENV['CFN_FLOW_DEV_NAME'],
|
34
|
+
'region' => ENV['AWS_REGION']
|
35
|
+
}.delete_if {|_,v| v.nil?}
|
36
|
+
|
37
|
+
# Env vars override config file. Command args override env vars.
|
38
|
+
self.options = defaults.merge(file_config).merge(env_config).merge(options)
|
39
|
+
|
40
|
+
# Ensure region env var is set for AWS client
|
41
|
+
ENV['AWS_REGION'] = options['region']
|
42
|
+
|
43
|
+
# TODO: validate required options are present
|
44
|
+
end
|
45
|
+
|
46
|
+
shared_options
|
47
|
+
def load_templates
|
48
|
+
load_config
|
49
|
+
glob = File.join(options['from'], '**/*.{yml,json,template}')
|
50
|
+
|
51
|
+
@templates = Dir.glob(glob).map { |path|
|
52
|
+
CfnFlow::Template.new(from: path, bucket: options['bucket'], prefix: prefix)
|
53
|
+
}.select! {|t|
|
54
|
+
verbose "Checking file #{t.from}... "
|
55
|
+
if t.is_cfn_template?
|
56
|
+
verbose "loaded"
|
57
|
+
true
|
58
|
+
else
|
59
|
+
verbose "skipped."
|
60
|
+
false
|
61
|
+
end
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc :validate, 'Validates templates'
|
67
|
+
shared_options
|
68
|
+
def validate
|
69
|
+
load_templates
|
70
|
+
@templates.each do |t|
|
71
|
+
begin
|
72
|
+
verbose "Validating #{t.from}... "
|
73
|
+
t.validate!
|
74
|
+
verbose "valid."
|
75
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
76
|
+
say "Error validating #{t.from}. Message:"
|
77
|
+
say $!.message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc :upload, 'Validate & upload templates to the CFN_DEV_FLOW_NAME prefix'
|
83
|
+
shared_options
|
84
|
+
method_option :release, type: :string, desc: 'Upload & tag release'
|
85
|
+
def upload
|
86
|
+
tag_release if options['release']
|
87
|
+
|
88
|
+
validate
|
89
|
+
@templates.each do |t|
|
90
|
+
verbose "Uploading #{t.from} to #{t.url}"
|
91
|
+
t.upload!
|
92
|
+
end
|
93
|
+
|
94
|
+
push_release if options['release']
|
95
|
+
|
96
|
+
end
|
97
|
+
default_task :upload
|
98
|
+
|
99
|
+
private
|
100
|
+
def verbose(msg)
|
101
|
+
say msg if options['verbose']
|
102
|
+
end
|
103
|
+
|
104
|
+
def prefix
|
105
|
+
# Add the release or dev name to the prefix
|
106
|
+
parts = []
|
107
|
+
parts << options['prefix'] unless options['prefix'].empty?
|
108
|
+
if options['release']
|
109
|
+
parts += [ 'release', options['release'] ]
|
110
|
+
else
|
111
|
+
parts += [ 'dev', options['dev-name'] ]
|
112
|
+
end
|
113
|
+
File.join(*parts)
|
114
|
+
end
|
115
|
+
|
116
|
+
def tag_release
|
117
|
+
# Check git status
|
118
|
+
unless `git status -s`.empty?
|
119
|
+
git_error "Git working directory is not clean. Please commit or reset changes in order to release."
|
120
|
+
end
|
121
|
+
unless $?.success?
|
122
|
+
git_error "Error running `git status`"
|
123
|
+
end
|
124
|
+
|
125
|
+
say "Tagging release #{options['release']}"
|
126
|
+
`git tag -a -m #{options['release']}, #{options['release']}`
|
127
|
+
unless $?.success?
|
128
|
+
git_error "Error tagging release."
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def push_tag
|
133
|
+
`git push origin #{options['release']}`
|
134
|
+
unless $?.success?
|
135
|
+
git_error "Error pushing tag to origin."
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def git_error(message)
|
140
|
+
say message, :red
|
141
|
+
raise GitError.new(message)
|
142
|
+
end
|
143
|
+
end
|
data/spec/sqs.template
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
{
|
2
|
+
"AWSTemplateFormatVersion" : "2010-09-09",
|
3
|
+
|
4
|
+
"Description" : "AWS CloudFormation Sample Template SQS_With_CloudWatch_Alarms: Sample template showing how to create an SQS queue with AWS CloudWatch alarms on queue depth. **WARNING** This template creates an Amazon SQS Queue and one or more Amazon CloudWatch alarms. You will be billed for the AWS resources used if you create a stack from this template.",
|
5
|
+
|
6
|
+
"Parameters" : {
|
7
|
+
"AlarmEMail": {
|
8
|
+
"Description": "EMail address to notify if there are any operational issues",
|
9
|
+
"Type": "String",
|
10
|
+
"AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)",
|
11
|
+
"ConstraintDescription": "must be a valid email address."
|
12
|
+
}
|
13
|
+
},
|
14
|
+
|
15
|
+
"Resources" : {
|
16
|
+
"MyQueue" : {
|
17
|
+
"Type" : "AWS::SQS::Queue",
|
18
|
+
"Properties" : {
|
19
|
+
}
|
20
|
+
},
|
21
|
+
|
22
|
+
"AlarmTopic": {
|
23
|
+
"Type": "AWS::SNS::Topic",
|
24
|
+
"Properties": {
|
25
|
+
"Subscription": [{
|
26
|
+
"Endpoint": { "Ref": "AlarmEMail" },
|
27
|
+
"Protocol": "email"
|
28
|
+
}]
|
29
|
+
}
|
30
|
+
},
|
31
|
+
|
32
|
+
"QueueDepthAlarm": {
|
33
|
+
"Type": "AWS::CloudWatch::Alarm",
|
34
|
+
"Properties": {
|
35
|
+
"AlarmDescription": "Alarm if queue depth grows beyond 10 messages",
|
36
|
+
"Namespace": "AWS/SQS",
|
37
|
+
"MetricName": "ApproximateNumberOfMessagesVisible",
|
38
|
+
"Dimensions": [{
|
39
|
+
"Name": "QueueName",
|
40
|
+
"Value" : { "Fn::GetAtt" : ["MyQueue", "QueueName"] }
|
41
|
+
}],
|
42
|
+
"Statistic": "Sum",
|
43
|
+
"Period": "300",
|
44
|
+
"EvaluationPeriods": "1",
|
45
|
+
"Threshold": "10",
|
46
|
+
"ComparisonOperator": "GreaterThanThreshold",
|
47
|
+
"AlarmActions": [{ "Ref": "AlarmTopic" }],
|
48
|
+
"InsufficientDataActions": [{ "Ref": "AlarmTopic" }]
|
49
|
+
}
|
50
|
+
}
|
51
|
+
},
|
52
|
+
"Outputs" : {
|
53
|
+
"QueueURL" : {
|
54
|
+
"Description" : "URL of newly created SQS Queue",
|
55
|
+
"Value" : { "Ref" : "MyQueue" }
|
56
|
+
},
|
57
|
+
"QueueARN" : {
|
58
|
+
"Description" : "ARN of newly created SQS Queue",
|
59
|
+
"Value" : { "Fn::GetAtt" : ["MyQueue", "Arn"]}
|
60
|
+
},
|
61
|
+
"QueueName" : {
|
62
|
+
"Description" : "Name newly created SQS Queue",
|
63
|
+
"Value" : { "Fn::GetAtt" : ["MyQueue", "QueueName"]}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
data/spec/sqs.yml
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
---
|
2
|
+
AWSTemplateFormatVersion: '2010-09-09'
|
3
|
+
Description: 'AWS CloudFormation Sample Template SQS_With_CloudWatch_Alarms: Sample
|
4
|
+
template showing how to create an SQS queue with AWS CloudWatch alarms on queue
|
5
|
+
depth. **WARNING** This template creates an Amazon SQS Queue and one or more Amazon
|
6
|
+
CloudWatch alarms. You will be billed for the AWS resources used if you create a
|
7
|
+
stack from this template.'
|
8
|
+
Parameters:
|
9
|
+
AlarmEMail:
|
10
|
+
Description: EMail address to notify if there are any operational issues
|
11
|
+
Type: String
|
12
|
+
AllowedPattern: "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)"
|
13
|
+
ConstraintDescription: must be a valid email address.
|
14
|
+
Resources:
|
15
|
+
MyQueue:
|
16
|
+
Type: AWS::SQS::Queue
|
17
|
+
Properties: {}
|
18
|
+
AlarmTopic:
|
19
|
+
Type: AWS::SNS::Topic
|
20
|
+
Properties:
|
21
|
+
Subscription:
|
22
|
+
- Endpoint:
|
23
|
+
Ref: AlarmEMail
|
24
|
+
Protocol: email
|
25
|
+
QueueDepthAlarm:
|
26
|
+
Type: AWS::CloudWatch::Alarm
|
27
|
+
Properties:
|
28
|
+
AlarmDescription: Alarm if queue depth grows beyond 10 messages
|
29
|
+
Namespace: AWS/SQS
|
30
|
+
MetricName: ApproximateNumberOfMessagesVisible
|
31
|
+
Dimensions:
|
32
|
+
- Name: QueueName
|
33
|
+
Value:
|
34
|
+
Fn::GetAtt:
|
35
|
+
- MyQueue
|
36
|
+
- QueueName
|
37
|
+
Statistic: Sum
|
38
|
+
Period: '300'
|
39
|
+
EvaluationPeriods: '1'
|
40
|
+
Threshold: '10'
|
41
|
+
ComparisonOperator: GreaterThanThreshold
|
42
|
+
AlarmActions:
|
43
|
+
- Ref: AlarmTopic
|
44
|
+
InsufficientDataActions:
|
45
|
+
- Ref: AlarmTopic
|
46
|
+
Outputs:
|
47
|
+
QueueURL:
|
48
|
+
Description: URL of newly created SQS Queue
|
49
|
+
Value:
|
50
|
+
Ref: MyQueue
|
51
|
+
QueueARN:
|
52
|
+
Description: ARN of newly created SQS Queue
|
53
|
+
Value:
|
54
|
+
Fn::GetAtt:
|
55
|
+
- MyQueue
|
56
|
+
- Arn
|
57
|
+
QueueName:
|
58
|
+
Description: Name newly created SQS Queue
|
59
|
+
Value:
|
60
|
+
Fn::GetAtt:
|
61
|
+
- MyQueue
|
62
|
+
- QueueName
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cfn-flow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Suggs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.20.pre
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.20.pre
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.18'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.18'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: multi_json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: appraisal
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: An opinionate worflow for AWS CloudFormation
|
98
|
+
email: aaron@ktheory.com
|
99
|
+
executables:
|
100
|
+
- cfn-flow
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- bin/cfn-flow
|
107
|
+
- lib/cfn-flow.rb
|
108
|
+
- lib/cfn-flow/template.rb
|
109
|
+
- lib/cfn-flow/version.rb
|
110
|
+
- spec/sqs.template
|
111
|
+
- spec/sqs.yml
|
112
|
+
homepage: http://github.com/kickstarter/cfn-flow
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options:
|
118
|
+
- "--charset=UTF-8"
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 2.0.0
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.4.5
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: A CLI for CloudFormation templates
|
137
|
+
test_files:
|
138
|
+
- spec/sqs.template
|
139
|
+
- spec/sqs.yml
|