terraform-wrapper 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.gitlab-ci.yml +35 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +13 -0
- data/bin/console +16 -0
- data/bin/setup +18 -0
- data/lib/terraform-wrapper.rb +47 -0
- data/lib/terraform-wrapper/common.rb +38 -0
- data/lib/terraform-wrapper/shared.rb +11 -0
- data/lib/terraform-wrapper/shared/backends.rb +11 -0
- data/lib/terraform-wrapper/shared/backends/aws.rb +106 -0
- data/lib/terraform-wrapper/shared/backends/azure.rb +120 -0
- data/lib/terraform-wrapper/shared/backends/common.rb +86 -0
- data/lib/terraform-wrapper/shared/backends/local.rb +86 -0
- data/lib/terraform-wrapper/shared/binary.rb +102 -0
- data/lib/terraform-wrapper/shared/code.rb +54 -0
- data/lib/terraform-wrapper/shared/config.rb +125 -0
- data/lib/terraform-wrapper/shared/identifiers.rb +70 -0
- data/lib/terraform-wrapper/shared/latest.rb +75 -0
- data/lib/terraform-wrapper/shared/runner.rb +155 -0
- data/lib/terraform-wrapper/tasks.rb +12 -0
- data/lib/terraform-wrapper/tasks/apply.rb +68 -0
- data/lib/terraform-wrapper/tasks/binary.rb +178 -0
- data/lib/terraform-wrapper/tasks/clean.rb +141 -0
- data/lib/terraform-wrapper/tasks/destroy.rb +68 -0
- data/lib/terraform-wrapper/tasks/init.rb +67 -0
- data/lib/terraform-wrapper/tasks/plan.rb +68 -0
- data/lib/terraform-wrapper/tasks/plandestroy.rb +68 -0
- data/lib/terraform-wrapper/tasks/validate.rb +59 -0
- data/lib/terraform-wrapper/version.rb +13 -0
- data/terraform-wrapper.gemspec +36 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ada2b6b6e65d6daedfc646d9f983894ada4061b649902252468bccaae76b4fee
|
4
|
+
data.tar.gz: 4698b8bc21d9ab1ab2866a263645a2aa07955aeb03b2f10d15aed732da1d4553
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '095bd5f00cda0d8fa2e6e636bfaf4bf31e6dea0a03cbc49b3149c85b15c75e4928e5754dd56b9a71d9d0b33f5b8a7e033739e45e7746fe2fd97d28bb0139f62e'
|
7
|
+
data.tar.gz: 36f56ccf800f33dba662e41f377688e753c409076417269a2b638a6a28b60980aea437736236ca1083602f2a1cf8d935c0cc7aaaa35b297ba11bde06e935efd2
|
data/.gitignore
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
**/*.DS_Store
|
4
|
+
**/*.swp
|
5
|
+
**/*.tmp
|
6
|
+
**/*~
|
7
|
+
|
8
|
+
###############################################################################
|
9
|
+
|
10
|
+
.idea
|
11
|
+
|
12
|
+
###############################################################################
|
13
|
+
|
14
|
+
/.bundle/
|
15
|
+
/.yardoc
|
16
|
+
/_yardoc/
|
17
|
+
/coverage/
|
18
|
+
/doc/
|
19
|
+
/pkg/
|
20
|
+
/spec/reports/
|
21
|
+
/tmp/
|
22
|
+
|
23
|
+
###############################################################################
|
24
|
+
|
25
|
+
/archlinux/
|
26
|
+
!/archlinux/PKGBUILD
|
27
|
+
|
28
|
+
###############################################################################
|
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
image: ruby
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
stages:
|
8
|
+
- test
|
9
|
+
- publish
|
10
|
+
|
11
|
+
###############################################################################
|
12
|
+
|
13
|
+
test:
|
14
|
+
stage : test
|
15
|
+
script:
|
16
|
+
- echo "-- Beginning Test --"
|
17
|
+
- echo "-- Tests not implemented yet --"
|
18
|
+
|
19
|
+
###############################################################################
|
20
|
+
|
21
|
+
deploy:
|
22
|
+
rules:
|
23
|
+
- if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/'
|
24
|
+
stage: publish
|
25
|
+
script:
|
26
|
+
- echo "-- Beginning Publish --"
|
27
|
+
- test -n "${GEM_HOST_API_KEY}"
|
28
|
+
- echo "RubyGems API key found!"
|
29
|
+
- hash rake
|
30
|
+
- hash ruby
|
31
|
+
- hash gem
|
32
|
+
- echo "-- Publishing Gem --"
|
33
|
+
- rake release
|
34
|
+
|
35
|
+
###############################################################################
|
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
source "https://rubygems.org"
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
gemspec
|
12
|
+
|
13
|
+
###############################################################################
|
14
|
+
|
15
|
+
gem "rake", "~> 13.0"
|
16
|
+
|
17
|
+
###############################################################################
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Richard Lees, BITServices Ltd.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
require "bundler/gem_tasks"
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
task default: %i[]
|
12
|
+
|
13
|
+
###############################################################################
|
data/bin/console
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
###############################################################################
|
3
|
+
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
###############################################################################
|
7
|
+
|
8
|
+
require "bundler/setup"
|
9
|
+
require "irb"
|
10
|
+
require "terraform-wrapper"
|
11
|
+
|
12
|
+
###############################################################################
|
13
|
+
|
14
|
+
IRB.start(__FILE__)
|
15
|
+
|
16
|
+
###############################################################################
|
data/bin/setup
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
###############################################################################
|
3
|
+
|
4
|
+
set -euo pipefail
|
5
|
+
|
6
|
+
###############################################################################
|
7
|
+
|
8
|
+
IFS=$'\n\t'
|
9
|
+
|
10
|
+
###############################################################################
|
11
|
+
|
12
|
+
set -vx
|
13
|
+
|
14
|
+
###############################################################################
|
15
|
+
|
16
|
+
bundle install
|
17
|
+
|
18
|
+
###############################################################################
|
@@ -0,0 +1,47 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
require_relative 'terraform-wrapper/shared'
|
4
|
+
require_relative 'terraform-wrapper/tasks'
|
5
|
+
require_relative 'terraform-wrapper/version'
|
6
|
+
|
7
|
+
###############################################################################
|
8
|
+
|
9
|
+
require_relative 'terraform-wrapper/common'
|
10
|
+
|
11
|
+
###############################################################################
|
12
|
+
|
13
|
+
module TerraformWrapper
|
14
|
+
|
15
|
+
###############################################################################
|
16
|
+
|
17
|
+
def self.define_tasks(backend: "local",
|
18
|
+
binaries: File.join(Dir.pwd, "vendor", "terraform"),
|
19
|
+
component:,
|
20
|
+
configs: File.join(Dir.pwd, "config"),
|
21
|
+
overrides: Hash.new,
|
22
|
+
service:,
|
23
|
+
terraform: File.join(Dir.pwd, "terraform"),
|
24
|
+
version: TerraformWrapper::Shared::Latest.instance.version)
|
25
|
+
|
26
|
+
$logger.info("Building tasks for service: #{service}, component: #{component}...")
|
27
|
+
|
28
|
+
binary = TerraformWrapper::Shared::Binary.new(base: binaries, version: version)
|
29
|
+
code = TerraformWrapper::Shared::Code.new(base: terraform, name: component)
|
30
|
+
|
31
|
+
tasks = Array.new
|
32
|
+
tasks << TerraformWrapper::Tasks::Apply.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
|
33
|
+
tasks << TerraformWrapper::Tasks::Binary.new(binary: binary)
|
34
|
+
tasks << TerraformWrapper::Tasks::Clean.new(code: code)
|
35
|
+
tasks << TerraformWrapper::Tasks::Destroy.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
|
36
|
+
tasks << TerraformWrapper::Tasks::Init.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
|
37
|
+
tasks << TerraformWrapper::Tasks::Plan.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
|
38
|
+
tasks << TerraformWrapper::Tasks::PlanDestroy.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
|
39
|
+
tasks << TerraformWrapper::Tasks::Validate.new(binary: binary, code: code)
|
40
|
+
return tasks
|
41
|
+
end
|
42
|
+
|
43
|
+
###############################################################################
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
###############################################################################
|
@@ -0,0 +1,38 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
$logger = Logger.new(STDOUT,
|
8
|
+
level: "INFO",
|
9
|
+
progname: "TerraformWrapper")
|
10
|
+
|
11
|
+
$logger.formatter = proc do |severity, datetime, progname, msg|
|
12
|
+
sevId = severity.chars.first.upcase
|
13
|
+
"#{progname} [#{sevId}] #{msg}\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
###############################################################################
|
17
|
+
|
18
|
+
$logger.info("Terraform Wrapper for Ruby - version: #{TerraformWrapper::VERSION}")
|
19
|
+
|
20
|
+
###############################################################################
|
21
|
+
|
22
|
+
def create_directory(directory:, purpose: nil, exists: true)
|
23
|
+
return exists if File.directory?(directory)
|
24
|
+
|
25
|
+
result = false
|
26
|
+
|
27
|
+
if not purpose.nil? and purpose.kind_of?(String) and not purpose.strip.empty? then
|
28
|
+
$logger.info("Creating directory for: #{purpose}, path: #{directory}")
|
29
|
+
else
|
30
|
+
$logger.info("Creating directory: #{directory}")
|
31
|
+
end
|
32
|
+
|
33
|
+
FileUtils.mkdir_p(directory)
|
34
|
+
|
35
|
+
result = File.directory?(directory)
|
36
|
+
end
|
37
|
+
|
38
|
+
###############################################################################
|
@@ -0,0 +1,11 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
require_relative 'shared/backends'
|
4
|
+
require_relative 'shared/binary'
|
5
|
+
require_relative 'shared/code'
|
6
|
+
require_relative 'shared/config'
|
7
|
+
require_relative 'shared/identifiers'
|
8
|
+
require_relative 'shared/latest'
|
9
|
+
require_relative 'shared/runner'
|
10
|
+
|
11
|
+
###############################################################################
|
@@ -0,0 +1,11 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
require_relative 'backends/common'
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
require_relative 'backends/aws'
|
8
|
+
require_relative 'backends/azure'
|
9
|
+
require_relative 'backends/local'
|
10
|
+
|
11
|
+
###############################################################################
|
@@ -0,0 +1,106 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
module TerraformWrapper
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
module Shared
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
module Backends
|
12
|
+
|
13
|
+
###############################################################################
|
14
|
+
|
15
|
+
class AWS < Common
|
16
|
+
|
17
|
+
###############################################################################
|
18
|
+
|
19
|
+
@@default_class = "terraform-state"
|
20
|
+
|
21
|
+
###############################################################################
|
22
|
+
|
23
|
+
@@type = "aws"
|
24
|
+
|
25
|
+
###############################################################################
|
26
|
+
|
27
|
+
attr_reader :bucket
|
28
|
+
attr_reader :class
|
29
|
+
attr_reader :key
|
30
|
+
attr_reader :region
|
31
|
+
|
32
|
+
###############################################################################
|
33
|
+
|
34
|
+
def initialize(service:, code:, identifiers:, overrides: Hash.new)
|
35
|
+
construct(service: service, code: code, identifiers: identifiers, overrides: overrides)
|
36
|
+
end
|
37
|
+
|
38
|
+
###############################################################################
|
39
|
+
|
40
|
+
def hash()
|
41
|
+
return {
|
42
|
+
"bucket" => @bucket,
|
43
|
+
"key" => @key,
|
44
|
+
"region" => @region
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
###############################################################################
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
###############################################################################
|
53
|
+
|
54
|
+
def specific()
|
55
|
+
if @overrides.key?("class") and @overrides["class"].kind_of?(String) and not @overrides["class"].strip.empty? then
|
56
|
+
@class = @overrides["class"]
|
57
|
+
else
|
58
|
+
@class = @@default_class
|
59
|
+
end
|
60
|
+
|
61
|
+
if @overrides.key?("region") and @overrides["region"].kind_of?(String) and not @overrides["region"].strip.empty? then
|
62
|
+
@region = @overrides["region"]
|
63
|
+
else
|
64
|
+
raise "Mandatory identifier 'region' or override 'region' must be set in provided configuration to backend of type: #{@@type}" unless @identifier.key?("region")
|
65
|
+
raise "Mandatory identifier 'region' is not a string in provided configuration to backend of type: #{@@type}" unless @identifier["region"].kind_of?(String)
|
66
|
+
raise "Mandatory identifier 'region' is empty in provided configuration to backend of type: #{@@type}" if @identifier["region"].strip.empty?
|
67
|
+
|
68
|
+
@region = @identifiers["account"].strip.downcase
|
69
|
+
end
|
70
|
+
|
71
|
+
if @overrides.key?("bucket") and @overrides["bucket"].kind_of?(String) and not @overrides["bucket"].strip.empty? then
|
72
|
+
@bucket = @overrides["bucket"]
|
73
|
+
else
|
74
|
+
raise "Mandatory identifier 'account' or override 'bucket' must be set in provided configuration to backend of type: #{@@type}" unless @identifier.key?("account")
|
75
|
+
raise "Mandatory identifier 'account' is not a string in provided configuration to backend of type: #{@@type}" unless @identifier["account"].kind_of?(String)
|
76
|
+
raise "Mandatory identifier 'account' is empty in provided configuration to backend of type: #{@@type}" if @identifier["account"].strip.empty?
|
77
|
+
|
78
|
+
@bucket = @class + "-" + @region + "-" + @identifiers["account"].strip.downcase
|
79
|
+
end
|
80
|
+
|
81
|
+
key = File.join(@identifiers.path, @service, @component + @@ext)
|
82
|
+
|
83
|
+
if key.length > 1024 then
|
84
|
+
raise "Key: #{key} is too long for backend of type: #{@@type}"
|
85
|
+
else
|
86
|
+
@key = key
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
###############################################################################
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
###############################################################################
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
###############################################################################
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
###############################################################################
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
###############################################################################
|
@@ -0,0 +1,120 @@
|
|
1
|
+
###############################################################################
|
2
|
+
|
3
|
+
module TerraformWrapper
|
4
|
+
|
5
|
+
###############################################################################
|
6
|
+
|
7
|
+
module Shared
|
8
|
+
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
module Backends
|
12
|
+
|
13
|
+
###############################################################################
|
14
|
+
|
15
|
+
class Azure < Common
|
16
|
+
|
17
|
+
###############################################################################
|
18
|
+
|
19
|
+
@@default_class = "state"
|
20
|
+
@@default_container = "default"
|
21
|
+
@@default_suffix = "tf"
|
22
|
+
|
23
|
+
###############################################################################
|
24
|
+
|
25
|
+
@@type = "azure"
|
26
|
+
|
27
|
+
###############################################################################
|
28
|
+
|
29
|
+
attr_reader :account
|
30
|
+
attr_reader :class
|
31
|
+
attr_reader :container
|
32
|
+
attr_reader :group
|
33
|
+
attr_reader :key
|
34
|
+
attr_reader :suffix
|
35
|
+
|
36
|
+
###############################################################################
|
37
|
+
|
38
|
+
def initialize(service:, code:, identifiers:, overrides: Hash.new)
|
39
|
+
construct(service: service, code: code, identifiers: identifiers, overrides: overrides)
|
40
|
+
end
|
41
|
+
|
42
|
+
###############################################################################
|
43
|
+
|
44
|
+
def hash()
|
45
|
+
return {
|
46
|
+
"container_name" => @container,
|
47
|
+
"key" => @key,
|
48
|
+
"resource_group_name" => @group,
|
49
|
+
"storage_account_name" => @account
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
###############################################################################
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
###############################################################################
|
58
|
+
|
59
|
+
def specific()
|
60
|
+
if @overrides.key?("class") and @overrides["class"].kind_of?(String) and not @overrides["class"].strip.empty? then
|
61
|
+
@class = @overrides["class"]
|
62
|
+
else
|
63
|
+
@class = @@default_class
|
64
|
+
end
|
65
|
+
|
66
|
+
if @overrides.key?("container") and @overrides["container"].kind_of?(String) and not @overrides["container"].strip.empty? then
|
67
|
+
@container = @overrides["container"]
|
68
|
+
else
|
69
|
+
@container = @@default_container
|
70
|
+
end
|
71
|
+
|
72
|
+
if @overrides.key?("suffix") and @overrides["suffix"].kind_of?(String) and not @overrides["suffix"].strip.empty? then
|
73
|
+
@suffix = @overrides["suffix"]
|
74
|
+
else
|
75
|
+
@suffix = @@default_suffix
|
76
|
+
end
|
77
|
+
|
78
|
+
if @overrides.key?("group") and @overrides["group"].kind_of?(String) and not @overrides["group"].strip.empty? then
|
79
|
+
@group = @overrides["group"]
|
80
|
+
else
|
81
|
+
raise "Mandatory identifier 'account' or override 'group' must be set in provided configuration to backend of type: #{@@type}" unless @identifier.key?("account")
|
82
|
+
raise "Mandatory identifier 'account' is not a string in provided configuration to backend of type: #{@@type}" unless @identifier["account"].kind_of?(String)
|
83
|
+
raise "Mandatory identifier 'account' is empty in provided configuration to backend of type: #{@@type}" if @identifier["account"].strip.empty?
|
84
|
+
|
85
|
+
@group = @identifiers["subscription"].strip.downcase + @suffix
|
86
|
+
end
|
87
|
+
|
88
|
+
if @overrides.key?("account") and @overrides["account"].kind_of?(String) and not @overrides["account"].strip.empty? then
|
89
|
+
@account = @overrides["account"]
|
90
|
+
else
|
91
|
+
@account = @group + "-" + @class
|
92
|
+
end
|
93
|
+
|
94
|
+
key = File.join(@identifiers.path, @service, @component + @@ext)
|
95
|
+
|
96
|
+
if key.length > 1024 then
|
97
|
+
raise "Key: #{key} is too long for backend of type: #{@@type}"
|
98
|
+
else
|
99
|
+
$logger.warning("Key for backend of type: #{@@type} exceeds 256 characters. This will not work with the Azure Storage Emulator. If key is not being overriden, consider using less identifiers.") if key.length > 256
|
100
|
+
@key = key
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
###############################################################################
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
###############################################################################
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
###############################################################################
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
###############################################################################
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
###############################################################################
|