terraform-wrapper 1.0.2 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5f6f6de51796b0d23045b3733faa6becaad7ad36abf07a653aa2bfc750623f6
4
- data.tar.gz: 83250f035ea1f126fb74f51bd171dd72b359e58df9cc39f707c38b928612f25e
3
+ metadata.gz: a2a6ef95d4f00565e776a4b2d13a6fd8d139aa2fc421725ab4f47ab19b770fbf
4
+ data.tar.gz: 6dcb4014c8b532f66d3e77bac62962ffd6d3445581070f94e99afd0d74300a84
5
5
  SHA512:
6
- metadata.gz: dd8fda5cc8485316ccd447b2ab4d713d8b78e7cee01d01f29336c15b11684ee44d0a19009b3c5dfda1e2b21d863f01f9ead3551199089870593a2fd8dd0f7f82
7
- data.tar.gz: 04bc0285f62cf3a6c8ff9e80cf38aea09a5d3e17ce78d3fe8464c16fc36eeebea5e11bd5e295629a5117a18a147f2cb0d3f6fa6596955072f969e333fd56ef2c
6
+ metadata.gz: 434ff1acb19dbddbbc2e854664a0f0bab5bcea44af9a8af17ea96e03686357c9c726532d514f5075b2065c86dca77387f41b5c9967307e75dae8562cb6b7357a
7
+ data.tar.gz: e83d68b78f98c3d98656def518a57f774bf085d8bc95e143ed28dfe19b860de6c2f7ff04de5ee0157858f7a0116afa1061dd212e2eb841a8893415509a2d3e6c
@@ -43,8 +43,12 @@ module TerraformWrapper
43
43
  config_options["backend-options"] = options.key?("config-backend-options") ? options["config-backend-options"] : Hash.new
44
44
  config_options["service"] = service
45
45
 
46
- binary = TerraformWrapper::Shared::Binary.new(options: binary_options)
47
- code = TerraformWrapper::Shared::Code.new(options: code_options)
46
+ provider_options = Hash.new
47
+ provider_options["platforms"] = options.key?("provider-platforms") ? options["provider-platforms"] : Array.new
48
+
49
+ provider = TerraformWrapper::Shared::Provider.new(options: provider_options)
50
+ binary = TerraformWrapper::Shared::Binary.new(options: binary_options, provider: provider)
51
+ code = TerraformWrapper::Shared::Code.new(options: code_options)
48
52
 
49
53
  tasks = Array.new
50
54
  tasks << TerraformWrapper::Tasks::Apply.new(binary: binary, code: code, options: config_options)
@@ -11,6 +11,7 @@ require_relative 'shared/binary'
11
11
  require_relative 'shared/code'
12
12
  require_relative 'shared/config'
13
13
  require_relative 'shared/latest'
14
+ require_relative 'shared/provider'
14
15
  require_relative 'shared/runner'
15
16
  require_relative 'shared/variables'
16
17
 
@@ -22,12 +22,13 @@ module TerraformWrapper
22
22
 
23
23
  attr_reader :base
24
24
  attr_reader :directory
25
+ attr_reader :provider
25
26
  attr_reader :platform
26
27
  attr_reader :version
27
28
 
28
29
  ###############################################################################
29
30
 
30
- def initialize(options:)
31
+ def initialize(options:, provider:)
31
32
  logger.fatal("Binary base path must be a string!") unless options["base"].kind_of?(String)
32
33
  logger.fatal("Binary base path must not be blank!") if options["base"].strip.empty?
33
34
 
@@ -39,8 +40,8 @@ module TerraformWrapper
39
40
  @version = options["version"]
40
41
 
41
42
  @platform = platform_detect
42
-
43
43
  @directory = File.join(@base, @version, @platform)
44
+ @provider = provider
44
45
  @name = "terraform"
45
46
  end
46
47
 
@@ -34,8 +34,6 @@ module TerraformWrapper
34
34
  @name = options["name"]
35
35
 
36
36
  @path = File.join(@base, @name)
37
-
38
- logger.fatal("Terraform code location: #{@path} does not exist!") unless exists
39
37
  end
40
38
 
41
39
  ###############################################################################
@@ -41,16 +41,16 @@ module TerraformWrapper
41
41
 
