cloudshaper 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/README.md +9 -39
- data/bin/cloudshaper +14 -0
- data/{terraform_dsl.gemspec → cloudshaper.gemspec} +6 -5
- data/lib/{terraform_dsl → cloudshaper}/aws/remote_s3.rb +1 -1
- data/lib/{terraform_dsl → cloudshaper}/aws/tagging.rb +2 -2
- data/lib/cloudshaper/cli.rb +98 -0
- data/lib/{terraform_dsl → cloudshaper}/command.rb +2 -2
- data/lib/cloudshaper/module.rb +30 -0
- data/lib/cloudshaper/output.rb +6 -0
- data/lib/{terraform_dsl → cloudshaper}/provider.rb +6 -4
- data/lib/{terraform_dsl → cloudshaper}/remote.rb +2 -2
- data/lib/{terraform_dsl → cloudshaper}/resource.rb +2 -2
- data/lib/{terraform_dsl → cloudshaper}/secrets.rb +0 -0
- data/lib/{terraform_dsl → cloudshaper}/stack.rb +14 -16
- data/lib/{terraform_dsl → cloudshaper}/stack_element.rb +8 -3
- data/lib/{terraform_dsl → cloudshaper}/stack_module.rb +42 -35
- data/lib/{terraform_dsl → cloudshaper}/stack_modules.rb +6 -2
- data/lib/{terraform_dsl → cloudshaper}/stacks.rb +3 -7
- data/lib/cloudshaper/variable.rb +6 -0
- data/lib/cloudshaper/version.rb +3 -0
- data/lib/cloudshaper.rb +4 -0
- data/lib/tasks/terraform.rake +19 -19
- data/test/stack_module_test.rb +41 -55
- data/test/test_helper.rb +1 -1
- metadata +44 -28
- data/lib/tasks/tasks.rb +0 -12
- data/lib/terraform_dsl/module.rb +0 -38
- data/lib/terraform_dsl/output.rb +0 -6
- data/lib/terraform_dsl/variable.rb +0 -6
- data/lib/terraform_dsl/version.rb +0 -3
- data/lib/terraform_dsl.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 993c81cd51249cfba9467ea7fcbdf922a1d520dd
|
4
|
+
data.tar.gz: c2ac2bdea9eb45c58004053069af40567aced2d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27de4a1c4291b51e313559fc4fe23614ec25889c0134704e5c0414ec2136809b71de27d4bd815f16e04f8f2e1c8b6e2cc817ed370457e0496c8d1beb9f44b7b5
|
7
|
+
data.tar.gz: c576febad8b279a24f829ba7ed1b16857958e5dc18bbfb81d20869eda2866fabf12fb9032c246f4bfccb2d0b3d1067737388006375d5e52a34aa2192811f4841
|
data/Gemfile.lock
CHANGED
@@ -2,7 +2,7 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
cloudshaper (0.0.4)
|
5
|
-
|
5
|
+
thor (~> 0.19.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
@@ -16,6 +16,7 @@ GEM
|
|
16
16
|
json (~> 1.8)
|
17
17
|
simplecov-html (~> 0.10.0)
|
18
18
|
simplecov-html (0.10.0)
|
19
|
+
thor (0.19.1)
|
19
20
|
|
20
21
|
PLATFORMS
|
21
22
|
ruby
|
@@ -24,4 +25,5 @@ DEPENDENCIES
|
|
24
25
|
bundler
|
25
26
|
cloudshaper!
|
26
27
|
minitest (~> 5.6)
|
28
|
+
rake (~> 10.4)
|
27
29
|
simplecov (= 0.10.0)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
[![Build Status](https://travis-ci.org/dalehamel/
|
1
|
+
[![Build Status](https://travis-ci.org/dalehamel/cloudshaper.svg)](https://travis-ci.org/dalehamel/cloudshaper)
|
2
2
|
|
3
|
-
#
|
3
|
+
# Cloudshaper
|
4
4
|
|
5
5
|
This is a simple DSL for wrapping hashicorp's [terraform configuration](https://terraform.io/docs/configuration/index.html).
|
6
6
|
|
@@ -50,13 +50,13 @@ Create a stack module, like one of our [examples](examples), such as our [simple
|
|
50
50
|
Generally, you need to do:
|
51
51
|
|
52
52
|
```
|
53
|
-
require '
|
53
|
+
require 'cloudshaper'
|
54
54
|
```
|
55
55
|
|
56
|
-
And then subclass
|
56
|
+
And then subclass Cloudshaper::StackModule
|
57
57
|
|
58
58
|
```
|
59
|
-
class MyAwesomeStackModule <
|
59
|
+
class MyAwesomeStackModule < Cloudshaper::StackModule
|
60
60
|
```
|
61
61
|
|
62
62
|
Within that class, define resources using a similar syntax to [terraform's configuration](https://terraform.io/docs/configuration/index.html).
|
@@ -107,7 +107,7 @@ common:
|
|
107
107
|
region: us-east-1
|
108
108
|
stacks:
|
109
109
|
- name: teststack
|
110
|
-
uuid:
|
110
|
+
uuid: 8adcbfb1-fdcc-4558-8958-ea8a9e1874ea # must be unique
|
111
111
|
description: just a test stack
|
112
112
|
root: simpleapp
|
113
113
|
variables:
|
@@ -117,43 +117,13 @@ stacks:
|
|
117
117
|
|
118
118
|
You may also specify a 'common' block, that will be merged into all stacks.
|
119
119
|
|
120
|
-
|
120
|
+
Cloudshaper stacks need somewhere to store their state. By default, this will be the local filesystem.
|
121
121
|
|
122
122
|
It's highly recommended that you use a [remote backend](https://www.terraform.io/docs/commands/remote-config.html) instead, so that you can share your stacks.
|
123
123
|
|
124
|
-
###
|
124
|
+
### Commands
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
```
|
129
|
-
## Loads terraform tasks and modules
|
130
|
-
require 'terraform_dsl'
|
131
|
-
Terraform::Tasks.loadall
|
132
|
-
|
133
|
-
```
|
134
|
-
|
135
|
-
This will add some terraform tasks for managing your terraform stacks:
|
136
|
-
|
137
|
-
```
|
138
|
-
rake terraform:apply[name] # Apply pending changes for a stack
|
139
|
-
rake terraform:apply_all # Apply all pending stack changes
|
140
|
-
rake terraform:destroy[name] # Destroy a stack
|
141
|
-
rake terraform:get[name] # Fetch modules for a stack
|
142
|
-
rake terraform:get_all # Fetch modules for all stacks
|
143
|
-
rake terraform:init # Initialize stacks.yml if it does not exist
|
144
|
-
rake terraform:list # List all available stacks
|
145
|
-
rake terraform:load # Loads available stack modules
|
146
|
-
rake terraform:plan[name] # Show pending changes for a stack
|
147
|
-
rake terraform:pull[name] # Pulls stack state from remote location
|
148
|
-
rake terraform:pull_all # Pulls stack states from remote location
|
149
|
-
rake terraform:push[name] # Push stack state to remote location
|
150
|
-
rake terraform:push_all # Push stack states to remote location
|
151
|
-
rake terraform:remote_config[name] # Sets up remote config for a stack
|
152
|
-
rake terraform:remote_config_all # Sets up remote config for all stacks that support it
|
153
|
-
rake terraform:show[name] # Show details about a stack by name
|
154
|
-
rake terraform:show_all # Show all pending stack changes
|
155
|
-
rake terraform:uuid # Generate a UUID for a stack, so stacks do not clobber each other
|
156
|
-
```
|
126
|
+
TODO
|
157
127
|
|
158
128
|
# Credits
|
159
129
|
|
data/bin/cloudshaper
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
3
|
+
require 'cloudshaper/cli'
|
4
|
+
|
5
|
+
begin
|
6
|
+
ENV["THOR_DEBUG"] = "1"
|
7
|
+
Cloudshaper::CLI.start(ARGV)
|
8
|
+
rescue Thor::UndefinedCommandError, Thor::UnknownArgumentError, Thor::AmbiguousCommandError, Thor::InvocationError => e
|
9
|
+
$stderr.puts(e.message)
|
10
|
+
exit(64)
|
11
|
+
rescue Thor::Error => e
|
12
|
+
$stderr.puts(e.message)
|
13
|
+
exit(1)
|
14
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
lib = File.expand_path('../lib', __FILE__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require '
|
3
|
+
require 'cloudshaper/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'cloudshaper'
|
7
|
-
spec.version =
|
7
|
+
spec.version = Cloudshaper::VERSION
|
8
8
|
spec.summary = 'Wrap hashicorps "terraform" in a ruby DSL for managing stack templates'
|
9
|
-
spec.description = '
|
9
|
+
spec.description = 'Cloudshaper provides a syntax for managing terraform infrastructure entirely in git'
|
10
10
|
spec.authors = ['Dale Hamel']
|
11
11
|
spec.email = 'dale.hamel@srvthe.net'
|
12
12
|
spec.files = Dir['lib/**/*']
|
13
|
-
spec.homepage = 'https://
|
13
|
+
spec.homepage = 'https://github.com/dalehamel/cloudshaper'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -18,8 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_runtime_dependency '
|
21
|
+
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
22
22
|
|
23
23
|
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.4'
|
24
25
|
spec.add_development_dependency 'minitest', '~> 5.6'
|
25
26
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Cloudshaper
|
2
2
|
# Aws provider-specific functionality, to be mixed in to stack elements
|
3
3
|
module Aws
|
4
4
|
def self.taggable?(resource_type)
|
@@ -17,7 +17,7 @@ module Terraform
|
|
17
17
|
def post_processing_aws
|
18
18
|
return unless Aws.taggable?(@resource_type)
|
19
19
|
@fields[:tags] ||= {}
|
20
|
-
@fields[:tags][:
|
20
|
+
@fields[:tags][:cloudshaper_stack_id] = var(:cloudshaper_stack_id)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'cloudshaper'
|
3
|
+
|
4
|
+
module Cloudshaper
|
5
|
+
class CLI < Thor
|
6
|
+
class_option "template_dir", type: "string", default: "templates"
|
7
|
+
class_option "remote_state", type: "boolean"
|
8
|
+
|
9
|
+
desc "list", "List all available stacks"
|
10
|
+
def list
|
11
|
+
Cloudshaper::Stacks.stacks.each do |name, _stack|
|
12
|
+
puts name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "show NAME", "Show details about a stack by name"
|
17
|
+
def show(name)
|
18
|
+
stack = load_stack(name, options)
|
19
|
+
puts stack
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "plan NAME", "Show pending changes for a stack"
|
23
|
+
def plan(name)
|
24
|
+
stack = load_stack(name, options)
|
25
|
+
stack.plan
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "apply NAME", "Apply all pending stack changes"
|
29
|
+
def apply(name)
|
30
|
+
stack = load_stack(name, options)
|
31
|
+
stack.apply
|
32
|
+
push(name) if remote_state?
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "destroy NAME", "Destroy a stack"
|
36
|
+
def destroy(name)
|
37
|
+
stack = load_stack(name, options)
|
38
|
+
stack.destroy
|
39
|
+
push(name) if remote_state?
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "pull NAME", "Pull stack state from remote location"
|
43
|
+
def pull(name)
|
44
|
+
stack = load_stack(name, options)
|
45
|
+
remote_config(name)
|
46
|
+
stack.pull
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "push NAME", "Push stack state from remote location"
|
50
|
+
def push(name)
|
51
|
+
stack = load_stack(name, options)
|
52
|
+
remote_config(name)
|
53
|
+
stack.push
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "remote_config NAME", "Sets up remote config for a stack"
|
57
|
+
def remote_config(name)
|
58
|
+
stack = load_stack(name, options)
|
59
|
+
stack.remote_config
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "init", "Initialize stacks.yml if it does not exist"
|
63
|
+
def init
|
64
|
+
Cloudshaper::Stacks.init
|
65
|
+
puts "Created stacks.yml, you're ready to configure your stack"
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "uuid", "Generate a UUID for your stacks, so they don't clobber each other"
|
69
|
+
def uuid
|
70
|
+
puts SecureRandom.uuid
|
71
|
+
end
|
72
|
+
|
73
|
+
desc "version", "Prints the version of cloudshaper"
|
74
|
+
def version
|
75
|
+
puts Cloudshaper::VERSION
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def load_stack(stack, options)
|
81
|
+
puts options
|
82
|
+
load_modules(options['template_dir'])
|
83
|
+
Cloudshaper::Stacks.load
|
84
|
+
pull(stack) if remote_state?
|
85
|
+
stack = Cloudshaper::Stacks.stacks[stack]
|
86
|
+
stack.get
|
87
|
+
stack
|
88
|
+
end
|
89
|
+
|
90
|
+
def remote_state?
|
91
|
+
options["remote_stack"]
|
92
|
+
end
|
93
|
+
|
94
|
+
def load_modules(dir)
|
95
|
+
Dir.glob("#{File.join(Dir.pwd, dir)}/*.rb").each { |t| puts t; require_relative t }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Cloudshaper
|
2
2
|
# Wraps terraform command execution
|
3
3
|
class Command
|
4
4
|
attr_accessor :command
|
@@ -11,7 +11,7 @@ module Terraform
|
|
11
11
|
|
12
12
|
def env
|
13
13
|
vars = {}
|
14
|
-
@stack.
|
14
|
+
@stack.module.each_variable { |k, v| vars["TF_VAR_#{k}"] = v[:default] }
|
15
15
|
@stack.module.secrets.each do |_provider, secrets|
|
16
16
|
secrets.each do |k, v|
|
17
17
|
vars[k.to_s] = v
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'cloudshaper/stack_element'
|
2
|
+
require 'cloudshaper/stack_modules'
|
3
|
+
require 'cloudshaper/stack_module'
|
4
|
+
require 'cloudshaper/stacks'
|
5
|
+
|
6
|
+
module Cloudshaper
|
7
|
+
# Supports terraform 'modules'. In our case, we call them submodules because
|
8
|
+
# Module is a ruby keyword. We also support directly referencing other ruby-defined modules.
|
9
|
+
class Module < StackElement
|
10
|
+
def initialize(parent_module, &block)
|
11
|
+
super(parent_module, &block)
|
12
|
+
|
13
|
+
if StackModules.has? @fields[:source].to_s
|
14
|
+
mod = StackModules.get @fields[:source].to_s
|
15
|
+
module_path = File.join(Stacks.dir, parent_module.id, mod.name)
|
16
|
+
FileUtils.mkdir_p(module_path)
|
17
|
+
@fields[:source] = File.expand_path(module_path)
|
18
|
+
|
19
|
+
file_path = File.join(module_path, 'stack_module.tf.json')
|
20
|
+
build_submodule(file_path, parent_module, mod)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_submodule(file_path, parent_module, child_module)
|
25
|
+
return if File.exists? file_path
|
26
|
+
child_module.build(cloudshaper_stack_id: parent_module.id)
|
27
|
+
File.open(file_path, 'w') { |f| f.write(child_module.generate) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'cloudshaper/secrets'
|
2
|
+
require 'cloudshaper/stack_element'
|
3
3
|
|
4
|
-
module
|
4
|
+
module Cloudshaper
|
5
5
|
# Implements DSL for a terraform provider, and a means of loading secrets.
|
6
6
|
class Provider < StackElement
|
7
7
|
def load_secrets(name)
|
8
8
|
@secrets ||= {}
|
9
|
-
|
9
|
+
if SECRETS.has_key? name.to_sym
|
10
|
+
@secrets[name.to_sym] = SECRETS[name.to_sym]
|
11
|
+
end
|
10
12
|
@secrets
|
11
13
|
end
|
12
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'cloudshaper/aws/remote_s3'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Cloudshaper
|
4
4
|
# Wrap 'remote' commands, such as config, pull, and push
|
5
5
|
# This allows us to store state remotely using different providers
|
6
6
|
class Remote < Command
|
File without changes
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
1
|
+
require 'cloudshaper/stacks'
|
2
|
+
require 'cloudshaper/stack_modules'
|
3
|
+
require 'cloudshaper/command'
|
4
|
+
require 'cloudshaper/remote'
|
5
5
|
|
6
|
-
module
|
6
|
+
module Cloudshaper
|
7
7
|
# Wrapper to instantiate a stack from a yaml definition
|
8
8
|
class Stack
|
9
9
|
class MalformedConfig < Exception; end
|
@@ -20,15 +20,17 @@ module Terraform
|
|
20
20
|
:stack_dir, :stack_id, :remote
|
21
21
|
|
22
22
|
def initialize(config)
|
23
|
-
@name = config
|
24
|
-
@uuid = config
|
25
|
-
@description = config['description'] || ''
|
26
|
-
@variables = config['variables'] || {}
|
23
|
+
@name = config.fetch('name')
|
24
|
+
@uuid = config.fetch('uuid')
|
27
25
|
@remote = config['remote'] || {}
|
28
|
-
@
|
29
|
-
|
30
|
-
@
|
26
|
+
@description = config['description'] || ''
|
27
|
+
|
28
|
+
@stack_id = "cloudshaper#{@name}_#{@uuid}"
|
31
29
|
@stack_dir = File.join(Stacks.dir, @stack_id)
|
30
|
+
|
31
|
+
@module = StackModules.get(config.fetch('root'))
|
32
|
+
@variables = config['variables'] || {}
|
33
|
+
@variables['cloudshaper_stack_id'] = @stack_id
|
32
34
|
@module.build(@variables.map { |k, v| [k.to_sym, v] }.to_h)
|
33
35
|
end
|
34
36
|
|
@@ -64,10 +66,6 @@ module Terraform
|
|
64
66
|
Remote.new(self, :config).execute
|
65
67
|
end
|
66
68
|
|
67
|
-
def variables
|
68
|
-
@module.variables
|
69
|
-
end
|
70
|
-
|
71
69
|
def to_s
|
72
70
|
<<-eos
|
73
71
|
Name: #{@name}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'cloudshaper/aws/tagging'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Cloudshaper
|
4
4
|
# Defines a single terraform stack element, subclass for any element defined in terraform DSL
|
5
5
|
class StackElement
|
6
6
|
include Aws
|
@@ -24,7 +24,7 @@ module Terraform
|
|
24
24
|
end
|
25
25
|
add_field(symbol, args[0])
|
26
26
|
else
|
27
|
-
add_field(symbol,
|
27
|
+
add_field(symbol, Cloudshaper::StackElement.new(@module, &block).fields)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -38,6 +38,11 @@ module Terraform
|
|
38
38
|
"${var.#{variable_name}}"
|
39
39
|
end
|
40
40
|
|
41
|
+
# Reference a list variable
|
42
|
+
def var_list(variable_name)
|
43
|
+
["${split(\",\",var.#{variable_name})}"]
|
44
|
+
end
|
45
|
+
|
41
46
|
# Syntax to handle interpolation of resource variables
|
42
47
|
def value_of(resource_type, resource_name, value_type)
|
43
48
|
"${#{resource_type}.#{resource_name}.#{value_type}}"
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
|
11
|
-
module
|
4
|
+
require 'cloudshaper/stack_modules'
|
5
|
+
require 'cloudshaper/resource'
|
6
|
+
require 'cloudshaper/provider'
|
7
|
+
require 'cloudshaper/variable'
|
8
|
+
require 'cloudshaper/module'
|
9
|
+
require 'cloudshaper/output'
|
10
|
+
|
11
|
+
module Cloudshaper
|
12
12
|
# Stack Modules contain stack elements. A stack is made up of a root module, which may have submodules
|
13
13
|
class StackModule
|
14
14
|
class << self
|
@@ -30,13 +30,14 @@ module Terraform
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
attr_accessor :secrets
|
33
|
+
attr_accessor :name, :secrets
|
34
34
|
|
35
|
-
def initialize(
|
35
|
+
def initialize(name, &block)
|
36
|
+
@name = name
|
36
37
|
@stack_elements = { resource: {}, provider: {}, variable: {}, output: {}, module: {} }
|
37
38
|
@secrets = {}
|
38
39
|
@block = block
|
39
|
-
variable(:
|
40
|
+
variable(:cloudshaper_stack_id) { default '' }
|
40
41
|
end
|
41
42
|
|
42
43
|
def clone
|
@@ -55,18 +56,24 @@ module Terraform
|
|
55
56
|
JSON.pretty_generate(elements)
|
56
57
|
end
|
57
58
|
|
58
|
-
def
|
59
|
-
|
59
|
+
def id
|
60
|
+
get(:cloudshaper_stack_id)
|
60
61
|
end
|
61
62
|
|
62
|
-
def
|
63
|
-
|
63
|
+
def get(variable)
|
64
|
+
elements[:variable].fetch(variable)[:default]
|
64
65
|
end
|
65
66
|
|
66
|
-
def
|
67
|
-
|
67
|
+
def each_variable(&b)
|
68
|
+
elements[:variable].each(&b)
|
68
69
|
end
|
69
70
|
|
71
|
+
def get_resource(type, id)
|
72
|
+
@stack_elements[:resource].fetch(type).fetch(id)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
70
77
|
def elements
|
71
78
|
elements = @stack_elements.clone
|
72
79
|
variables = StackModule.flatten_variable_arrays(@stack_elements[:variable])
|
@@ -77,45 +84,45 @@ module Terraform
|
|
77
84
|
elements
|
78
85
|
end
|
79
86
|
|
80
|
-
def id
|
81
|
-
get(:terraform_stack_id)
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
87
|
def register_resource(resource_type, name, &block)
|
87
88
|
@stack_elements[:resource] ||= {}
|
88
89
|
@stack_elements[:resource][resource_type.to_sym] ||= {}
|
89
|
-
@stack_elements[:resource][resource_type.to_sym][name.to_sym] =
|
90
|
+
@stack_elements[:resource][resource_type.to_sym][name.to_sym] = Cloudshaper::Resource.new(self, name, resource_type, &block).fields
|
90
91
|
end
|
91
92
|
|
92
93
|
def register_variable(name, &block)
|
93
|
-
|
94
|
-
|
95
|
-
|
94
|
+
return if @stack_elements[:variable].key?(name)
|
95
|
+
|
96
|
+
new_variable = Cloudshaper::Variable.new(self, &block).fields
|
97
|
+
if new_variable[:default].nil?
|
98
|
+
@stack_elements[:variable][name.to_sym] = {}
|
99
|
+
else
|
100
|
+
@stack_elements[:variable][name.to_sym] = {
|
101
|
+
default: new_variable[:default]
|
102
|
+
}
|
96
103
|
end
|
97
104
|
end
|
98
105
|
|
99
106
|
def register_output(name, &block)
|
100
|
-
new_output =
|
107
|
+
new_output = Cloudshaper::Output.new(self, &block).fields
|
101
108
|
@stack_elements[:output][name.to_sym] = new_output
|
102
109
|
end
|
103
110
|
|
104
111
|
def register_module(name, &block)
|
105
|
-
new_module =
|
112
|
+
new_module = Cloudshaper::Module.new(self, &block).fields
|
106
113
|
@stack_elements[:module][name.to_sym] = new_module
|
107
114
|
end
|
108
115
|
|
109
116
|
def register_provider(name, &block)
|
110
|
-
provider =
|
117
|
+
provider = Cloudshaper::Provider.new(self, &block)
|
111
118
|
@secrets.merge!(provider.load_secrets(name))
|
112
119
|
@stack_elements[:provider][name.to_sym] = provider.fields
|
113
120
|
end
|
114
121
|
|
115
|
-
alias_method :resource,
|
116
|
-
alias_method :variable,
|
117
|
-
alias_method :provider,
|
118
|
-
alias_method :output,
|
119
|
-
alias_method :submodule,
|
122
|
+
alias_method :resource, :register_resource
|
123
|
+
alias_method :variable, :register_variable
|
124
|
+
alias_method :provider, :register_provider
|
125
|
+
alias_method :output, :register_output
|
126
|
+
alias_method :submodule, :register_module
|
120
127
|
end
|
121
128
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Cloudshaper
|
2
2
|
# Stack module factory, register a module and provide clones of it
|
3
3
|
class StackModules
|
4
4
|
class ModuleNotFound < StandardError; end
|
@@ -10,13 +10,17 @@ module Terraform
|
|
10
10
|
@stack_modules[name.downcase] = stack_module
|
11
11
|
end
|
12
12
|
|
13
|
+
def has?(stack_module_name)
|
14
|
+
@stack_modules.key?(stack_module_name.downcase)
|
15
|
+
end
|
16
|
+
|
13
17
|
def get(stack_module_name)
|
14
18
|
fail ModuleNotFound, "#{stack_module_name} module module not found" unless @stack_modules.key?(stack_module_name.downcase)
|
15
19
|
@stack_modules[stack_module_name.downcase].clone
|
16
20
|
end
|
17
21
|
|
18
22
|
def reset!
|
19
|
-
@stack_modules
|
23
|
+
@stack_modules = {}
|
20
24
|
end
|
21
25
|
end
|
22
26
|
reset!
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'securerandom'
|
3
3
|
|
4
|
-
require '
|
4
|
+
require 'cloudshaper/stack'
|
5
5
|
|
6
|
-
module
|
6
|
+
module Cloudshaper
|
7
7
|
# Singleton to keep track of stack templates
|
8
8
|
class Stacks
|
9
9
|
class MalformedConfig < StandardError; end
|
@@ -30,10 +30,6 @@ module Terraform
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def uuid
|
34
|
-
"#{Time.now.utc.to_i}_#{SecureRandom.urlsafe_base64(6)}"
|
35
|
-
end
|
36
|
-
|
37
33
|
def base_config
|
38
34
|
{
|
39
35
|
'common' => {},
|
@@ -44,7 +40,7 @@ module Terraform
|
|
44
40
|
def base_stack_config
|
45
41
|
{
|
46
42
|
'name' => 'SET_NAME',
|
47
|
-
'uuid' => uuid,
|
43
|
+
'uuid' => SecureRandom.uuid,
|
48
44
|
'description' => 'SET_A_DESCRIPTION',
|
49
45
|
'root' => 'SET_A_TEMPLATE',
|
50
46
|
'variables' => {}
|
data/lib/cloudshaper.rb
ADDED
data/lib/tasks/terraform.rake
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
require '
|
1
|
+
require 'cloudshaper'
|
2
2
|
|
3
3
|
namespace 'terraform' do
|
4
4
|
desc 'Loads available stack modules'
|
5
5
|
task :load do
|
6
|
-
|
6
|
+
Cloudshaper::Stacks.load
|
7
7
|
end
|
8
8
|
|
9
9
|
desc 'Initialize stacks.yml if it does not exist'
|
10
10
|
task :init do
|
11
|
-
|
11
|
+
Cloudshaper::Stacks.init
|
12
12
|
end
|
13
13
|
|
14
14
|
desc 'Fetch modules for a stack'
|
15
15
|
task :get, [:name] => :load do |_t, args|
|
16
|
-
stack =
|
16
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
17
17
|
stack.get
|
18
18
|
end
|
19
19
|
|
20
20
|
desc 'Fetch modules for all stacks'
|
21
21
|
task get_all: :load do
|
22
|
-
|
22
|
+
Cloudshaper::Stacks.stacks.each do |_name, stack|
|
23
23
|
stack.get
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
desc 'List all available stacks'
|
28
28
|
task list: :load do
|
29
|
-
|
29
|
+
Cloudshaper::Stacks.stacks.each do |name, _stack|
|
30
30
|
puts name
|
31
31
|
end
|
32
32
|
end
|
@@ -34,14 +34,14 @@ namespace 'terraform' do
|
|
34
34
|
desc 'Show details about a stack by name'
|
35
35
|
task :show, [:name] => :load do |_t, args|
|
36
36
|
fail 'Specify a name' unless args[:name]
|
37
|
-
stack =
|
37
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
38
38
|
puts stack
|
39
39
|
stack.plan
|
40
40
|
end
|
41
41
|
|
42
42
|
desc 'Show all pending stack changes'
|
43
43
|
task show_all: [:load, :get_all] do
|
44
|
-
|
44
|
+
Cloudshaper::Stacks.stacks.each do |_name, stack|
|
45
45
|
puts stack
|
46
46
|
stack.plan
|
47
47
|
end
|
@@ -50,20 +50,20 @@ namespace 'terraform' do
|
|
50
50
|
desc 'Show pending changes for a stack'
|
51
51
|
task :plan, [:name] => :load do |_t, args|
|
52
52
|
fail 'Specify a name' unless args[:name]
|
53
|
-
stack =
|
53
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
54
54
|
stack.plan
|
55
55
|
end
|
56
56
|
|
57
57
|
desc 'Apply pending changes for a stack'
|
58
58
|
task :apply, [:name] => :load do |_t, args|
|
59
59
|
fail 'Specify a name' unless args[:name]
|
60
|
-
stack =
|
60
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
61
61
|
stack.apply
|
62
62
|
end
|
63
63
|
|
64
64
|
desc 'Apply all pending stack changes'
|
65
65
|
task apply_all: :load do
|
66
|
-
|
66
|
+
Cloudshaper::Stacks.stacks.each do |_name, stack|
|
67
67
|
puts stack
|
68
68
|
stack.apply
|
69
69
|
end
|
@@ -72,19 +72,19 @@ namespace 'terraform' do
|
|
72
72
|
desc 'Destroy a stack'
|
73
73
|
task :destroy, [:name] => :load do |_t, args|
|
74
74
|
fail 'Specify a name' unless args[:name]
|
75
|
-
stack =
|
75
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
76
76
|
stack.destroy
|
77
77
|
end
|
78
78
|
|
79
79
|
desc 'Push stack state to remote location'
|
80
80
|
task :push, [:name] => [:load, :remote_config] do |_t, args|
|
81
|
-
stack =
|
81
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
82
82
|
stack.push
|
83
83
|
end
|
84
84
|
|
85
85
|
desc 'Push stack states to remote location'
|
86
86
|
task push_all: [:load, :remote_config_all] do
|
87
|
-
|
87
|
+
Cloudshaper::Stacks.stacks.each do |_name, stack|
|
88
88
|
puts stack
|
89
89
|
stack.push
|
90
90
|
end
|
@@ -92,13 +92,13 @@ namespace 'terraform' do
|
|
92
92
|
|
93
93
|
desc 'Pulls stack state from remote location'
|
94
94
|
task :pull, [:name] => [:load, :remote_config] do |_t, args|
|
95
|
-
stack =
|
95
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
96
96
|
stack.pull
|
97
97
|
end
|
98
98
|
|
99
99
|
desc 'Pulls stack states from remote location'
|
100
100
|
task pull_all: [:load, :remote_config_all] do
|
101
|
-
|
101
|
+
Cloudshaper::Stacks.stacks.each do |_name, stack|
|
102
102
|
puts stack
|
103
103
|
stack.pull
|
104
104
|
end
|
@@ -106,13 +106,13 @@ namespace 'terraform' do
|
|
106
106
|
|
107
107
|
desc 'Sets up remote config for a stack'
|
108
108
|
task :remote_config, [:name] => [:load] do |_t, args|
|
109
|
-
stack =
|
109
|
+
stack = Cloudshaper::Stacks.stacks[args[:name]]
|
110
110
|
stack.remote_config
|
111
111
|
end
|
112
112
|
|
113
113
|
desc 'Sets up remote config for all stacks that support it'
|
114
114
|
task remote_config_all: :load do
|
115
|
-
|
115
|
+
Cloudshaper::Stacks.stacks.each do |_name, stack|
|
116
116
|
puts stack
|
117
117
|
stack.remote_config
|
118
118
|
end
|
@@ -120,7 +120,7 @@ namespace 'terraform' do
|
|
120
120
|
|
121
121
|
desc 'Generate a UUID for a stack, so stacks do not clobber each other'
|
122
122
|
task :uuid do
|
123
|
-
uuid =
|
123
|
+
uuid = Cloudshaper::Stacks.uuid
|
124
124
|
puts "uuid: #{uuid}"
|
125
125
|
puts 'Add this as a field to a new stack to prevent clobbering stacks with the same name'
|
126
126
|
end
|
data/test/stack_module_test.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class StackModuleTest < Minitest::Test
|
4
|
-
include
|
4
|
+
include Cloudshaper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
StackModules.reset!
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_multiple_modules_same_name_raises_exception
|
11
|
+
StackModule.define 'same_name_test'
|
12
|
+
assert_raises(StackModules::ModuleAlreadyRegistered) do
|
13
|
+
StackModule.define 'same_name_test'
|
14
|
+
end
|
15
|
+
end
|
5
16
|
|
6
17
|
def test_multiple_instantiations_of_module
|
7
18
|
StackModule.define 'factory_instantiation_test' do
|
@@ -19,48 +30,45 @@ class StackModuleTest < Minitest::Test
|
|
19
30
|
first.build(ports: '80')
|
20
31
|
second.build(ports: '443')
|
21
32
|
|
22
|
-
sg_first = first.
|
23
|
-
sg_second = second.
|
33
|
+
sg_first = first.get_resource(:aws_security_group, :a)
|
34
|
+
sg_second = second.get_resource(:aws_security_group, :a)
|
24
35
|
|
25
36
|
assert_equal '80', sg_first[:ingress].fetch(:from_port)
|
26
37
|
assert_equal '443', sg_second[:ingress].fetch(:from_port)
|
27
38
|
end
|
28
39
|
|
29
|
-
|
30
|
-
|
31
|
-
|
40
|
+
def test_module_build_registers_variable_with_defaults
|
41
|
+
mod = StackModule.define('variable_register_default') do
|
42
|
+
variable(:name) { default 'spam' }
|
43
|
+
end
|
44
|
+
mod.build
|
32
45
|
|
33
|
-
|
34
|
-
|
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
|
46
|
+
assert_equal 'spam', mod.get(:name)
|
47
|
+
end
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
|
49
|
+
def test_required_variable_has_no_default_value
|
50
|
+
mod = StackModule.define('resource_required_variable') { variable(:name) {} }
|
51
|
+
mod.build
|
43
52
|
|
44
|
-
|
45
|
-
|
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
|
53
|
+
assert_nil mod.get(:name)
|
54
|
+
end
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
56
|
+
def test_module_build_registers_variables_at_runtime
|
57
|
+
mod = StackModule.define('variable_override') do
|
58
|
+
variable(:name) { default 'default' }
|
59
|
+
end
|
60
|
+
mod.build(name: 'not-default')
|
54
61
|
|
55
|
-
|
56
|
-
|
57
|
-
# end
|
62
|
+
assert_equal 'not-default', mod.get(:name)
|
63
|
+
end
|
58
64
|
|
59
65
|
def test_register_resource
|
60
|
-
mod = StackModule.define('register_resource')
|
66
|
+
mod = StackModule.define('register_resource') do
|
67
|
+
resource('aws_instance', :a) { default 'default' }
|
68
|
+
end
|
61
69
|
mod.build
|
62
70
|
|
63
|
-
instance = mod.
|
71
|
+
instance = mod.get_resource(:aws_instance, :a)
|
64
72
|
assert_equal 'default', instance.fetch(:default)
|
65
73
|
end
|
66
74
|
|
@@ -74,7 +82,7 @@ class StackModuleTest < Minitest::Test
|
|
74
82
|
end
|
75
83
|
mod.build
|
76
84
|
|
77
|
-
instance = mod.
|
85
|
+
instance = mod.get_resource(:aws_instance, :a)
|
78
86
|
assert_equal 'root', instance.fetch(:connection).fetch(:user)
|
79
87
|
end
|
80
88
|
|
@@ -90,7 +98,7 @@ class StackModuleTest < Minitest::Test
|
|
90
98
|
end
|
91
99
|
mod.build
|
92
100
|
|
93
|
-
instance = mod.
|
101
|
+
instance = mod.get_resource(:aws_instance, :a)
|
94
102
|
provisioner = instance.fetch(:provisioner).first
|
95
103
|
connection = provisioner.fetch(:file).fetch(:connection)
|
96
104
|
assert_equal 'root', connection.fetch(:user)
|
@@ -105,7 +113,7 @@ class StackModuleTest < Minitest::Test
|
|
105
113
|
end
|
106
114
|
mod.build
|
107
115
|
|
108
|
-
sg = mod.
|
116
|
+
sg = mod.get_resource(:aws_security_group, :a)
|
109
117
|
ingress = sg.fetch(:ingress)
|
110
118
|
|
111
119
|
assert_kind_of Array, ingress
|
@@ -123,30 +131,8 @@ class StackModuleTest < Minitest::Test
|
|
123
131
|
end
|
124
132
|
mod.build(ports: '22,80,443')
|
125
133
|
|
126
|
-
|
127
|
-
sg = mod.elements.fetch(:resource).fetch(:aws_security_group).fetch(:a)
|
134
|
+
sg = mod.get_resource(:aws_security_group, :a)
|
128
135
|
ingress = sg.fetch(:ingress)
|
129
136
|
assert_equal [{from_port: "22"}, {from_port: "80"}, {from_port: "443"}], ingress
|
130
137
|
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
138
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudshaper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Hamel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.19.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.19.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.4'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,10 +66,11 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '5.6'
|
55
|
-
description:
|
56
|
-
|
69
|
+
description: Cloudshaper provides a syntax for managing terraform infrastructure entirely
|
70
|
+
in git
|
57
71
|
email: dale.hamel@srvthe.net
|
58
|
-
executables:
|
72
|
+
executables:
|
73
|
+
- cloudshaper
|
59
74
|
extensions: []
|
60
75
|
extra_rdoc_files: []
|
61
76
|
files:
|
@@ -67,6 +82,8 @@ files:
|
|
67
82
|
- README.md
|
68
83
|
- Rakefile
|
69
84
|
- TODO.md
|
85
|
+
- bin/cloudshaper
|
86
|
+
- cloudshaper.gemspec
|
70
87
|
- examples/secretconfig/README.md
|
71
88
|
- examples/secretconfig/atlas.json
|
72
89
|
- examples/secretconfig/aws.json
|
@@ -77,30 +94,29 @@ files:
|
|
77
94
|
- examples/secretconfig/heroku.json
|
78
95
|
- examples/secretconfig/mailgun.json
|
79
96
|
- examples/simple_app.rb
|
80
|
-
- lib/
|
97
|
+
- lib/cloudshaper.rb
|
98
|
+
- lib/cloudshaper/aws/remote_s3.rb
|
99
|
+
- lib/cloudshaper/aws/tagging.rb
|
100
|
+
- lib/cloudshaper/cli.rb
|
101
|
+
- lib/cloudshaper/command.rb
|
102
|
+
- lib/cloudshaper/module.rb
|
103
|
+
- lib/cloudshaper/output.rb
|
104
|
+
- lib/cloudshaper/provider.rb
|
105
|
+
- lib/cloudshaper/remote.rb
|
106
|
+
- lib/cloudshaper/resource.rb
|
107
|
+
- lib/cloudshaper/secrets.rb
|
108
|
+
- lib/cloudshaper/stack.rb
|
109
|
+
- lib/cloudshaper/stack_element.rb
|
110
|
+
- lib/cloudshaper/stack_module.rb
|
111
|
+
- lib/cloudshaper/stack_modules.rb
|
112
|
+
- lib/cloudshaper/stacks.rb
|
113
|
+
- lib/cloudshaper/variable.rb
|
114
|
+
- lib/cloudshaper/version.rb
|
81
115
|
- 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
116
|
- test/stack_module_test.rb
|
101
117
|
- test/stack_test.rb
|
102
118
|
- test/test_helper.rb
|
103
|
-
homepage: https://
|
119
|
+
homepage: https://github.com/dalehamel/cloudshaper
|
104
120
|
licenses:
|
105
121
|
- MIT
|
106
122
|
metadata: {}
|
data/lib/tasks/tasks.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
|
3
|
-
module Terraform
|
4
|
-
# Loads all rake tasks when terraform_dsl is included by a rake script
|
5
|
-
class Tasks
|
6
|
-
def self.loadall
|
7
|
-
Dir.glob("#{File.join(File.dirname(__dir__), 'tasks')}/*.rake").each { |r| load r }
|
8
|
-
template_path = ENV['TERRAFORM_TEMPLATE_PATH'] || 'templates'
|
9
|
-
Dir.glob("#{File.join(Dir.pwd, template_path)}/*.rb").each { |t| require_relative t }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
data/lib/terraform_dsl/module.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'terraform_dsl/stack_element'
|
2
|
-
require 'terraform_dsl/stack_modules'
|
3
|
-
require 'terraform_dsl/stack_module'
|
4
|
-
require 'terraform_dsl/stacks'
|
5
|
-
|
6
|
-
module Terraform
|
7
|
-
# Supports terraform 'modules'. In our case, we call them submodules because
|
8
|
-
# Module is a ruby keyword. We also support directly referencing other ruby-defined modules.
|
9
|
-
class Module < StackElement
|
10
|
-
def initialize(parent_module, module_name, &block)
|
11
|
-
super(parent_module, &block)
|
12
|
-
|
13
|
-
if @fields[:source].match(/^module_/)
|
14
|
-
build_submodule(parent_module, module_name)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def build_submodule(parent_module, module_name)
|
21
|
-
generated = generate_child_module(parent_module)
|
22
|
-
module_path = File.join(Stacks.dir, parent_module.id, module_name.to_s)
|
23
|
-
FileUtils.mkdir_p(module_path)
|
24
|
-
File.open(File.join(module_path, 'stack_module.tf.json'), 'w') { |f| f.write(generated) }
|
25
|
-
@fields[:source] = File.expand_path(module_path)
|
26
|
-
end
|
27
|
-
|
28
|
-
def generate_child_module(parent_module)
|
29
|
-
variables = @fields.clone
|
30
|
-
variables.delete(:source)
|
31
|
-
variables[:terraform_stack_id] = parent_module.id
|
32
|
-
child_name = @fields[:source].gsub(/^module_/, '')
|
33
|
-
child_module = StackModules.get(child_name)
|
34
|
-
child_module.build(variables)
|
35
|
-
child_module.generate
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/lib/terraform_dsl/output.rb
DELETED