cloud_builder 0.0.6
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.
- data/.gitignore +17 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +1 -0
- data/bin/stack +5 -0
- data/cloud_builder.gemspec +27 -0
- data/lib/cloud_builder/brick.rb +45 -0
- data/lib/cloud_builder/cli.rb +79 -0
- data/lib/cloud_builder/dontformatunderscore.rb +23 -0
- data/lib/cloud_builder/dsl.rb +138 -0
- data/lib/cloud_builder/dslostruct.rb +33 -0
- data/lib/cloud_builder/jsonable.rb +22 -0
- data/lib/cloud_builder/mappings.rb +25 -0
- data/lib/cloud_builder/output.rb +45 -0
- data/lib/cloud_builder/parameter.rb +43 -0
- data/lib/cloud_builder/reference.rb +88 -0
- data/lib/cloud_builder/resource.rb +82 -0
- data/lib/cloud_builder/stack.rb +12 -0
- data/lib/cloud_builder/version.rb +3 -0
- data/lib/cloud_builder.rb +45 -0
- data/spec/example_spec.rb +14 -0
- data/stacks/bricks/example_security_groups.rb +42 -0
- data/stacks/bricks/example_tags.rb +38 -0
- data/stacks/bricks/mappings/ami_ids_ubuntu_ebs_20130624.rb +39 -0
- data/stacks/bricks/mappings/ami_ids_ubuntu_instancestore_20130624.rb +40 -0
- data/stacks/bricks/mappings/instance2arch.rb +35 -0
- data/stacks/example.rb +80 -0
- metadata +163 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Songkick, Optaros
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# CloudBuilder
|
2
|
+
|
3
|
+
Generates JSON config for AWS CloudFormation using a Ruby DSL. Manage CloudFormation stacks - create, update, diff.
|
4
|
+
|
5
|
+
Based on https://github.com/songkick/cloud_formatter
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Clone the repository, then run:
|
10
|
+
|
11
|
+
gem build cloud_builder.gemspec
|
12
|
+
gem install cloud_builder-version.gem
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
### CLI tool
|
17
|
+
|
18
|
+
$ stack --help
|
19
|
+
Usage:
|
20
|
+
stack [OPTIONS] STACK
|
21
|
+
|
22
|
+
Parameters:
|
23
|
+
STACK stack to build
|
24
|
+
|
25
|
+
Options:
|
26
|
+
-r, --region REGION AWS region to use (default: $EC2_REGION, or "us-east-1")
|
27
|
+
-v, --validate validate the stack file before doing anything else
|
28
|
+
-b, --bucket BUCKET upload template to BUCKET (default: $CLOUD_BUILDER_BUCKET, or nil)
|
29
|
+
-t, --diff-tool DIFF_TOOL tool to use for diff (default: $CLOUD_BUILDER_DIFF_TOOL)
|
30
|
+
-c, --create create the stack
|
31
|
+
-u, --update update the stack
|
32
|
+
-d, --diff do a diff between the existing template in BUCKET and the generated template
|
33
|
+
-e, --estimate estimate template cost
|
34
|
+
-h, --help print help
|
35
|
+
|
36
|
+
For most actions you will require an active AWS account, so make sure you export `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to `ENV`
|
37
|
+
|
38
|
+
### Example stack
|
39
|
+
|
40
|
+
See stacks/example.rb for an example stack.
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
1. Fork it
|
45
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
46
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
47
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
5. Create new Pull Request
|
49
|
+
|
50
|
+
## Changelog
|
51
|
+
|
52
|
+
### 0.0.6
|
53
|
+
- added support for template Outputs (see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)
|
54
|
+
|
55
|
+
### 0.0.5
|
56
|
+
- cli can use the EC2_REGION, CLOUD_BUILDER_BUCKET and CLOUD_BUILDER_DIFF_TOOL environment variables as defaults for `--region`, `--bucket` and `--diff-tool`
|
57
|
+
- deprecated the `--upload` flag/action, if you specify a bucket the stack json is uploaded by default
|
58
|
+
|
59
|
+
### 0.0.4
|
60
|
+
- support for specifying an AWS region
|
61
|
+
|
62
|
+
### 0.0.3
|
63
|
+
- add the Changelog
|
64
|
+
- AWS resources can have a Version property
|
65
|
+
|
66
|
+
### 0.0.2
|
67
|
+
- fix cloud_builder problem when using `--help`
|
68
|
+
- add DontFormatUnderscore class
|
69
|
+
- estimation should be done after uploading to s3 bucket
|
70
|
+
- add `--diff-tool` to specify a different tool to use for diffs
|
71
|
+
|
72
|
+
### 0.0.1
|
73
|
+
- beta initial release
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/stack
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cloud_builder/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "cloud_builder"
|
8
|
+
gem.version = CloudBuilder::GEM_VERSION
|
9
|
+
gem.authors = ["Sorin Stoiana"]
|
10
|
+
gem.email = ["sstoiana@optaros.com"]
|
11
|
+
gem.description = "Generate JSON config for AWS CloudFormation using a Ruby based DSL"
|
12
|
+
gem.summary = "Generate JSON config for AWS CloudFormation"
|
13
|
+
gem.homepage = "https://github.com/Optaros/cloud_builder"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency "netaddr"
|
21
|
+
gem.add_development_dependency "rspec", "~> 2.6"
|
22
|
+
|
23
|
+
gem.add_dependency "clamp"
|
24
|
+
gem.add_dependency "json"
|
25
|
+
gem.add_dependency "aws-sdk"
|
26
|
+
gem.add_dependency "activesupport"
|
27
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'cloud_builder/reference'
|
2
|
+
|
3
|
+
module CloudBuilder
|
4
|
+
class Brick
|
5
|
+
extend Forwardable
|
6
|
+
include ExposesRefs
|
7
|
+
|
8
|
+
def initialize(stack, type, hash, &block)
|
9
|
+
@stack = stack
|
10
|
+
@type = type
|
11
|
+
@factory = block
|
12
|
+
@block = block
|
13
|
+
|
14
|
+
@hash = DSLOpenStruct.new(hash)
|
15
|
+
|
16
|
+
filename = "%s/bricks/%s.rb" % [ @stack.dirname, @type.to_s ]
|
17
|
+
instance_eval File.read(filename), filename
|
18
|
+
end
|
19
|
+
|
20
|
+
def brick
|
21
|
+
@hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def globals
|
25
|
+
@stack.globals
|
26
|
+
end
|
27
|
+
|
28
|
+
def include_brick(name, hash={}, &block)
|
29
|
+
@stack.include_brick(name, hash, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def mappings(&block)
|
33
|
+
@stack.mappings(&block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def parameter(name, &block)
|
37
|
+
@stack.parameter(name, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def resource(name, &block)
|
41
|
+
@stack.resource(name, &block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'clamp'
|
2
|
+
require 'aws-sdk'
|
3
|
+
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module CloudBuilder
|
7
|
+
class StackCommand < Clamp::Command
|
8
|
+
parameter "STACK", "stack to build"
|
9
|
+
option ["-r", "--region"], "REGION", "AWS region to use", :default => "us-east-1", :environment_variable => "EC2_REGION"
|
10
|
+
option ["-v", "--validate"], :flag, "validate the stack file before doing anything else"
|
11
|
+
option ["-b", "--bucket"], "BUCKET", "upload template to BUCKET", :attribute_name => :bucket, :default => nil, :environment_variable => "CLOUD_BUILDER_BUCKET"
|
12
|
+
option ["-t", "--diff-tool"], "DIFF_TOOL", "tool to use for diff", :environment_variable => "CLOUD_BUILDER_DIFF_TOOL"
|
13
|
+
option ["-c", "--create"], :flag, "create the stack"
|
14
|
+
option ["-u", "--update"], :flag, "update the stack"
|
15
|
+
|
16
|
+
option ["-d", "--diff"], :flag, "do a diff between the existing template in BUCKET and the generated template"
|
17
|
+
|
18
|
+
option ["-e", "--estimate"], :flag, "estimate template cost"
|
19
|
+
|
20
|
+
def execute
|
21
|
+
template = CloudBuilder::Stack.new(stack).to_json + "\n"
|
22
|
+
|
23
|
+
cf = AWS::CloudFormation.new(:cloud_formation_endpoint => 'cloudformation.%s.amazonaws.com' % region)
|
24
|
+
|
25
|
+
s3 = AWS::S3.new
|
26
|
+
|
27
|
+
key = File.basename(stack, '.*')
|
28
|
+
|
29
|
+
if validate?
|
30
|
+
result = cf.validate_template(template)
|
31
|
+
if result.has_key?(:code)
|
32
|
+
raise Exception, "Could not validate!\ncode=#{result[:code]}\nreason=#{result[:reason]}\n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if diff?
|
37
|
+
remote_template = cf.stacks[key].template
|
38
|
+
|
39
|
+
# b = s3.buckets[bucket]
|
40
|
+
# o = b.objects[key]
|
41
|
+
# remote_template = o.read
|
42
|
+
|
43
|
+
t1 = Tempfile.new('stack')
|
44
|
+
t1.write(remote_template)
|
45
|
+
t1.close
|
46
|
+
|
47
|
+
t2 = Tempfile.new('stack')
|
48
|
+
t2.write(template)
|
49
|
+
t2.close
|
50
|
+
|
51
|
+
cmd = "%s %s %s" % [diff_tool ? diff_tool : "git diff --color", t1.path, t2.path]
|
52
|
+
# puts cmd
|
53
|
+
puts `#{cmd}`
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
if bucket
|
58
|
+
b = s3.buckets[bucket]
|
59
|
+
o = b.objects[key]
|
60
|
+
o.write template
|
61
|
+
template = o.public_url
|
62
|
+
else
|
63
|
+
puts template
|
64
|
+
end
|
65
|
+
|
66
|
+
if estimate?
|
67
|
+
puts cf.estimate_template_cost(template, :capabilities => ["CAPABILITY_IAM"] )
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
if create?
|
72
|
+
cf.stacks.create(key, template, :capabilities => ["CAPABILITY_IAM"] )
|
73
|
+
elsif update?
|
74
|
+
cf.stacks[key].update(:template => template, :capabilities => ["CAPABILITY_IAM"])
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
|
4
|
+
module CloudBuilder
|
5
|
+
class DontFormatUnderscore
|
6
|
+
def initialize(*p)
|
7
|
+
@vars = ActiveSupport::OrderedHash.new()
|
8
|
+
if p.first
|
9
|
+
p.first.sort.map do |k,v|
|
10
|
+
self[k] = v
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(key, value)
|
16
|
+
@vars[key] = value
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_json_data()
|
20
|
+
@vars
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module CloudBuilder
|
4
|
+
|
5
|
+
module DSL
|
6
|
+
|
7
|
+
attr_accessor :globals
|
8
|
+
|
9
|
+
def globals
|
10
|
+
@globals ||= DSLOpenStruct.new()
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.format(key)
|
14
|
+
key.to_s.gsub(/(.)[_-](.)/) { $1 + $2.upcase }.gsub(/^(.)/) { $1.upcase }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.hashize(value, format_hash_keys = true)
|
18
|
+
case value
|
19
|
+
when Array then value.map { |v| jsonize v,format_hash_keys }
|
20
|
+
when Hash then
|
21
|
+
ret = {}
|
22
|
+
value.each do |k,v|
|
23
|
+
if format_hash_keys
|
24
|
+
ret[DSL.format(k)] = jsonize v,format_hash_keys
|
25
|
+
else
|
26
|
+
ret[k] = jsonize v,format_hash_keys
|
27
|
+
end
|
28
|
+
end
|
29
|
+
ret
|
30
|
+
else
|
31
|
+
value.respond_to?(:to_json_data) ? value.to_json_data : value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.jsonize(value, format_hash_keys = true)
|
36
|
+
ret = self.hashize(value, format_hash_keys)
|
37
|
+
case ret
|
38
|
+
when Hash then
|
39
|
+
sh = ActiveSupport::OrderedHash.new
|
40
|
+
ret.sort.map do |k,v|
|
41
|
+
sh[k] =v
|
42
|
+
end
|
43
|
+
sh
|
44
|
+
else
|
45
|
+
ret
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def mappings(&block)
|
50
|
+
_mappings.instance_eval(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def resource(name, &block)
|
54
|
+
_resources[name.to_s] = Resource.new(self, name, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def include_brick(name, hash={}, &block)
|
58
|
+
_bricks[name.to_s] = Brick.new(self, name, hash, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def parameter(name, &block)
|
62
|
+
_parameters[DSL.format(name.to_s)] = Parameter.new(self, &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
def output(name, &block)
|
66
|
+
_outputs[DSL.format(name.to_s)] = Output.new(self, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_json
|
70
|
+
JSON.pretty_generate(DSL.jsonize(generate_spec, false))
|
71
|
+
end
|
72
|
+
|
73
|
+
def reference_type(name)
|
74
|
+
if _parameters.has_key?(name)
|
75
|
+
:parameter
|
76
|
+
elsif _mappings.has_key?(name)
|
77
|
+
:map
|
78
|
+
elsif _resources.has_key?(name)
|
79
|
+
:resource
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def dirname
|
84
|
+
@dirname
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_missing(field, value)
|
88
|
+
instance_variable_set("@#{field}", value)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def generate_spec
|
94
|
+
spec = {
|
95
|
+
DESCRIPTION => @description,
|
96
|
+
VERSION => @template_version,
|
97
|
+
MAPPINGS => DSL.jsonize(_mappings),
|
98
|
+
RESOURCES => {},
|
99
|
+
PARAMETERS => {},
|
100
|
+
OUTPUTS => {},
|
101
|
+
}
|
102
|
+
_resources.each do |name, instance|
|
103
|
+
spec[RESOURCES][DSL.format(name)] = DSL.jsonize(instance)
|
104
|
+
end
|
105
|
+
|
106
|
+
_parameters.each do |name, parameter|
|
107
|
+
spec[PARAMETERS][name] = DSL.jsonize(parameter)
|
108
|
+
end
|
109
|
+
|
110
|
+
_outputs.each do |name, parameter|
|
111
|
+
spec[OUTPUTS][name] = DSL.jsonize(parameter)
|
112
|
+
end
|
113
|
+
|
114
|
+
spec
|
115
|
+
end
|
116
|
+
|
117
|
+
def _mappings
|
118
|
+
@mappings ||= Mappings.new
|
119
|
+
end
|
120
|
+
|
121
|
+
def _resources
|
122
|
+
@resources ||= {}
|
123
|
+
end
|
124
|
+
|
125
|
+
def _bricks
|
126
|
+
@bricks ||= {}
|
127
|
+
end
|
128
|
+
|
129
|
+
def _parameters
|
130
|
+
@parameters ||= {}
|
131
|
+
end
|
132
|
+
|
133
|
+
def _outputs
|
134
|
+
@outputs ||= {}
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module CloudBuilder
|
4
|
+
class DSLOpenStruct < OpenStruct
|
5
|
+
|
6
|
+
def ref(name)
|
7
|
+
Reference.new(name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_att(name, att)
|
11
|
+
Reference::Attribute.new(name, att)
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(mid, *args)
|
15
|
+
mname = mid.id2name
|
16
|
+
len = args.length
|
17
|
+
if mname.chomp!('=')
|
18
|
+
if len != 1
|
19
|
+
raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
|
20
|
+
end
|
21
|
+
modifiable[new_ostruct_member(mname)] = args[0]
|
22
|
+
elsif len == 0
|
23
|
+
if @table.has_key? mid
|
24
|
+
@table[mid]
|
25
|
+
else
|
26
|
+
raise NameError, "undefined property #{mid} for #{self}", caller(1)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
raise NoMethodError, "undefined method `#{mid}' for #{self}", caller(1)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CloudBuilder
|
2
|
+
class JSONable
|
3
|
+
def to_hash
|
4
|
+
hash = {}
|
5
|
+
|
6
|
+
self.instance_variables.each do |var|
|
7
|
+
hash[var.to_s.delete("@")] = self.instance_variable_get var
|
8
|
+
end
|
9
|
+
hash
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_json(*a)
|
13
|
+
self.to_hash.to_json(*a)
|
14
|
+
end
|
15
|
+
|
16
|
+
# def from_json! string
|
17
|
+
# JSON.load(string).each do |var, val|
|
18
|
+
# self.instance_variable_set var, val
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module CloudBuilder
|
4
|
+
class Mappings
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :@maps, :has_key?
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@maps = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_json_data
|
13
|
+
json = {}
|
14
|
+
@maps.each do |key, value|
|
15
|
+
json[DSL.format(key)] = value
|
16
|
+
end
|
17
|
+
json
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(map_name, values)
|
21
|
+
@maps[map_name.to_s] = values
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module CloudBuilder
|
2
|
+
class Output < JSONable
|
3
|
+
include ExposesRefs
|
4
|
+
|
5
|
+
def initialize(stack, &block)
|
6
|
+
@stack = stack
|
7
|
+
|
8
|
+
@Description = ''
|
9
|
+
@block = block
|
10
|
+
instance_exec(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
hash = super.to_hash
|
15
|
+
hash.delete('block')
|
16
|
+
hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def globals
|
20
|
+
@stack.globals
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_json_data
|
24
|
+
{ "Value" => @Value, "Description" => @Description }
|
25
|
+
end
|
26
|
+
|
27
|
+
def value v
|
28
|
+
@Value = v
|
29
|
+
end
|
30
|
+
|
31
|
+
def description value
|
32
|
+
@Description = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def brick
|
36
|
+
@block.binding.eval('brick')
|
37
|
+
end
|
38
|
+
# def method_missing(field, *params)
|
39
|
+
# instance_variable_set("@#{field}", value)
|
40
|
+
# print @block.binding.eval('@hash')
|
41
|
+
# null
|
42
|
+
# end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module CloudBuilder
|
2
|
+
class Parameter < JSONable
|
3
|
+
def initialize(stack, &block)
|
4
|
+
@stack = stack
|
5
|
+
|
6
|
+
@Type = 'String'
|
7
|
+
@block = block
|
8
|
+
instance_exec(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
hash = super.to_hash
|
13
|
+
hash.delete('block')
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def globals
|
18
|
+
@stack.globals
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_json_data
|
22
|
+
{ "Default" => @Default, "Type" => @Type }
|
23
|
+
end
|
24
|
+
|
25
|
+
def default value
|
26
|
+
@Default = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def type value
|
30
|
+
@Type = value
|
31
|
+
end
|
32
|
+
|
33
|
+
def brick
|
34
|
+
@block.binding.eval('brick')
|
35
|
+
end
|
36
|
+
# def method_missing(field, *params)
|
37
|
+
# instance_variable_set("@#{field}", value)
|
38
|
+
# print @block.binding.eval('@hash')
|
39
|
+
# null
|
40
|
+
# end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module CloudBuilder
|
2
|
+
module ExposesRefs
|
3
|
+
def ref(name)
|
4
|
+
Reference.new(name)
|
5
|
+
end
|
6
|
+
|
7
|
+
def base64(value)
|
8
|
+
Reference::Base64.new(value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_att(name, att)
|
12
|
+
Reference::Attribute.new(name, att)
|
13
|
+
end
|
14
|
+
|
15
|
+
def join(sep, values)
|
16
|
+
Reference::Join.new(sep, values)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Reference
|
21
|
+
def initialize(name)
|
22
|
+
@name = name
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_json_data
|
26
|
+
{REF => DSL.format(@name)}
|
27
|
+
end
|
28
|
+
|
29
|
+
class Base64
|
30
|
+
def initialize(value)
|
31
|
+
@value = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_json_data
|
35
|
+
{ BASE64 => @value }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Join
|
40
|
+
def initialize(sep, values)
|
41
|
+
@sep = sep
|
42
|
+
@values = values
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_json_data
|
46
|
+
{ JOIN => [ @sep, DSL.jsonize(@values) ]}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Attribute
|
51
|
+
def initialize(name, att)
|
52
|
+
@name = name
|
53
|
+
@att = att
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_json_data
|
57
|
+
{GET_ATT => [DSL.format(@name), DSL.format(@att)]}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Map
|
62
|
+
def initialize(name)
|
63
|
+
@name = name.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
def [](key)
|
67
|
+
Key.new(@name, [key])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Key
|
72
|
+
def initialize(name, key)
|
73
|
+
@map_name = name
|
74
|
+
@key = key
|
75
|
+
end
|
76
|
+
|
77
|
+
def [](subkey)
|
78
|
+
Key.new(@map_name, @key + [subkey])
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_json_data
|
82
|
+
{FIND_IN_MAP => [DSL.format(@map_name)] + DSL.jsonize(@key)}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'cloud_builder/reference'
|
2
|
+
|
3
|
+
module CloudBuilder
|
4
|
+
class Resource
|
5
|
+
include ExposesRefs
|
6
|
+
def initialize(stack, name, &block)
|
7
|
+
@stack = stack
|
8
|
+
@type = nil
|
9
|
+
@properties = {}
|
10
|
+
@metadata = {}
|
11
|
+
@block = block
|
12
|
+
|
13
|
+
# add metadata describing the brick we were defined in
|
14
|
+
if @block.binding.eval('@type')
|
15
|
+
metadata do
|
16
|
+
brick_name @block.binding.eval('@type')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
instance_eval(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def type(value)
|
24
|
+
@type = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def version(value)
|
28
|
+
@version = value
|
29
|
+
end
|
30
|
+
|
31
|
+
def properties
|
32
|
+
old_map = @current_map
|
33
|
+
@current_map = @properties
|
34
|
+
yield
|
35
|
+
@current_map = old_map
|
36
|
+
end
|
37
|
+
|
38
|
+
def metadata
|
39
|
+
old_map = @current_map
|
40
|
+
@current_map = @metadata
|
41
|
+
yield
|
42
|
+
@current_map = old_map
|
43
|
+
end
|
44
|
+
|
45
|
+
def brick
|
46
|
+
@block.binding.eval('brick')
|
47
|
+
end
|
48
|
+
|
49
|
+
def globals
|
50
|
+
@stack.globals
|
51
|
+
end
|
52
|
+
|
53
|
+
def tags(tag_map, propagate = nil)
|
54
|
+
list = @current_map[TAGS] ||= []
|
55
|
+
tag_map = Hash[tag_map.map { |key, value| [key.to_s, value] }]
|
56
|
+
tag_map.keys.sort.each do |key|
|
57
|
+
if propagate.nil?
|
58
|
+
list << {KEY => DSL.format(key), VALUE => DSL.jsonize(tag_map[key])}
|
59
|
+
else
|
60
|
+
list << {KEY => DSL.format(key), VALUE => DSL.jsonize(tag_map[key]), PROPAGATE_AT_LAUNCH => propagate }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_json_data
|
66
|
+
if @version
|
67
|
+
{TYPE => @type, "Version" => @version, METADATA => @metadata, PROPERTIES => @properties}
|
68
|
+
else
|
69
|
+
{TYPE => @type, METADATA => @metadata, PROPERTIES => @properties}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_missing(field, *params)
|
74
|
+
if @stack.reference_type(field.to_s) == :map
|
75
|
+
Reference::Map.new(field)
|
76
|
+
else
|
77
|
+
@current_map[DSL.format(field)] = DSL.jsonize(params.first)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "cloud_builder/version"
|
2
|
+
require "cloud_builder/cli"
|
3
|
+
require 'cloud_builder/dsl'
|
4
|
+
require 'cloud_builder/resource'
|
5
|
+
require 'cloud_builder/mappings'
|
6
|
+
require 'cloud_builder/reference'
|
7
|
+
require 'cloud_builder/stack'
|
8
|
+
require 'cloud_builder/brick'
|
9
|
+
require 'cloud_builder/jsonable'
|
10
|
+
require 'cloud_builder/parameter'
|
11
|
+
require 'cloud_builder/output'
|
12
|
+
|
13
|
+
|
14
|
+
require 'cloud_builder/dslostruct'
|
15
|
+
require 'cloud_builder/dontformatunderscore'
|
16
|
+
|
17
|
+
require 'json'
|
18
|
+
require 'forwardable'
|
19
|
+
|
20
|
+
module CloudBuilder
|
21
|
+
DESCRIPTION = 'Description'
|
22
|
+
GET_ATT = 'Fn::GetAtt'
|
23
|
+
FIND_IN_MAP = 'Fn::FindInMap'
|
24
|
+
BASE64 = 'Fn::Base64'
|
25
|
+
JOIN = 'Fn::Join'
|
26
|
+
KEY = 'Key'
|
27
|
+
MAPPINGS = 'Mappings'
|
28
|
+
PROPERTIES = 'Properties'
|
29
|
+
REF = 'Ref'
|
30
|
+
RESOURCES = 'Resources'
|
31
|
+
PARAMETERS = 'Parameters'
|
32
|
+
METADATA = 'Metadata'
|
33
|
+
OUTPUTS = 'Outputs'
|
34
|
+
TAGS = 'Tags'
|
35
|
+
TYPE = 'Type'
|
36
|
+
VALUE = 'Value'
|
37
|
+
PROPAGATE_AT_LAUNCH = 'PropagateAtLaunch'
|
38
|
+
VERSION = 'AWSTemplateFormatVersion'
|
39
|
+
|
40
|
+
|
41
|
+
class Spec
|
42
|
+
extend DSL
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'cloud_builder'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'aws-sdk'
|
4
|
+
|
5
|
+
stack = CloudBuilder::Stack.new(File.expand_path('../../stacks/example.rb', __FILE__))
|
6
|
+
|
7
|
+
describe stack, "#valid_cfn" do
|
8
|
+
it "returns valid cloudformation" do
|
9
|
+
cf = AWS::CloudFormation.new
|
10
|
+
template = stack.to_json
|
11
|
+
result = cf.validate_template(template)
|
12
|
+
result.has_key?(:code).should eq false
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# Define the default *ingress* security rules. Your office IPs and VPN IPs need to be in here
|
3
|
+
#
|
4
|
+
def globals.example_security_group_ingress
|
5
|
+
# Define VPC vs. non-vpc security groups differently
|
6
|
+
if self.respond_to?('no_vpc') && self.no_vpc
|
7
|
+
protocols = [ "tcp", "udp", "icmp" ]
|
8
|
+
from_port = "-1"
|
9
|
+
to_port = "-1"
|
10
|
+
else
|
11
|
+
protocols = [ "-1" ]
|
12
|
+
from_port = "0"
|
13
|
+
to_port = "65535"
|
14
|
+
end
|
15
|
+
|
16
|
+
rules = []
|
17
|
+
protocols.each do |protocol|
|
18
|
+
case protocol
|
19
|
+
when "tcp"
|
20
|
+
from_port = "0"
|
21
|
+
to_port = "65535"
|
22
|
+
when "udp"
|
23
|
+
from_port = "0"
|
24
|
+
to_port = "65535"
|
25
|
+
when "icmp"
|
26
|
+
from_port = "-1"
|
27
|
+
to_port = "-1"
|
28
|
+
when "-1"
|
29
|
+
from_port = "0"
|
30
|
+
to_port = "65535"
|
31
|
+
else
|
32
|
+
# error ?
|
33
|
+
end
|
34
|
+
|
35
|
+
rules += [
|
36
|
+
# Main office IP
|
37
|
+
{ :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => "123.123.123.123/32", },
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
rules
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Defines Example specific parameters and tags
|
2
|
+
# - client
|
3
|
+
# - projects
|
4
|
+
# - environments
|
5
|
+
#
|
6
|
+
# Also defines the globals.example_tags method
|
7
|
+
|
8
|
+
# Client name
|
9
|
+
parameter :client do
|
10
|
+
default globals.client
|
11
|
+
end
|
12
|
+
|
13
|
+
# Project name
|
14
|
+
parameter :project do
|
15
|
+
default globals.project
|
16
|
+
end
|
17
|
+
|
18
|
+
# Environment name
|
19
|
+
parameter :environment do
|
20
|
+
default globals.environment
|
21
|
+
end
|
22
|
+
|
23
|
+
# Output from this method can be passed directly to the tags parameter block
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# resource :name do
|
27
|
+
# type "AWS::EC2::Instance"
|
28
|
+
# properties do
|
29
|
+
# tags globals.example_tags
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
def globals.example_tags
|
33
|
+
{
|
34
|
+
:client => ref(:client),
|
35
|
+
:project => ref(:project),
|
36
|
+
:environment => ref(:environment),
|
37
|
+
}
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Ubuntu Precise (12.04 LTS) Release 20130624 EC2 AMIs for ebs Instance Types
|
2
|
+
# Source: http://cloud-images.ubuntu.com/locator/ec2/
|
3
|
+
|
4
|
+
ami_ids = {}
|
5
|
+
ami_ids["ap-northeast-1"] = {}
|
6
|
+
ami_ids["ap-northeast-1"]["64"] = "ami-51129850"
|
7
|
+
ami_ids["ap-northeast-1"]["32"] = "ami-4b12984a"
|
8
|
+
|
9
|
+
ami_ids["ap-southeast-1"] = {}
|
10
|
+
ami_ids["ap-southeast-1"]["64"] = "ami-a02f66f2"
|
11
|
+
ami_ids["ap-southeast-1"]["32"] = "ami-a22f66f0"
|
12
|
+
|
13
|
+
ami_ids["eu-west-1"] = {}
|
14
|
+
ami_ids["eu-west-1"]["64"] = "ami-89b1a3fd"
|
15
|
+
ami_ids["eu-west-1"]["32"] = "ami-8fb1a3fb"
|
16
|
+
|
17
|
+
ami_ids["sa-east-1"] = {}
|
18
|
+
ami_ids["sa-east-1"]["64"] = "ami-5c7edb41"
|
19
|
+
ami_ids["sa-east-1"]["32"] = "ami-227edb3f"
|
20
|
+
|
21
|
+
ami_ids["us-east-1"] = {}
|
22
|
+
ami_ids["us-east-1"]["64"] = "ami-23d9a94a"
|
23
|
+
ami_ids["us-east-1"]["32"] = "ami-21d9a948"
|
24
|
+
|
25
|
+
ami_ids["us-west-1"] = {}
|
26
|
+
ami_ids["us-west-1"]["64"] = "ami-c4072e81"
|
27
|
+
ami_ids["us-west-1"]["32"] = "ami-3a072e7f"
|
28
|
+
|
29
|
+
ami_ids["ap-southeast-2"] = {}
|
30
|
+
ami_ids["ap-southeast-2"]["64"] = "ami-974ddead"
|
31
|
+
ami_ids["ap-southeast-2"]["32"] = "ami-914ddeab"
|
32
|
+
|
33
|
+
ami_ids["us-west-2"] = {}
|
34
|
+
ami_ids["us-west-2"]["64"] = "ami-fb68f8cb"
|
35
|
+
ami_ids["us-west-2"]["32"] = "ami-f968f8c9"
|
36
|
+
|
37
|
+
mappings do
|
38
|
+
ami_ids_ubuntu_ebs_20130624 ami_ids
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Ubuntu Precise (12.04 LTS) Release 20130624 EC2 AMIs for instance-store Instance Types
|
2
|
+
# Source: http://cloud-images.ubuntu.com/locator/ec2/
|
3
|
+
|
4
|
+
ami_ids = {}
|
5
|
+
ami_ids["ap-northeast-1"] = {}
|
6
|
+
ami_ids["ap-northeast-1"]["64"] = "ami-7d1d977c"
|
7
|
+
ami_ids["ap-northeast-1"]["32"] = "ami-d31c96d2"
|
8
|
+
|
9
|
+
ami_ids["ap-southeast-1"] = {}
|
10
|
+
ami_ids["ap-southeast-1"]["64"] = "ami-b02f66e2"
|
11
|
+
ami_ids["ap-southeast-1"]["32"] = "ami-c22f6690"
|
12
|
+
|
13
|
+
ami_ids["eu-west-1"] = {}
|
14
|
+
ami_ids["eu-west-1"]["64"] = "ami-57b0a223"
|
15
|
+
ami_ids["eu-west-1"]["32"] = "ami-a5b2a0d1"
|
16
|
+
|
17
|
+
ami_ids["sa-east-1"] = {}
|
18
|
+
ami_ids["sa-east-1"]["64"] = "ami-027edb1f"
|
19
|
+
ami_ids["sa-east-1"]["32"] = "ami-ce7fdad3"
|
20
|
+
|
21
|
+
ami_ids["us-east-1"] = {}
|
22
|
+
ami_ids["us-east-1"]["64"] = "ami-d9d6a6b0"
|
23
|
+
ami_ids["us-east-1"]["32"] = "ami-bfd3a3d6"
|
24
|
+
|
25
|
+
ami_ids["us-west-1"] = {}
|
26
|
+
ami_ids["us-west-1"]["64"] = "ami-72072e37"
|
27
|
+
ami_ids["us-west-1"]["32"] = "ami-e6042da3"
|
28
|
+
|
29
|
+
ami_ids["ap-southeast-2"] = {}
|
30
|
+
ami_ids["ap-southeast-2"]["64"] = "ami-934ddea9"
|
31
|
+
ami_ids["ap-southeast-2"]["32"] = "ami-134dde29"
|
32
|
+
|
33
|
+
ami_ids["us-west-2"] = {}
|
34
|
+
ami_ids["us-west-2"]["64"] = "ami-5168f861"
|
35
|
+
ami_ids["us-west-2"]["32"] = "ami-ef67f7df"
|
36
|
+
|
37
|
+
|
38
|
+
mappings do
|
39
|
+
ami_ids_ubuntu_instancestore_20130624 ami_ids
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
mappings do
|
2
|
+
aws_instance_type_to_arch(
|
3
|
+
{
|
4
|
+
"t1.micro"=> {
|
5
|
+
"Arch"=> "64"
|
6
|
+
},
|
7
|
+
"m1.small"=> {
|
8
|
+
"Arch"=> "64"
|
9
|
+
},
|
10
|
+
"m1.medium"=> {
|
11
|
+
"Arch"=> "64"
|
12
|
+
},
|
13
|
+
"m1.large"=> {
|
14
|
+
"Arch"=> "64"
|
15
|
+
},
|
16
|
+
"m1.xlarge"=> {
|
17
|
+
"Arch"=> "64"
|
18
|
+
},
|
19
|
+
"m2.xlarge"=> {
|
20
|
+
"Arch"=> "64"
|
21
|
+
},
|
22
|
+
"m2.2xlarge"=> {
|
23
|
+
"Arch"=> "64"
|
24
|
+
},
|
25
|
+
"m2.4xlarge"=> {
|
26
|
+
"Arch"=> "64"
|
27
|
+
},
|
28
|
+
"c1.medium"=> {
|
29
|
+
"Arch"=> "64"
|
30
|
+
},
|
31
|
+
"c1.xlarge"=> {
|
32
|
+
"Arch"=> "64"
|
33
|
+
}
|
34
|
+
})
|
35
|
+
end
|
data/stacks/example.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'netaddr'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Define some global variables
|
6
|
+
#
|
7
|
+
|
8
|
+
# This variable isn't used anywhere, but provides the perfect example for
|
9
|
+
# using Ruby code in the DSL
|
10
|
+
globals.subnet_class_b = NetAddr::CIDR.create('10.200.0.0/16')
|
11
|
+
|
12
|
+
#
|
13
|
+
globals.client = 'example'
|
14
|
+
globals.project = 'cloud_builder'
|
15
|
+
globals.environment = 'testing'
|
16
|
+
|
17
|
+
#
|
18
|
+
# We will not be using a vpc;
|
19
|
+
#
|
20
|
+
globals.no_vpc = true
|
21
|
+
|
22
|
+
#
|
23
|
+
# Include bricks
|
24
|
+
#
|
25
|
+
include_brick :example_tags
|
26
|
+
include_brick :example_security_groups
|
27
|
+
|
28
|
+
include_brick "mappings/ami_ids_ubuntu_ebs_20130624"
|
29
|
+
include_brick "mappings/instance2arch"
|
30
|
+
|
31
|
+
#
|
32
|
+
# Begin the actual template descriptions
|
33
|
+
#
|
34
|
+
description "%s/%s/%s" % [globals.client, globals.project, globals.environment]
|
35
|
+
template_version "2010-09-09"
|
36
|
+
|
37
|
+
|
38
|
+
# ssh key name that will be used
|
39
|
+
parameter :key_name do
|
40
|
+
default :example
|
41
|
+
end
|
42
|
+
|
43
|
+
parameter :example_instance_type do
|
44
|
+
default "m1.small"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Security group for the example instance
|
48
|
+
resource "example_instance_security_group" do
|
49
|
+
type "AWS::EC2::SecurityGroup"
|
50
|
+
properties do
|
51
|
+
group_description "example security group"
|
52
|
+
security_group_ingress globals.example_security_group_ingress + [
|
53
|
+
{
|
54
|
+
:ip_protocol => "tcp",
|
55
|
+
:from_port => "8080",
|
56
|
+
:to_port => "8080",
|
57
|
+
:cidr_ip => "0.0.0.0/0",
|
58
|
+
}
|
59
|
+
]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# EC2 instance declaration
|
64
|
+
resource "example_instance" do
|
65
|
+
type "AWS::EC2::Instance"
|
66
|
+
properties do
|
67
|
+
key_name ref(:key_name)
|
68
|
+
image_id ami_ids_ubuntu_ebs_20130624[ref("AWS::Region")][ aws_instance_type_to_arch[ref(:example_instance_type)]["Arch"] ]
|
69
|
+
|
70
|
+
|
71
|
+
security_group_ids [ ref(:example_instance_security_group) ]
|
72
|
+
|
73
|
+
instance_type ref(:example_instance_type)
|
74
|
+
|
75
|
+
monitoring true
|
76
|
+
tags globals.example_tags
|
77
|
+
tags :function => "example"
|
78
|
+
tags :name => "%s-%s-%s-%s" % [globals.client, globals.project, globals.environment, "example"]
|
79
|
+
end
|
80
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloud_builder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
version: 0.0.6
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Sorin Stoiana
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2013-09-19 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: netaddr
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: rspec
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 2
|
41
|
+
- 6
|
42
|
+
version: "2.6"
|
43
|
+
type: :development
|
44
|
+
version_requirements: *id002
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: clamp
|
47
|
+
prerelease: false
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
type: :runtime
|
56
|
+
version_requirements: *id003
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: json
|
59
|
+
prerelease: false
|
60
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id004
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-sdk
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
type: :runtime
|
80
|
+
version_requirements: *id005
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: activesupport
|
83
|
+
prerelease: false
|
84
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
type: :runtime
|
92
|
+
version_requirements: *id006
|
93
|
+
description: Generate JSON config for AWS CloudFormation using a Ruby based DSL
|
94
|
+
email:
|
95
|
+
- sstoiana@optaros.com
|
96
|
+
executables:
|
97
|
+
- stack
|
98
|
+
extensions: []
|
99
|
+
|
100
|
+
extra_rdoc_files: []
|
101
|
+
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- .travis.yml
|
105
|
+
- Gemfile
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- bin/stack
|
110
|
+
- cloud_builder.gemspec
|
111
|
+
- lib/cloud_builder.rb
|
112
|
+
- lib/cloud_builder/brick.rb
|
113
|
+
- lib/cloud_builder/cli.rb
|
114
|
+
- lib/cloud_builder/dontformatunderscore.rb
|
115
|
+
- lib/cloud_builder/dsl.rb
|
116
|
+
- lib/cloud_builder/dslostruct.rb
|
117
|
+
- lib/cloud_builder/jsonable.rb
|
118
|
+
- lib/cloud_builder/mappings.rb
|
119
|
+
- lib/cloud_builder/output.rb
|
120
|
+
- lib/cloud_builder/parameter.rb
|
121
|
+
- lib/cloud_builder/reference.rb
|
122
|
+
- lib/cloud_builder/resource.rb
|
123
|
+
- lib/cloud_builder/stack.rb
|
124
|
+
- lib/cloud_builder/version.rb
|
125
|
+
- spec/example_spec.rb
|
126
|
+
- stacks/bricks/example_security_groups.rb
|
127
|
+
- stacks/bricks/example_tags.rb
|
128
|
+
- stacks/bricks/mappings/ami_ids_ubuntu_ebs_20130624.rb
|
129
|
+
- stacks/bricks/mappings/ami_ids_ubuntu_instancestore_20130624.rb
|
130
|
+
- stacks/bricks/mappings/instance2arch.rb
|
131
|
+
- stacks/example.rb
|
132
|
+
has_rdoc: true
|
133
|
+
homepage: https://github.com/Optaros/cloud_builder
|
134
|
+
licenses: []
|
135
|
+
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
segments:
|
153
|
+
- 0
|
154
|
+
version: "0"
|
155
|
+
requirements: []
|
156
|
+
|
157
|
+
rubyforge_project:
|
158
|
+
rubygems_version: 1.3.6
|
159
|
+
signing_key:
|
160
|
+
specification_version: 3
|
161
|
+
summary: Generate JSON config for AWS CloudFormation
|
162
|
+
test_files:
|
163
|
+
- spec/example_spec.rb
|