42
42
  @base = options["base"]
43
43
 
44
- logger.fatal("Configuration service name must be a string!") unless options["service"].kind_of?(String)
45
- logger.fatal("Configuration service name must not be blank!") if options["service"].strip.empty?
46
-
47
- @service = options["service"]
48
-
49
44
  logger.fatal("Configuration name must be a string!") unless options["name"].kind_of?(String)
50
45
  logger.fatal("Configuration name must not be blank!") if options["name"].strip.empty?
51
46
 
52
47
  @name = options["name"]
53
48
 
49
+ logger.fatal("Configuration service name must be a string!") unless options["service"].kind_of?(String)
50
+ logger.fatal("Configuration service name must not be blank!") if options["service"].strip.empty?
51
+
52
+ @service = options["service"]
53
+
54
54
  logger.fatal("Configuration authenticator for Azure enabled must be a Boolean!") unless [ true, false ].include?(options["auth-azure"])
55
55
 
56
56
  auth_azure = options["auth-azure"]
@@ -75,15 +75,28 @@ module TerraformWrapper
75
75
  logger.fatal("Invalid YAML in configuration file: #{@path}") unless yaml.kind_of?(Hash)
76
76
 
77
77
  identifiers = yaml.key?("identifiers") ? yaml["identifiers"] : Hash.new
78
- @variables = TerraformWrapper::Shared::Variables.new(config: @name, component: @code.name, service: @service, identifiers: identifiers)
79
- @variables.add_variables(variables: yaml["globals"]) if yaml.key?("globals")
78
+ @variables = TerraformWrapper::Shared::Variables.new(config: @name, component: @code.name, service: @service, identifiers: identifiers)
79
+
80
+ if yaml.key?("globals") then
81
+ logger.fatal("Key 'globals' is not a hash in configuration file: #{@path}") unless yaml["globals"].kind_of?(Hash)
82
+ globals = yaml["globals"]
83
+
84
+ @variables.add_variables(variables: globals["variables"]) if globals.key?("variables")
85
+ end
80
86
 
81
87
  if yaml.key?("terraform") then
82
88
  logger.fatal("Key 'terraform' is not a hash in configuration file: #{@path}") unless yaml["terraform"].kind_of?(Hash)
83
89
  terraform = yaml["terraform"]
84
90
 
85
- @variables.add_variables(variables: terraform["variables"]) if terraform.key?("variables")
86
- @variables.add_files(base: @base, files: terraform["files"]) if terraform.key?("files")
91
+ [ "globals", @code.name ].each do |extra|
92
+ if terraform.key?(extra) then
93
+ logger.fatal("Key '#{extra}' under 'terraform' is not a hash in configuration file: #{@path}") unless terraform[extra].kind_of?(Hash)
94
+ section = terraform[extra]
95
+
96
+ @variables.add_variables(variables: section["variables"]) if section.key?("variables")
97
+ @variables.add_files(base: @base, files: section["files"]) if section.key?("files")
98
+ end
99
+ end
87
100
  end
88
101
 
89
102
  @auths = Array.new
@@ -0,0 +1,41 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Provider
12
+
13
+ ###############################################################################
14
+
15
+ include TerraformWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ attr_reader :platforms
20
+
21
+ ###############################################################################
22
+
23
+ def initialize(options:)
24
+ logger.fatal("Provider platforms to prefetch hashs for must be an array!") unless options["platforms"].kind_of?(Array)
25
+
26
+ @platforms = options["platforms"]
27
+ end
28
+
29
+ ###############################################################################
30
+
31
+ end
32
+
33
+ ###############################################################################
34
+
35
+ end
36
+
37
+ ###############################################################################
38
+
39
+ end
40
+
41
+ ###############################################################################
@@ -14,6 +14,10 @@ module TerraformWrapper
14
14
 
15
15
  include TerraformWrapper::Shared::Logging
16
16
 
17
+ ###############################################################################
18
+
19
+ @@lockfile_name = ".terraform.lock.hcl"
20
+
17
21
  ###############################################################################
18
22
 
19
23
  attr_reader :binary
@@ -25,6 +29,8 @@ module TerraformWrapper
25
29
  ###############################################################################
26
30
 
27
31
  def initialize(binary:, code:)
