terraframe 0.0.5
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/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +2 -0
- data/bin/terraframe +32 -0
- data/lib/terraframe.rb +2 -0
- data/lib/terraframe/context.rb +10 -0
- data/lib/terraframe/contexts/aws_context.rb +20 -0
- data/lib/terraframe/processor.rb +64 -0
- data/lib/terraframe/provider.rb +6 -0
- data/lib/terraframe/resource.rb +9 -0
- data/lib/terraframe/script_item.rb +36 -0
- data/lib/terraframe/state.rb +96 -0
- data/lib/terraframe/version.rb +3 -0
- data/terraframe.gemspec +28 -0
- data/test/aws_tests.rb +0 -0
- data/test/basic_tests.rb +0 -0
- data/test/scripts/aws.terraframe +12 -0
- data/test/scripts/aws_vars.yaml +2 -0
- data/test/scripts/basic.terraframe +0 -0
- data/test/scripts/basic_vars.yaml +2 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 69c298bb5fae6f55bd0926b9f6ee7d51317a932c
|
4
|
+
data.tar.gz: 1e27ef8d075df5f45a8f32b0bc6790b303c575d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 494647a04c86977f4652244a39984e201693628303619122bd50584a73e80c19c350b0e3c6df1392318de2de5829e8247f114e7b83bffd3dcb652986468b1da2
|
7
|
+
data.tar.gz: 4a5b5829ce32c10cf1f39e4e72b77246ada761a612ec5fe2da3f86fe5fa153e532f42d152c49bb1984639fe11839b3ea56f68ccd7fe0067e32dd2c21d140ea92
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ed Ropple
|
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,60 @@
|
|
1
|
+
# Terraframe #
|
2
|
+
Terraframe is a processor for a domain-specific language that outputs to the Terraform specification format.
|
3
|
+
|
4
|
+
[Terraform][1] is a cool infrastructure-as-code system with a boatload of functionality and a really awesome core that makes building out entire clouds on AWS super easy and super fun. I am a fan.
|
5
|
+
|
6
|
+
_But_. But but but. It's not perfect. And personally, ever since HashiCorp went away from Ruby DSLs as configuration, I have been sad. And worse than sad, I have been unproductive as all hell. I'm just not satisfied with the state of the Terraform description language. It's hard to write, its built-in assumptions are gross (the handling of variables is a minor crime in progress), and it's just a huge step back from being able to deploy, say, a Vagrant instance--or, as I have done, [a configurable number of Vagrant instances][2]--in a nice, comprehensible manner.
|
7
|
+
|
8
|
+
The configuration, while not CloudFormation-bad, is pretty bad, and I came close to ditching Terraform because it was really hard to write. I got halfway through some ERB templating monstrosity before I learned of a better way: Terraform supports JSON as a declaration notation, and that makes it really easy to build an external DSL that can be exported for use in Terraform.
|
9
|
+
|
10
|
+
## Installation ##
|
11
|
+
Terraframe is distributed as a RubyGem.
|
12
|
+
|
13
|
+
```bash
|
14
|
+
gem install terraframe
|
15
|
+
```
|
16
|
+
|
17
|
+
## Usage ##
|
18
|
+
1. You'll need to have [Terraform][1] installed to actually use the output of Terraframe.
|
19
|
+
2. Check `terraframe --help` for exhaustive usage details.
|
20
|
+
|
21
|
+
## Syntax ##
|
22
|
+
For the most part, the Terraframe syntax directly parallels the Terraform syntax, but has been Rubified. At present, most of this is a wrapper around `method_missing`, and so it's a _little_ rocky when dealing with nested data types.
|
23
|
+
|
24
|
+
You can easily wire up outputs via `id_of(resource_type, resource_name)` and `output_of(resource_type, resource_name, output_name)`, to make things a little less crazy.
|
25
|
+
|
26
|
+
Variables can be passed in via the `-v` flag in as many YAML files (which will be deep-merged) as you would like. They are exposed to scripts via the `vars` hash.
|
27
|
+
|
28
|
+
Examples: TBD. To get you started, here's the supported invocations:
|
29
|
+
|
30
|
+
- `provider :provider_type {}`
|
31
|
+
- `resource :resource_type, "resource_name" {}`
|
32
|
+
- `resource_type "resource_name {}`
|
33
|
+
|
34
|
+
The latter deserves special attention, because any attempted invocation other than `provider`, `variable`, `resource`, or `provisioner` will be interpreted as a resource. (`resource :resource_type, "resource_name"` is supported for people who like the Terraform syntax.)
|
35
|
+
|
36
|
+
## Future Work ##
|
37
|
+
Right now, Terraframe is being extended as I need it. Pull requests very gratefully accepted for
|
38
|
+
|
39
|
+
- Variable interpolation in YAML variable files (or possibly Ruby variable files that must emit a hash, a la Chef). This will be soon, I'll need it.
|
40
|
+
- Supporting `variable` and `provisioner` blocks, neither are hard but they have to get done.
|
41
|
+
- Script linting (checking for id existence, only allowing valid keys, etc.) before starting up Terraform. Very low priority, as that's what Terraform itself does.
|
42
|
+
- Test coverage.
|
43
|
+
|
44
|
+
## Contributing ##
|
45
|
+
1. Fork it ( https://github.com/eropple/terraframe/fork )
|
46
|
+
2. Create your feature branch under the `feature/` prefix, as with [git-flow][3] (`git flow feature start my-new-feature`)
|
47
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
48
|
+
4. Push to the branch (`git push origin feature/my-new-feature`). Please don't change the version number and please make README changes in a separate commit to make everything comprehensible for me.
|
49
|
+
5. Make a pull request!
|
50
|
+
|
51
|
+
## Thanks ##
|
52
|
+
- My employer, [Leaf][4], for encouraging the development and use of Terraframe. ([We're hiring!][5])
|
53
|
+
- William Lee, my platform engineering co-conspirator at Leaf.
|
54
|
+
- HashiCorp, 'cause Terraform is fundamentally an awesome project and we're all better because you guys made this.
|
55
|
+
|
56
|
+
[1]: https://www.terraform.io
|
57
|
+
[2]: http://edcanhack.com/2014/07/a-virtual-mesos-cluster-with-vagrant-and-chef/
|
58
|
+
[3]: https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow
|
59
|
+
[4]: http://engineering.leaf.me
|
60
|
+
[5]: mailto:eropple+hiring@leaf.me
|
data/Rakefile
ADDED
data/bin/terraframe
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'logger'
|
7
|
+
require 'trollop'
|
8
|
+
require 'terraframe'
|
9
|
+
require 'awesome_print'
|
10
|
+
|
11
|
+
opts = Trollop::options do
|
12
|
+
opt :input_file, "Input file(s) to process into a Terraform script.",
|
13
|
+
:short => "f", :type => :string, :multi => true, :required => true
|
14
|
+
opt :variable_file, "Variable file (YAML or JSON, not tfvars!).",
|
15
|
+
:short => "v", :type => :string, :multi => true
|
16
|
+
opt :pretty_print, "Pretty-prints the Terraform output.", :default => true
|
17
|
+
opt :verbose, "Increases logging verbosity.", :default => false
|
18
|
+
end
|
19
|
+
|
20
|
+
processor = Terraframe::Processor.new
|
21
|
+
if opts[:verbose]
|
22
|
+
processor.logger.level = Logger::DEBUG
|
23
|
+
end
|
24
|
+
processor.logger.debug opts.inspect
|
25
|
+
|
26
|
+
output = processor.process_files(opts[:input_file], opts[:variable_file] || [])
|
27
|
+
if opts[:pretty_print]
|
28
|
+
output = JSON.pretty_generate(JSON.parse(output))
|
29
|
+
end
|
30
|
+
|
31
|
+
processor.logger.info "Writing output to stdout."
|
32
|
+
puts output
|
data/lib/terraframe.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'terraframe/context'
|
2
|
+
require 'terraframe/provider'
|
3
|
+
|
4
|
+
module Terraframe
|
5
|
+
module Contexts
|
6
|
+
class AWSContext < Context
|
7
|
+
RESOURCES = [
|
8
|
+
:aws_instance
|
9
|
+
]
|
10
|
+
|
11
|
+
def provider_type
|
12
|
+
Terraframe::Provider
|
13
|
+
end
|
14
|
+
|
15
|
+
def resources
|
16
|
+
RESOURCES
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require 'active_support/core_ext/hash'
|
6
|
+
require 'awesome_print'
|
7
|
+
|
8
|
+
require 'terraframe/state'
|
9
|
+
require 'terraframe/contexts/aws_context'
|
10
|
+
|
11
|
+
module Terraframe
|
12
|
+
class Processor
|
13
|
+
attr_reader :logger
|
14
|
+
attr_reader :contexts
|
15
|
+
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@logger = Logger.new($stderr)
|
19
|
+
logger.level = Logger::INFO
|
20
|
+
|
21
|
+
logger.debug "Logger initialized."
|
22
|
+
|
23
|
+
@contexts = {}
|
24
|
+
register_context(:aws, Terraframe::Contexts::AWSContext.new)
|
25
|
+
end
|
26
|
+
|
27
|
+
def register_context(name, context)
|
28
|
+
name = name.to_sym
|
29
|
+
if @contexts[name]
|
30
|
+
logger.warn "A context with the name '#{name}' has been registered more than once."
|
31
|
+
end
|
32
|
+
@contexts[name] = context
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_files(scripts, variables)
|
36
|
+
scripts = scripts.map { |f| File.expand_path(f) }
|
37
|
+
variables = variables.map { |f| File.expand_path(f) }
|
38
|
+
|
39
|
+
missing_scripts = scripts.reject { |f| File.exist?(f) }
|
40
|
+
missing_variables = variables.reject { |f| File.exist?(f) }
|
41
|
+
unless missing_scripts.empty? && missing_variables.empty?
|
42
|
+
missing_scripts.each { |f| logger.fatal "Script file not found: #{f}" }
|
43
|
+
missing_variables.each { |f| logger.fatal "Variable file not found: #{f}" }
|
44
|
+
raise "One or more specified files were missing."
|
45
|
+
end
|
46
|
+
|
47
|
+
apply(Hash[scripts.zip(scripts.map { |f| IO.read(f) })], load_variables(variables))
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_variables(variables)
|
51
|
+
vars = {}
|
52
|
+
variables.each { |f| vars = vars.deep_merge(YAML::load_file(f)) }
|
53
|
+
vars
|
54
|
+
end
|
55
|
+
|
56
|
+
def apply(inputs, vars)
|
57
|
+
logger.info "Beginning state execution."
|
58
|
+
|
59
|
+
state = State.new(logger, vars, @contexts)
|
60
|
+
inputs.each { |input| state.__apply_script(input[0], input[1])}
|
61
|
+
state.__build()
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Terraframe
|
4
|
+
class ScriptItem
|
5
|
+
attr_reader :fields
|
6
|
+
attr_reader :vars
|
7
|
+
|
8
|
+
def initialize(vars, &block)
|
9
|
+
@fields = {}
|
10
|
+
@vars = vars
|
11
|
+
|
12
|
+
instance_eval &block
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_json(*a)
|
16
|
+
@fields.to_json(*a)
|
17
|
+
end
|
18
|
+
|
19
|
+
## DSL FUNCTIONS BELOW
|
20
|
+
def method_missing(method_name, *args, &block)
|
21
|
+
if args.length == 1
|
22
|
+
@fields[method_name.to_sym] = args[0]
|
23
|
+
else
|
24
|
+
raise "Multiple fields passed to a scalar auto-argument '#{method_name}'."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def output_of(resource_type, resource_name, output_type)
|
30
|
+
"${#{resource_type}.#{resource_name}.#{output_type}}"
|
31
|
+
end
|
32
|
+
def id_of(resource_type, resource_name)
|
33
|
+
output_of(resource_type, resource_name, :id)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'recursive_open_struct'
|
3
|
+
|
4
|
+
module Terraframe
|
5
|
+
class State
|
6
|
+
attr_reader :vars
|
7
|
+
attr_reader :logger
|
8
|
+
|
9
|
+
def initialize(logger, vars, contexts)
|
10
|
+
@logger = logger
|
11
|
+
logger.info "Initializing state."
|
12
|
+
|
13
|
+
@vars = RecursiveOpenStruct.new(vars, :recurse_over_arrays => true )
|
14
|
+
logger.debug "State variables:"
|
15
|
+
logger.ap vars, :debug
|
16
|
+
|
17
|
+
@__contexts = contexts
|
18
|
+
|
19
|
+
@__output = {
|
20
|
+
:provider => {},
|
21
|
+
:variable => {},
|
22
|
+
:resource => {}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def __build()
|
27
|
+
logger.info "Building Terraform script from state."
|
28
|
+
logger.debug "Contexts:"
|
29
|
+
@__contexts.each { |c| logger.debug " - #{c}" }
|
30
|
+
@__output.to_json
|
31
|
+
end
|
32
|
+
|
33
|
+
def __apply_script(script_name, script)
|
34
|
+
logger.info "Applying script '#{script_name}' to state."
|
35
|
+
instance_eval(script, script_name, 0)
|
36
|
+
logger.info "Script '#{script_name}' applied successfully."
|
37
|
+
end
|
38
|
+
|
39
|
+
## DSL FUNCTIONS BELOW ##
|
40
|
+
def provider(type, &block)
|
41
|
+
if !@__contexts[type]
|
42
|
+
msg = "Unknown provider type: '#{type}'."
|
43
|
+
logger.fatal msg
|
44
|
+
raise msg
|
45
|
+
end
|
46
|
+
|
47
|
+
if @__output[:provider][type]
|
48
|
+
msg = "Duplicate provider type (sorry, blame Terraform): '#{type}'"
|
49
|
+
logger.fatal msg
|
50
|
+
raise msg
|
51
|
+
end
|
52
|
+
|
53
|
+
provider = @__contexts[type].provider_type.new(vars, &block)
|
54
|
+
logger.debug "Provider of type '#{type}': #{provider.inspect}"
|
55
|
+
@__output[:provider][type] = provider
|
56
|
+
|
57
|
+
provider
|
58
|
+
end
|
59
|
+
|
60
|
+
def variable
|
61
|
+
msg = "TODO: implement tfvar support."
|
62
|
+
logger.fatal msg
|
63
|
+
raise msg
|
64
|
+
end
|
65
|
+
|
66
|
+
def provisioner
|
67
|
+
msg = "TODO: implement provisioner support."
|
68
|
+
logger.fatal msg
|
69
|
+
raise msg
|
70
|
+
end
|
71
|
+
|
72
|
+
def resource(resource_type, resource_name, &block)
|
73
|
+
unless @__contexts.any? { |k, v| v.resources.include?(resource_type) }
|
74
|
+
logger.warn "Could not find a context that supports resource type '#{resource_type}'. Continuing, but you've been warned."
|
75
|
+
end
|
76
|
+
|
77
|
+
@__output[:resource][resource_type] ||= {}
|
78
|
+
@__output[:resource][resource_type][resource_name.to_s] = Resource.new(vars, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
# anything that is not a provider or a variable should be interpreted
|
82
|
+
def method_missing(method_name, *args, &block)
|
83
|
+
case method_name
|
84
|
+
when "vars"
|
85
|
+
@vars
|
86
|
+
else
|
87
|
+
if (args.length != 1)
|
88
|
+
msg = "Too many arguments for resource invocation '#{method_name}'."
|
89
|
+
logger.fatal(msg)
|
90
|
+
raise msg
|
91
|
+
end
|
92
|
+
resource(method_name.to_sym, args[0], &block)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/terraframe.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'terraframe/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "terraframe"
|
8
|
+
spec.version = Terraframe::VERSION
|
9
|
+
spec.authors = ["Ed Ropple"]
|
10
|
+
spec.email = ["ed@edropple.com"]
|
11
|
+
spec.summary = "A sane Ruby-based DSL for emitting Terraform scripts."
|
12
|
+
# spec.description = %q{TODO: Write a longer description. Optional.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "trollop", "~> 2.0"
|
25
|
+
spec.add_runtime_dependency "activesupport", "~> 4.2.0"
|
26
|
+
spec.add_runtime_dependency "awesome_print", "~> 1.6.1"
|
27
|
+
spec.add_runtime_dependency "recursive-open-struct", "~> 0.5.0"
|
28
|
+
end
|
data/test/aws_tests.rb
ADDED
File without changes
|
data/test/basic_tests.rb
ADDED
File without changes
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: terraframe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ed Ropple
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: trollop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.2.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.2.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: awesome_print
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.6.1
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.6.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: recursive-open-struct
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.5.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.5.0
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- ed@edropple.com
|
100
|
+
executables:
|
101
|
+
- terraframe
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- bin/terraframe
|
111
|
+
- lib/terraframe.rb
|
112
|
+
- lib/terraframe/context.rb
|
113
|
+
- lib/terraframe/contexts/aws_context.rb
|
114
|
+
- lib/terraframe/processor.rb
|
115
|
+
- lib/terraframe/provider.rb
|
116
|
+
- lib/terraframe/resource.rb
|
117
|
+
- lib/terraframe/script_item.rb
|
118
|
+
- lib/terraframe/state.rb
|
119
|
+
- lib/terraframe/version.rb
|
120
|
+
- terraframe.gemspec
|
121
|
+
- test/aws_tests.rb
|
122
|
+
- test/basic_tests.rb
|
123
|
+
- test/scripts/aws.terraframe
|
124
|
+
- test/scripts/aws_vars.yaml
|
125
|
+
- test/scripts/basic.terraframe
|
126
|
+
- test/scripts/basic_vars.yaml
|
127
|
+
homepage: ''
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.4.5
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: A sane Ruby-based DSL for emitting Terraform scripts.
|
151
|
+
test_files:
|
152
|
+
- test/aws_tests.rb
|
153
|
+
- test/basic_tests.rb
|
154
|
+
- test/scripts/aws.terraframe
|
155
|
+
- test/scripts/aws_vars.yaml
|
156
|
+
- test/scripts/basic.terraframe
|
157
|
+
- test/scripts/basic_vars.yaml
|