terraform-wrapper 0.0.2

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.
@@ -0,0 +1,86 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ module Backends
12
+
13
+ ###############################################################################
14
+
15
+ class Common
16
+
17
+ ###############################################################################
18
+
19
+ @@ext = ".tfstate"
20
+ @@type
21
+
22
+ ###############################################################################
23
+
24
+ @component
25
+ @identifiers
26
+ @overrides
27
+ @service
28
+
29
+ ###############################################################################
30
+
31
+ def initialize(service:, code:, identifiers:, overrides: Hash.new)
32
+ raise("This class should not be used directly! Please create a backend-specific class instead!")
33
+ end
34
+
35
+ ###############################################################################
36
+
37
+ def hash()
38
+ raise("The backend specific class should override the 'hash' method to return a hash of parameters for Terraform to set!")
39
+ end
40
+
41
+ ###############################################################################
42
+
43
+ def type()
44
+ raise("The backend specific class should set the 'type' class variable to a string!") unless @@type.kind_of?(String)
45
+
46
+ return @@type
47
+ end
48
+
49
+ ###############################################################################
50
+
51
+ private
52
+
53
+ ###############################################################################
54
+
55
+ def construct(service:, code:, identifiers:, overrides:)
56
+ @component = code.name
57
+ @identifiers = identifiers
58
+ @overrides = overrides
59
+ @service = service
60
+
61
+ specific
62
+ end
63
+
64
+ ###############################################################################
65
+
66
+ def specific()
67
+ raise("The backend specific class should override the 'specific' method to include backend specific validation and setup, or simply return 'true' if it is not required.")
68
+ end
69
+
70
+ ###############################################################################
71
+
72
+ end
73
+
74
+ ###############################################################################
75
+
76
+ end
77
+
78
+ ###############################################################################
79
+
80
+ end
81
+
82
+ ###############################################################################
83
+
84
+ end
85
+
86
+ ###############################################################################
@@ -0,0 +1,86 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ module Backends
12
+
13
+ ###############################################################################
14
+
15
+ class Local < Common
16
+
17
+ ###############################################################################
18
+
19
+ @@default_base = File.join(Dir.pwd, "state", "terraform")
20
+
21
+ ###############################################################################
22
+
23
+ @@type = "local"
24
+
25
+ ###############################################################################
26
+
27
+ attr_reader :base
28
+ attr_reader :directory
29
+ attr_reader :key
30
+ attr_reader :name
31
+ attr_reader :path
32
+
33
+ ###############################################################################
34
+
35
+ def initialize(service:, code:, identifiers:, overrides: Hash.new)
36
+ construct(service: service, code: code, identifiers: identifiers, overrides: overrides)
37
+ end
38
+
39
+ ###############################################################################
40
+
41
+ def hash()
42
+ return {
43
+ "path" => @path,
44
+ }
45
+ end
46
+
47
+ ###############################################################################
48
+
49
+ private
50
+
51
+ ###############################################################################
52
+
53
+ def specific()
54
+ if @overrides.key?("base") and @overrides["base"].kind_of?(String) and not @overrides["base"].strip.empty? then
55
+ @base = @overrides["base"]
56
+ else
57
+ @base = @@default_base
58
+ end
59
+
60
+ @name = @component + @@ext
61
+
62
+ directory = File.join(@base, @identifiers.path)
63
+ raise "Failed to create state directory: #{directory}" unless create_directory(directory: directory, purpose: "state")
64
+
65
+ @directory = directory
66
+ @key = File.join(@identifiers.path, @name)
67
+ @path = File.join(@directory, @name)
68
+ end
69
+
70
+ ###############################################################################
71
+
72
+ end
73
+
74
+ ###############################################################################
75
+
76
+ end
77
+
78
+ ###############################################################################
79
+
80
+ end
81
+
82
+ ###############################################################################
83
+
84
+ end
85
+
86
+ ###############################################################################
@@ -0,0 +1,102 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Binary
12
+
13
+ ###############################################################################
14
+
15
+ attr_accessor :name
16
+
17
+ ###############################################################################
18
+
19
+ attr_reader :base
20
+ attr_reader :directory
21
+ attr_reader :platform
22
+ attr_reader :version
23
+
24
+ ###############################################################################
25
+
26
+ def initialize(base:, version:)
27
+ @platform = platform_detect
28
+
29
+ @base = base
30
+ @version = version
31
+
32
+ @directory = File.join(@base, @version, @platform)
33
+ @name = "terraform"
34
+ end
35
+
36
+ ###############################################################################
37
+
38
+ def check()
39
+ result = false
40
+
41
+ if exists and executable then
42
+ result = system("\"#{path}\" version") || false
43
+ end
44
+
45
+ return result
46
+ end
47
+
48
+ ###############################################################################
49
+
50
+ def exists()
51
+ return File.exist?(path)
52
+ end
53
+
54
+ ###############################################################################
55
+
56
+ def executable()
57
+ return File.executable?(path)
58
+ end
59
+
60
+ ###############################################################################
61
+
62
+ def path()
63
+ return File.join(@directory, @name)
64
+ end
65
+
66
+ ###############################################################################
67
+
68
+ private
69
+
70
+ ###############################################################################
71
+
72
+ def platform_detect
73
+ return "darwin" if platform_is_mac
74
+ return "linux" if platform_is_linux
75
+ raise "Platform is NOT supported: #{RUBY_PLATFORM}"
76
+ end
77
+
78
+ ###############################################################################
79
+
80
+ def platform_is_mac
81
+ RUBY_PLATFORM =~ /darwin/
82
+ end
83
+
84
+ ###############################################################################
85
+
86
+ def platform_is_linux
87
+ RUBY_PLATFORM =~ /linux/
88
+ end
89
+
90
+ ###############################################################################
91
+
92
+ end
93
+
94
+ ###############################################################################
95
+
96
+ end
97
+
98
+ ###############################################################################
99
+
100
+ end
101
+
102
+ ###############################################################################
@@ -0,0 +1,54 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Code
12
+
13
+ ###############################################################################
14
+
15
+ attr_reader :base
16
+ attr_reader :name
17
+ attr_reader :path
18
+
19
+ ###############################################################################
20
+
21
+ def initialize(base:, name:)
22
+ @base = base
23
+ @name = name
24
+
25
+ @path = File.join(@base, @name)
26
+
27
+ raise "Terraform code location: #{@path} does not exist!" unless exists
28
+ end
29
+
30
+ ###############################################################################
31
+
32
+ def check()
33
+ return exists
34
+ end
35
+
36
+ ###############################################################################
37
+
38
+ def exists()
39
+ return File.directory?(@path)
40
+ end
41
+
42
+ ###############################################################################
43
+
44
+ end
45
+
46
+ ###############################################################################
47
+
48
+ end
49
+
50
+ ###############################################################################
51
+
52
+ end
53
+
54
+ ###############################################################################
@@ -0,0 +1,125 @@
1
+ ###############################################################################
2
+
3
+ require 'yaml'
4
+
5
+ ###############################################################################
6
+
7
+ module TerraformWrapper
8
+
9
+ ###############################################################################
10
+
11
+ module Shared
12
+
13
+ ###############################################################################
14
+
15
+ class Config
16
+
17
+ ###############################################################################
18
+
19
+ @@config_exts = [ "", ".yaml", ".yml" ]
20
+
21
+ ###############################################################################
22
+
23
+ @@variable_files_name = "tfvars"
24
+ @@variable_files_ext = ".tfvars"
25
+
26
+ ###############################################################################
27
+
28
+ attr_reader :backend
29
+ attr_reader :base
30
+ attr_reader :code
31
+ attr_reader :name
32
+ attr_reader :path
33
+ attr_reader :overrides
34
+ attr_reader :service
35
+ attr_reader :variable_files
36
+
37
+ ###############################################################################
38
+
39
+ def initialize(backend:, base:, code:, name:, overrides:, service:)
40
+ if not name.nil? and name.kind_of?(String) and not name.strip.empty? then
41
+ @name = name
42
+ else
43
+ raise("Configuration name not provided!")
44
+ end
45
+
46
+ @base = base
47
+ @code = code
48
+ @name = name
49
+ @overrides = overrides
50
+ @service = service
51
+
52
+ @path = find
53
+
54
+ yaml = YAML.load(File.read(@path))
55
+
56
+ raise "Invalid YAML in configuration file: #{@path}" unless yaml.kind_of?(Hash)
57
+
58
+ raise "Mandatory key 'identifiers' missing from configuration file: #{@path}" unless yaml.key?("identifiers")
59
+ raise "Mandatory key 'identifiers' is not a hash in configuration file: #{@path}" unless yaml["identifiers"].kind_of?(Hash)
60
+ raise "Mandatory key 'identifiers' is empty in provided configuration file: #{@path}" if yaml["identifiers"].empty?
61
+
62
+ identifiers = TerraformWrapper::Shared::Identifiers.new(identifiers: yaml["identifiers"])
63
+
64
+ if backend == "local" then
65
+ @backend = TerraformWrapper::Shared::Backends::Local.new(service: @service, code: @code, identifiers: identifiers, overrides: @overrides)
66
+ elsif backend == "aws" then
67
+ @backend = TerraformWrapper::Shared::Backends::AWS.new(service: @service, code: @code, identifiers: identifiers, overrides: @overrides)
68
+ elsif backend == "azure" then
69
+ @backend = TerraformWrapper::Shared::Backends::Azure.new(service: @service, code: @code, identifiers: identifiers, overrides: @overrides)
70
+ else
71
+ raise "Backend: #{backend} is not valid!"
72
+ end
73
+
74
+ @variable_files = yaml.key?("tfvars") ? tfvars(tfvars: yaml["tfvars"]) : Array.new
75
+ end
76
+
77
+ ###############################################################################
78
+
79
+ private
80
+
81
+ ###############################################################################
82
+
83
+ def find
84
+ @@config_exts.each do |config_ext|
85
+ path = File.join(@base, @name + config_ext)
86
+ return path if File.file?(path)
87
+ end
88
+
89
+ raise "Terraform configuration name: #{@name} not found in location: #{@base}!"
90
+ end
91
+
92
+ ###############################################################################
93
+
94
+ def tfvars(tfvars:)
95
+ raise("Optional key 'tfvars' must be a list of strings!") unless tfvars.kind_of?(Array)
96
+
97
+ result = Array.new
98
+
99
+ tfvars.each do |tfvar|
100
+ raise("All elements of 'tfvars' must be strings!") unless tfvar.kind_of?(String)
101
+ raise("All elements of 'tfvars' must not be blank!") if tfvar.strip.empty?
102
+ path = File.join(@base, @@variable_files_name, tfvar.strip + @@variable_files_ext)
103
+ if File.file?(path) then
104
+ result.append(path)
105
+ else
106
+ raise("Terraform variables file: #{tfvar}, path: #{path} does not exist!")
107
+ end
108
+ end
109
+
110
+ return result
111
+ end
112
+
113
+ ###############################################################################
114
+
115
+ end
116
+
117
+ ###############################################################################
118
+
119
+ end
120
+
121
+ ###############################################################################
122
+
123
+ end
124
+
125
+ ###############################################################################