32
+ logger.fatal("Terraform code location: #{code.path} does not exist!") unless code.check
33
+
28
34
  @binary = binary
29
35
  @code = code
30
36
 
@@ -33,35 +39,13 @@ module TerraformWrapper
33
39
 
34
40
  ###############################################################################
35
41
 
36
- def download(upgrade: false)
42
+ def download
37
43
  parameters = Array.new
38
44
  parameters.append("-backend=false")
39
- parameters.append("-upgrade") if upgrade
40
-
41
- @downloaded = run(action: "init", parameters: parameters)
42
- logger.fatal("Failed to download Terraform modules.") unless @downloaded
43
- end
44
-
45
- ###############################################################################
46
45
 
47
- def import(address: nil, id: nil)
48
- logger.fatal("Cannot Terraform import before initialising backend!") unless initialised
49
-
50
- logger.fatal("Terraform state address for import must be a string!") unless address.kind_of?(String)
51
- logger.fatal("Terraform state address for import must be a string!") unless address.kind_of?(String)
52
- logger.fatal("Terraform state address for import must not be blank!") if address.strip.empty?
46
+ logger.fatal("Failed to download Terraform modules.") unless run(action: "init", parameters: parameters)
53
47
 
54
- logger.fatal("Identification for infrastructure to import must be a string!") unless id.kind_of?(String)
55
- logger.fatal("Identification for infrastructure to import must not be blank!") if id.strip.empty?
56
-
57
- parameters = Array.new
58
- parameters.concat(variable_files)
59
- parameters.concat(variable_strings)
60
-
61
- parameters.append("'#{address}'")
62
- parameters.append("'#{id}'")
63
-
64
- logger.fatal("Terraform import failed!") unless run(action: "import", parameters: parameters)
48
+ @downloaded = true
65
49
  end
66
50
 
67
51
  ###############################################################################
@@ -76,28 +60,36 @@ module TerraformWrapper
76
60
 
77
61
  config.auths.map(&:auth)
78
62
 
63
+ logger.fatal("Failed to initialise Terraform with backend.") unless run(action: "init", parameters: parameters)
64
+
79
65
  @config = config
80
- @initialised = run(action: "init", parameters: parameters)
81
- logger.fatal("Failed to initialise Terraform with backend.") unless @initialised
66
+ @initialised = true
82
67
  end
83
68
 
84
69
  ###############################################################################
85
70
 
86
- def plan(destroy: false, file: nil)
87
- logger.fatal("Cannot Terraform plan before initialising backend!") unless initialised
71
+ def upgrade
72
+ lockfile_path = File.join(@code.path, @@lockfile_name)
73
+
74
+ if File.file?(lockfile_path)
75
+ logger.info("Removing lock file: #{lockfile_path}")
76
+ File.delete(lockfile_path)
77
+ end
78
+
79
+ logger.fatal("Lock file removal failed!") if File.file?(lockfile_path)
88
80
 
89
81
  parameters = Array.new
90
- parameters.concat(variable_files)
91
- parameters.concat(variable_strings)
82
+ parameters.append("-update")
83
+ logger.fatal("Failed to upgrade Terraform modules!") unless run(action: "get", parameters: parameters)
92
84
 
93
- if not file.nil? and file.kind_of?(String) and not file.strip.empty? then
94
- logger.fatal("Failed to create plan directory: #{directory}") unless ::TerraformWrapper.create_directory(directory: File.dirname(file), purpose: "plan")
95
- parameters.append("-out=\"#{file}\"")
96
- end
85
+ parameters = Array.new
86
+ parameters.append("lock")
97
87
 
98
- parameters.append("-destroy") if destroy
88
+ @binary.provider.platforms.each do |platform|
89
+ parameters.append("-platform=\"#{platform}\"")
90
+ end
99
91
 
100
- logger.fatal("Terraform plan failed!") unless run(action: "plan", parameters: parameters)
92
+ logger.fatal("Failed to upgrade Terraform providers!") unless run(action: "providers", parameters: parameters)
101
93
  end
102
94
 
103
95
  ###############################################################################
@@ -120,6 +112,25 @@ module TerraformWrapper
120
112
  logger.fatal("Terraform apply failed!") unless run(action: "apply", parameters: parameters)
121
113
  end
122
114
 
