cloudshaper 0.0.4
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 +4 -0
- data/.travis.yml +3 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +27 -0
- data/LICENSE +23 -0
- data/README.md +162 -0
- data/Rakefile +9 -0
- data/TODO.md +7 -0
- data/examples/secretconfig/README.md +3 -0
- data/examples/secretconfig/atlas.json +5 -0
- data/examples/secretconfig/aws.json +6 -0
- data/examples/secretconfig/cloudflare.json +6 -0
- data/examples/secretconfig/cloudstack.json +7 -0
- data/examples/secretconfig/digitalocean.json +5 -0
- data/examples/secretconfig/dme.json +6 -0
- data/examples/secretconfig/heroku.json +6 -0
- data/examples/secretconfig/mailgun.json +5 -0
- data/examples/simple_app.rb +61 -0
- data/lib/tasks/tasks.rb +12 -0
- data/lib/tasks/terraform.rake +127 -0
- data/lib/terraform_dsl.rb +6 -0
- data/lib/terraform_dsl/aws/remote_s3.rb +20 -0
- data/lib/terraform_dsl/aws/tagging.rb +23 -0
- data/lib/terraform_dsl/command.rb +58 -0
- data/lib/terraform_dsl/module.rb +38 -0
- data/lib/terraform_dsl/output.rb +6 -0
- data/lib/terraform_dsl/provider.rb +13 -0
- data/lib/terraform_dsl/remote.rb +31 -0
- data/lib/terraform_dsl/resource.rb +44 -0
- data/lib/terraform_dsl/secrets.rb +29 -0
- data/lib/terraform_dsl/stack.rb +79 -0
- data/lib/terraform_dsl/stack_element.rb +62 -0
- data/lib/terraform_dsl/stack_module.rb +121 -0
- data/lib/terraform_dsl/stack_modules.rb +24 -0
- data/lib/terraform_dsl/stacks.rb +64 -0
- data/lib/terraform_dsl/variable.rb +6 -0
- data/lib/terraform_dsl/version.rb +3 -0
- data/terraform_dsl.gemspec +25 -0
- data/test/stack_module_test.rb +152 -0
- data/test/stack_test.rb +5 -0
- data/test/test_helper.rb +4 -0
- metadata +131 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Terraform
|
2
|
+
# Stack module factory, register a module and provide clones of it
|
3
|
+
class StackModules
|
4
|
+
class ModuleNotFound < StandardError; end
|
5
|
+
class ModuleAlreadyRegistered < StandardError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def register(name, stack_module)
|
9
|
+
fail ModuleAlreadyRegistered, "#{name} is already a registered stack_module" if @stack_modules.key?(name.downcase)
|
10
|
+
@stack_modules[name.downcase] = stack_module
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(stack_module_name)
|
14
|
+
fail ModuleNotFound, "#{stack_module_name} module module not found" unless @stack_modules.key?(stack_module_name.downcase)
|
15
|
+
@stack_modules[stack_module_name.downcase].clone
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset!
|
19
|
+
@stack_modules ||= {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
reset!
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
require 'terraform_dsl/stack'
|
5
|
+
|
6
|
+
module Terraform
|
7
|
+
# Singleton to keep track of stack templates
|
8
|
+
class Stacks
|
9
|
+
class MalformedConfig < StandardError; end
|
10
|
+
class << self
|
11
|
+
attr_reader :stacks
|
12
|
+
|
13
|
+
def load
|
14
|
+
config = ENV['STACK_CONFIG'] || 'stacks.yml'
|
15
|
+
fail 'stacks.yml must exist in root directory, or specify STACK_CONFIG pointing to stacks.yml' unless File.exist?(config)
|
16
|
+
stack_specs = YAML.load(File.read(config))
|
17
|
+
fail MalformedConfig, 'Stacks must be an array' unless stack_specs.key?('stacks') && stack_specs['stacks'].is_a?(Array)
|
18
|
+
common = stack_specs['common'] || {}
|
19
|
+
stack_specs['stacks'].each do |stack_spec|
|
20
|
+
stack = Stack.load(stack_spec.merge(common))
|
21
|
+
@stacks[stack.name] = stack
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def init
|
26
|
+
config = ENV['STACK_CONFIG'] || 'stacks.yml'
|
27
|
+
fail "stacks.yaml already exists at #{File.expand_path(config)}" if File.exist?(config)
|
28
|
+
File.open(config, 'w') do |f|
|
29
|
+
f.write(YAML.dump(base_config))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def uuid
|
34
|
+
"#{Time.now.utc.to_i}_#{SecureRandom.urlsafe_base64(6)}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def base_config
|
38
|
+
{
|
39
|
+
'common' => {},
|
40
|
+
'stacks' => [base_stack_config]
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def base_stack_config
|
45
|
+
{
|
46
|
+
'name' => 'SET_NAME',
|
47
|
+
'uuid' => uuid,
|
48
|
+
'description' => 'SET_A_DESCRIPTION',
|
49
|
+
'root' => 'SET_A_TEMPLATE',
|
50
|
+
'variables' => {}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset!
|
55
|
+
@stacks ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def dir
|
59
|
+
File.expand_path(File.join(ENV['TERRAFORM_DATA_DIR'] || 'data', 'stacks'))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
reset!
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'terraform_dsl/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'cloudshaper'
|
7
|
+
spec.version = Terraform::VERSION
|
8
|
+
spec.summary = 'Wrap hashicorps "terraform" in a ruby DSL for managing stack templates'
|
9
|
+
spec.description = 'Terraform DSL provides a syntax for managing terraform infrastructure entirely in git'
|
10
|
+
spec.authors = ['Dale Hamel']
|
11
|
+
spec.email = 'dale.hamel@srvthe.net'
|
12
|
+
spec.files = Dir['lib/**/*']
|
13
|
+
spec.homepage = 'https://rubygems.org/gems/terraform_dsl'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
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_runtime_dependency 'rake', '~> 10.4'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'minitest', '~> 5.6'
|
25
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class StackModuleTest < Minitest::Test
|
4
|
+
include Terraform
|
5
|
+
|
6
|
+
def test_multiple_instantiations_of_module
|
7
|
+
StackModule.define 'factory_instantiation_test' do
|
8
|
+
variable(:ports) { default '22' }
|
9
|
+
resource 'aws_security_group', :a do
|
10
|
+
get(:ports).split(',').each do |port|
|
11
|
+
ingress { from_port port }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
first = StackModules.get('factory_instantiation_test')
|
17
|
+
second = StackModules.get('factory_instantiation_test')
|
18
|
+
|
19
|
+
first.build(ports: '80')
|
20
|
+
second.build(ports: '443')
|
21
|
+
|
22
|
+
sg_first = first.elements[:resource][:aws_security_group][:a]
|
23
|
+
sg_second = second.elements[:resource][:aws_security_group][:a]
|
24
|
+
|
25
|
+
assert_equal '80', sg_first[:ingress].fetch(:from_port)
|
26
|
+
assert_equal '443', sg_second[:ingress].fetch(:from_port)
|
27
|
+
end
|
28
|
+
|
29
|
+
# it 'should register variables with default values' do
|
30
|
+
# mod = StackModule.define('variable_register_default') { variable(:name) { default 'default' } }
|
31
|
+
# mod.build
|
32
|
+
|
33
|
+
# expect(mod.variables).to be_a(Hash)
|
34
|
+
# expect(mod.variables).to include(:name)
|
35
|
+
# expect(mod.variables[:name]).to be_a(Hash)
|
36
|
+
# expect(mod.variables[:name]).to include(:default)
|
37
|
+
# expect(mod.variables[:name][:default]).to eq('default')
|
38
|
+
# end
|
39
|
+
|
40
|
+
# it 'should register variables without default values' do
|
41
|
+
# mod = StackModule.define('variable_register_nodefault') { variable(:name) {} }
|
42
|
+
# mod.build
|
43
|
+
|
44
|
+
# expect(mod.variables).to be_a(Hash)
|
45
|
+
# expect(mod.variables).to include(:name)
|
46
|
+
# expect(mod.variables[:name]).to be_a(Hash)
|
47
|
+
# expect(mod.variables[:name]).to include(:default)
|
48
|
+
# expect(mod.variables[:name][:default]).to eq('')
|
49
|
+
# end
|
50
|
+
|
51
|
+
# it 'should accept variables at runtime' do
|
52
|
+
# mod = StackModule.define('variable_override') { variable(:name) { default 'default' } }
|
53
|
+
# mod.build(name: 'not-default')
|
54
|
+
|
55
|
+
# expect(mod.variables[:name][:default]).to eql('not-default')
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
def test_register_resource
|
60
|
+
mod = StackModule.define('register_resource') { resource('aws_instance', :a) { default 'default' } }
|
61
|
+
mod.build
|
62
|
+
|
63
|
+
instance = mod.elements.fetch(:resource).fetch(:aws_instance).fetch(:a)
|
64
|
+
assert_equal 'default', instance.fetch(:default)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_register_resource_with_connections
|
68
|
+
mod = StackModule.define 'register_connection_test' do
|
69
|
+
resource 'aws_instance', :a do
|
70
|
+
connection do
|
71
|
+
user 'root'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
mod.build
|
76
|
+
|
77
|
+
instance = mod.elements.fetch(:resource).fetch(:aws_instance).fetch(:a)
|
78
|
+
assert_equal 'root', instance.fetch(:connection).fetch(:user)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_register_resource_with_provisioners_with_connections
|
82
|
+
mod = StackModule.define 'register_provision_connection_test' do
|
83
|
+
resource 'aws_instance', :a do
|
84
|
+
provisioner 'file' do
|
85
|
+
connection do
|
86
|
+
user 'root'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
mod.build
|
92
|
+
|
93
|
+
instance = mod.elements.fetch(:resource).fetch(:aws_instance).fetch(:a)
|
94
|
+
provisioner = instance.fetch(:provisioner).first
|
95
|
+
connection = provisioner.fetch(:file).fetch(:connection)
|
96
|
+
assert_equal 'root', connection.fetch(:user)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_group_attributes_into_arrays
|
100
|
+
mod = StackModule.define 'resource_scalar_variable_groups' do
|
101
|
+
resource 'aws_security_group', :a do
|
102
|
+
ingress { from_port 80 }
|
103
|
+
ingress { from_port 443 }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
mod.build
|
107
|
+
|
108
|
+
sg = mod.elements.fetch(:resource).fetch(:aws_security_group).fetch(:a)
|
109
|
+
ingress = sg.fetch(:ingress)
|
110
|
+
|
111
|
+
assert_kind_of Array, ingress
|
112
|
+
assert_equal [{from_port: 80}, {from_port: 443}], ingress
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_support_overriding_attributes
|
116
|
+
mod = StackModule.define 'resource_overriden_runtime_variable' do
|
117
|
+
variable(:ports) { default '22' }
|
118
|
+
resource 'aws_security_group', :a do
|
119
|
+
get(:ports).split(',').each do |port|
|
120
|
+
ingress { from_port port }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
mod.build(ports: '22,80,443')
|
125
|
+
|
126
|
+
|
127
|
+
sg = mod.elements.fetch(:resource).fetch(:aws_security_group).fetch(:a)
|
128
|
+
ingress = sg.fetch(:ingress)
|
129
|
+
assert_equal [{from_port: "22"}, {from_port: "80"}, {from_port: "443"}], ingress
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# it 'it should be able to access overridden default variables at runtime' do
|
134
|
+
# mod = StackModule.define 'resource_overriden_runtime_variable' do
|
135
|
+
# variable(:ports) { default '22' }
|
136
|
+
# resource 'aws_security_group', :a do
|
137
|
+
# get(:ports).split(',').each do |port|
|
138
|
+
# ingress { from_port port }
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
|
143
|
+
# mod.build(ports: '22,80,443')
|
144
|
+
|
145
|
+
# sg = mod.elements[:resource][:aws_security_group][:a]
|
146
|
+
# expect(sg).to include(:ingress)
|
147
|
+
# expect(sg[:ingress]).to be_a(Array)
|
148
|
+
# expect(sg[:ingress].first).to eq(from_port: '22')
|
149
|
+
# expect(sg[:ingress].last).to eq(from_port: '443')
|
150
|
+
# end
|
151
|
+
# end
|
152
|
+
end
|
data/test/stack_test.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudshaper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dale Hamel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.6'
|
55
|
+
description: Terraform DSL provides a syntax for managing terraform infrastructure
|
56
|
+
entirely in git
|
57
|
+
email: dale.hamel@srvthe.net
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".travis.yml"
|
64
|
+
- Gemfile
|
65
|
+
- Gemfile.lock
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- TODO.md
|
70
|
+
- examples/secretconfig/README.md
|
71
|
+
- examples/secretconfig/atlas.json
|
72
|
+
- examples/secretconfig/aws.json
|
73
|
+
- examples/secretconfig/cloudflare.json
|
74
|
+
- examples/secretconfig/cloudstack.json
|
75
|
+
- examples/secretconfig/digitalocean.json
|
76
|
+
- examples/secretconfig/dme.json
|
77
|
+
- examples/secretconfig/heroku.json
|
78
|
+
- examples/secretconfig/mailgun.json
|
79
|
+
- examples/simple_app.rb
|
80
|
+
- lib/tasks/tasks.rb
|
81
|
+
- lib/tasks/terraform.rake
|
82
|
+
- lib/terraform_dsl.rb
|
83
|
+
- lib/terraform_dsl/aws/remote_s3.rb
|
84
|
+
- lib/terraform_dsl/aws/tagging.rb
|
85
|
+
- lib/terraform_dsl/command.rb
|
86
|
+
- lib/terraform_dsl/module.rb
|
87
|
+
- lib/terraform_dsl/output.rb
|
88
|
+
- lib/terraform_dsl/provider.rb
|
89
|
+
- lib/terraform_dsl/remote.rb
|
90
|
+
- lib/terraform_dsl/resource.rb
|
91
|
+
- lib/terraform_dsl/secrets.rb
|
92
|
+
- lib/terraform_dsl/stack.rb
|
93
|
+
- lib/terraform_dsl/stack_element.rb
|
94
|
+
- lib/terraform_dsl/stack_module.rb
|
95
|
+
- lib/terraform_dsl/stack_modules.rb
|
96
|
+
- lib/terraform_dsl/stacks.rb
|
97
|
+
- lib/terraform_dsl/variable.rb
|
98
|
+
- lib/terraform_dsl/version.rb
|
99
|
+
- terraform_dsl.gemspec
|
100
|
+
- test/stack_module_test.rb
|
101
|
+
- test/stack_test.rb
|
102
|
+
- test/test_helper.rb
|
103
|
+
homepage: https://rubygems.org/gems/terraform_dsl
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.4.6
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Wrap hashicorps "terraform" in a ruby DSL for managing stack templates
|
127
|
+
test_files:
|
128
|
+
- test/stack_module_test.rb
|
129
|
+
- test/stack_test.rb
|
130
|
+
- test/test_helper.rb
|
131
|
+
has_rdoc:
|