115
+ ###############################################################################
116
+
117
+ def plan(destroy: false, file: nil)
118
+ logger.fatal("Cannot Terraform plan before initialising backend!") unless initialised
119
+
120
+ parameters = Array.new
121
+ parameters.concat(variable_files)
122
+ parameters.concat(variable_strings)
123
+
124
+ if not file.nil? and file.kind_of?(String) and not file.strip.empty? then
125
+ logger.fatal("Failed to create plan directory: #{directory}") unless ::TerraformWrapper.create_directory(directory: File.dirname(file), purpose: "plan")
126
+ parameters.append("-out=\"#{file}\"")
127
+ end
128
+
129
+ parameters.append("-destroy") if destroy
130
+
131
+ logger.fatal("Terraform plan failed!") unless run(action: "plan", parameters: parameters)
132
+ end
133
+
123
134
  ###############################################################################
124
135
 
125
136
  def destroy
@@ -133,6 +144,28 @@ module TerraformWrapper
133
144
  logger.fatal("Terraform destroy failed!") unless run(action: "destroy", parameters: parameters)
134
145
  end
135
146
 
147
+ ###############################################################################
148
+
149
+ def import(address: nil, id: nil)
150
+ logger.fatal("Cannot Terraform import before initialising backend!") unless initialised
151
+
152
+ logger.fatal("Terraform state address for import must be a string!") unless address.kind_of?(String)
153
+ logger.fatal("Terraform state address for import must be a string!") unless address.kind_of?(String)
154
+ logger.fatal("Terraform state address for import must not be blank!") if address.strip.empty?
155
+
156
+ logger.fatal("Identification for infrastructure to import must be a string!") unless id.kind_of?(String)
157
+ logger.fatal("Identification for infrastructure to import must not be blank!") if id.strip.empty?
158
+
159
+ parameters = Array.new
160
+ parameters.concat(variable_files)
161
+ parameters.concat(variable_strings)
162
+
163
+ parameters.append("'#{address}'")
164
+ parameters.append("'#{id}'")
165
+
166
+ logger.fatal("Terraform import failed!") unless run(action: "import", parameters: parameters)
167
+ end
168
+
136
169
  ###############################################################################
137
170
 
138
171
  def validate
@@ -144,6 +177,27 @@ module TerraformWrapper
144
177
 
145
178
  private
146
179
 
180
+ ###############################################################################
181
+
182
+ def run(action:, parameters: Array.new)
183
+ result = false
184
+
185
+ parameters.reject! { |item| not item.kind_of?(String) or item.strip.empty? }
186
+
187
+ cmdline = [ "\"#{@binary.path}\"", action ].concat(parameters).join(" ")
188
+
189
+ logger.info("Starting Terraform, action: #{action}")
190
+
191
+ puts("\n" + ('#' * 80) + "\n\n")
192
+
193
+ Dir.chdir(@code.path)
194
+ result = system(cmdline) || false
195
+
196
+ puts("\n" + ('#' * 80) + "\n\n")
197
+
198
+ return result
199
+ end
200
+
147
201
  ###############################################################################
148
202
 
149
203
  def variable_files
@@ -172,27 +226,6 @@ module TerraformWrapper
172
226
  return result
173
227
  end
174
228
 
175
- ###############################################################################
176
-
177
- def run(action:, parameters: Array.new)
178
- result = false
179
-
180
- parameters.reject! { |item| not item.kind_of?(String) or item.strip.empty? }
181
-
182
- cmdline = [ "\"#{@binary.path}\"", action ].concat(parameters).join(" ")
183
-
184
- logger.info("Starting Terraform, action: #{action}")
185
-
186
- puts("\n" + ('#' * 80) + "\n\n")
187
-
188
- Dir.chdir(@code.path)
189
- result = system(cmdline) || false
190
-
191
- puts("\n" + ('#' * 80) + "\n\n")
192
-
193
- return result
194
- end
195
-
196
229
  ###############################################################################
197
230
 
198
231
  end
@@ -36,11 +36,11 @@ module TerraformWrapper
36
36
  @core[:config] = config
37
37
  @core[:service] = service
38
38
 
39
- user = cleanse(variables: identifiers, reserved: @core.keys)
39
+ user = cleanse(variables: identifiers, reserved: @core.keys, downcase: true)
40
40
  merged = @core.merge(user)
41
41
 
42
42
  @identifiers = sort ? merged.sort.to_h : merged
43
- @values = @identifiers
43
+ @values = Hash.new
44
44
  @files = Array.new
45
45
  end
46
46
 
@@ -89,7 +89,7 @@ module TerraformWrapper
89
89
  ###############################################################################
90
90
 
91
91
  def clear_variables()
92
- @values = @identifers
92
+ @values = Hash.new
93
93
  end
94
94
 
95
95
  ###############################################################################
@@ -98,17 +98,20 @@ module TerraformWrapper
98
98
 
99
99
  ###############################################################################
100
100
 
101
- def cleanse(variables:, reserved:)
101
+ def cleanse(variables:, reserved:, downcase: false)
102
102
  result = Hash.new
103
103
 
104
104
  variables.keys.each do |key|
105
105
  logger.fatal("Could not clean variables hash. All keys MUST be strings!") unless key.kind_of?(String)
106
- logger.fatal("Could not clean variables hash, key: #{key.downcase} is reserved or already in use and cannot be used!") if reserved.include?(key.downcase.to_sym)
107
- logger.fatal("Could not clean variables hash, duplicate key found: #{key.downcase}!") if result.key?(key.downcase.to_sym)
108
- logger.fatal("Could not clean variables hash, value for: #{key.downcase} is not a string!") unless variables[key].kind_of?(String)
109
- logger.fatal("Could not clean variables hash, value for: #{key.downcase} is empty!") if variables[key].strip.empty?
110
106
 
111
- result[key.downcase.to_sym] = variables[key].strip
107
+ sym = downcase ? key.downcase.to_sym : key.to_sym
108
+
109
+ logger.fatal("Could not clean variables hash, key: #{sym.to_s} is reserved or already in use and cannot be used!") if reserved.include?(sym)
110
+ logger.fatal("Could not clean variables hash, duplicate key found: #{sym.to_s}!") if result.key?(sym)
111
+ logger.fatal("Could not clean variables hash, value for: #{sym.to_s} is not a string!") unless variables[key].kind_of?(String)
112
+ logger.fatal("Could not clean variables hash, value for: #{sym.to_s} is empty!") if variables[key].strip.empty?
113
+
114
+ result[sym] = variables[key].strip
112
115
  end
113
116
 
114
117
  return result
@@ -34,12 +34,12 @@ module TerraformWrapper
34
34
 
35
35
  def upgrade_task
36
36
  desc "Upgrades the Terraform infrastructure component modules, providers and lock file."
37
- task :upgrade => :binary do |t, args|
37
+ task :upgrade => [:binary] do |t, args|
38
38
  runner = TerraformWrapper::Shared::Runner.new(binary: @binary, code: @code)
39
39
 
40
40
  logger.info("Upgrading Terraform component: #{@code.name}...")
41
41
 
42
- runner.download(upgrade: true)
42
+ runner.upgrade
43
43
  end
44
44
  end
45
45
 
@@ -4,7 +4,7 @@ module TerraformWrapper
4
4
 
5
5
  ###############################################################################
6
6
 
7
- VERSION = "1.0.2"
7
+ VERSION = "1.2.4"
8
8
 
9
9
  ###############################################################################
10
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terraform-wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Lees
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-09 00:00:00.000000000 Z
11
+ date: 2021-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -71,6 +71,7 @@ files:
71
71
  - lib/terraform-wrapper/shared/latest.rb
72
72
  - lib/terraform-wrapper/shared/logger.rb
73
73
  - lib/terraform-wrapper/shared/logging.rb
74
+ - lib/terraform-wrapper/shared/provider.rb
74
75
  - lib/terraform-wrapper/shared/runner.rb
75
76
  - lib/terraform-wrapper/shared/variables.rb
76
77
  - lib/terraform-wrapper/tasks.rb
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
108
  - !ruby/object:Gem::Version
108
109
  version: '0'
109
110
  requirements: []
110
- rubygems_version: 3.2.3
111
+ rubygems_version: 3.2.15
111
112
  signing_key:
112
113
  specification_version: 4
113
114
  summary: A ruby wrapper for managing Terraform binaries and remote state.