terraform-wrapper 0.0.2 → 0.2.0

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +2 -0
  3. data/Gemfile +0 -4
  4. data/lib/terraform-wrapper.rb +36 -16
  5. data/lib/terraform-wrapper/common.rb +12 -23
  6. data/lib/terraform-wrapper/shared.rb +7 -1
  7. data/lib/terraform-wrapper/shared/auths.rb +9 -0
  8. data/lib/terraform-wrapper/shared/auths/azure.rb +179 -0
  9. data/lib/terraform-wrapper/shared/auths/common.rb +95 -0
  10. data/lib/terraform-wrapper/shared/backends/aws.rb +71 -33
  11. data/lib/terraform-wrapper/shared/backends/azure.rb +38 -39
  12. data/lib/terraform-wrapper/shared/backends/common.rb +18 -14
  13. data/lib/terraform-wrapper/shared/backends/local.rb +20 -18
  14. data/lib/terraform-wrapper/shared/binary.rb +16 -5
  15. data/lib/terraform-wrapper/shared/code.rb +15 -4
  16. data/lib/terraform-wrapper/shared/config.rb +61 -31
  17. data/lib/terraform-wrapper/shared/latest.rb +11 -7
  18. data/lib/terraform-wrapper/shared/logger.rb +80 -0
  19. data/lib/terraform-wrapper/shared/logging.rb +77 -0
  20. data/lib/terraform-wrapper/shared/runner.rb +79 -21
  21. data/lib/terraform-wrapper/shared/variables.rb +66 -0
  22. data/lib/terraform-wrapper/tasks.rb +6 -0
  23. data/lib/terraform-wrapper/tasks/apply.rb +16 -18
  24. data/lib/terraform-wrapper/tasks/binary.rb +26 -23
  25. data/lib/terraform-wrapper/tasks/clean.rb +15 -15
  26. data/lib/terraform-wrapper/tasks/destroy.rb +16 -18
  27. data/lib/terraform-wrapper/tasks/import.rb +66 -0
  28. data/lib/terraform-wrapper/tasks/init.rb +16 -18
  29. data/lib/terraform-wrapper/tasks/plan.rb +16 -18
  30. data/lib/terraform-wrapper/tasks/plandestroy.rb +16 -18
  31. data/lib/terraform-wrapper/tasks/upgrade.rb +58 -0
  32. data/lib/terraform-wrapper/tasks/validate.rb +7 -7
  33. data/lib/terraform-wrapper/version.rb +1 -1
  34. data/terraform-wrapper.gemspec +3 -0
  35. metadata +39 -4
  36. data/lib/terraform-wrapper/shared/identifiers.rb +0 -70
@@ -0,0 +1,66 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ class Variables
12
+
13
+ ###############################################################################
14
+
15
+ include TerraformWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ @@reserved = [ "component", "config", "service" ]
20
+
21
+ ###############################################################################
22
+
23
+ attr_reader :values
24
+
25
+ ###############################################################################
26
+
27
+ def initialize(values: Hash.new, sort: true)
28
+ cleansed = cleanse(values: values)
29
+ @values = sort ? cleansed.sort.to_h : cleansed
30
+ end
31
+
32
+ ###############################################################################
33
+
34
+ private
35
+
36
+ ###############################################################################
37
+
38
+ def cleanse(values:)
39
+ result = Hash.new
40
+
41
+ values.keys.each do |key|
42
+ logger.fatal("Could not clean variables hash. All keys MUST be strings!") unless key.kind_of?(String)
43
+ logger.fatal("Could not clean variables hash, key: #{key.downcase} is reserved and cannot be used!") if @@reserved.include?(key.downcase)
44
+ logger.fatal("Could not clean variables hash, duplicate key found: #{key.downcase}!") if result.key?(key.downcase.to_sym)
45
+ logger.fatal("Could not clean variables hash, value for: #{key.downcase} is not a string!") unless values[key].kind_of?(String)
46
+ logger.fatal("Could not clean variables hash, value for: #{key.downcase} is empty!") if values[key].strip.empty?
47
+
48
+ result[key.downcase.to_sym] = values[key].strip
49
+ end
50
+
51
+ return result
52
+ end
53
+
54
+ ###############################################################################
55
+
56
+ end
57
+
58
+ ###############################################################################
59
+
60
+ end
61
+
62
+ ###############################################################################
63
+
64
+ end
65
+
66
+ ###############################################################################
@@ -1,12 +1,18 @@
1
1
  ###############################################################################
2
2
 
3
+ require 'rake/tasklib'
4
+
5
+ ###############################################################################
6
+
3
7
  require_relative 'tasks/apply'
4
8
  require_relative 'tasks/binary'
5
9
  require_relative 'tasks/clean'
6
10
  require_relative 'tasks/destroy'
11
+ require_relative 'tasks/import'
7
12
  require_relative 'tasks/init'
8
13
  require_relative 'tasks/plan'
9
14
  require_relative 'tasks/plandestroy'
15
+ require_relative 'tasks/upgrade'
10
16
  require_relative 'tasks/validate'
11
17
 
12
18
  ###############################################################################
@@ -1,9 +1,5 @@
1
1
  ###############################################################################
2
2
 
3
- require 'rake/tasklib'
4
-
5
- ###############################################################################
6
-
7
3
  module TerraformWrapper
8
4
 
9
5
  ###############################################################################
@@ -16,22 +12,20 @@ module TerraformWrapper
16
12
 
17
13
  ###############################################################################
18
14
 
19
- @backend
15
+ include TerraformWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
20
19
  @binary
21
20
  @code
22
- @configs
23
- @overrides
24
- @service
21
+ @options
25
22
 
26
23
  ###############################################################################
27
24
 
28
- def initialize(backend:, binary:, code:, configs:, overrides:, service:)
29
- @backend = backend
30
- @binary = binary
31
- @code = code
32
- @configs = configs
33
- @overrides = overrides
34
- @service = service
25
+ def initialize(binary:, code:, options:)
26
+ @binary = binary
27
+ @code = code
28
+ @options = options
35
29
 
36
30
  yield self if block_given?
37
31
 
@@ -41,13 +35,17 @@ module TerraformWrapper
41
35
  ###############################################################################
42
36
 
43
37
  def apply_task
44
- desc "Applies infrastructure with Terraform for a given configuration on a workspace."
38
+ desc "Applies infrastructure with Terraform for a given configuration on an infrastructure component."
45
39
  task :apply, [:config, :plan] => :binary do |t, args|
46
- $logger.info("Running Terraform apply for service: #{@service}, component: #{@code.name}...")
40
+ options = @options.merge({"name" => args[:config]})
47
41
 
48
- config = TerraformWrapper::Shared::Config.new(backend: @backend, base: @configs, code: @code, name: args[:config], overrides: @overrides, service: @service)
42
+ logger.info("Processing configuration for Terraform apply...")
43
+
44
+ config = TerraformWrapper::Shared::Config.new(code: @code, options: options)
49
45
  runner = TerraformWrapper::Shared::Runner.new(binary: @binary, code: @code)
50
46
 
47
+ logger.info("Running Terraform apply for service: #{config.service}, component: #{@code.name}...")
48
+
51
49
  runner.init(config: config)
52
50
  runner.apply(file: args[:plan])
53
51
  end
@@ -3,7 +3,6 @@
3
3
  require 'digest'
4
4
  require 'fileutils'
5
5
  require 'net/http'
6
- require 'rake/tasklib'
7
6
  require 'uri'
8
7
  require 'zip'
9
8
 
@@ -19,6 +18,10 @@ module TerraformWrapper
19
18
 
20
19
  class Binary < ::Rake::TaskLib
21
20
 
21
+ ###############################################################################
22
+
23
+ include TerraformWrapper::Shared::Logging
24
+
22
25
  ###############################################################################
23
26
 
24
27
  @binary
@@ -38,12 +41,12 @@ module TerraformWrapper
38
41
  def binary_task
39
42
  desc "Downloads and extracts the expected version of the Terraform binary if it is not already present."
40
43
  task :binary do |t, args|
41
- $logger.info("Checking Terraform binary for platform: #{@binary.platform}, version: #{@binary.version}")
44
+ logger.info("Checking Terraform binary for platform: #{@binary.platform}, version: #{@binary.version}")
42
45
 
43
46
  if not @binary.exists then
44
- $logger.info("Terraform binary not found. Preparing binary...")
47
+ logger.info("Terraform binary not found. Preparing binary...")
45
48
 
46
- raise "Failed to create binary directory: #{directory}" unless create_directory(directory: @binary.directory, purpose: "binaries")
49
+ logger.fatal("Failed to create binary directory: #{directory}") unless ::TerraformWrapper.create_directory(directory: @binary.directory, purpose: "binaries")
47
50
 
48
51
  archive_binary = "terraform"
49
52
  archive_file = "terraform_#{@binary.version}_#{@binary.platform}_amd64.zip"
@@ -65,11 +68,11 @@ module TerraformWrapper
65
68
  end
66
69
 
67
70
  if not @binary.executable then
68
- $logger.info("Terraform binary not executable. Setting permissions...")
71
+ logger.info("Terraform binary not executable. Setting permissions...")
69
72
  executable(path: @binary.path)
70
73
  end
71
74
 
72
- raise("Problem with checking the Terraform binary!") unless @binary.check
75
+ logger.fatal("Problem with checking the Terraform binary!") unless @binary.check
73
76
  end
74
77
  end
75
78
 
@@ -80,25 +83,25 @@ module TerraformWrapper
80
83
  ###############################################################################
81
84
 
82
85
  def download(path:, uri:)
83
- $logger.info("Downloading: #{uri}")
86
+ logger.info("Downloading: #{uri}")
84
87
 
85
88
  response = Net::HTTP.get_response(URI(uri))
86
89
 
87
- raise "Download request did not return HTTP status 200!" if response.code != "200"
88
- raise "Download response body is not permitted!" unless response.class.body_permitted?
89
- raise "Download response body is empty!" if response.body.nil?
90
+ logger.fatal("Download request did not return HTTP status 200!") if response.code != "200"
91
+ logger.fatal("Download response body is not permitted!") unless response.class.body_permitted?
92
+ logger.fatal("Download response body is empty!") if response.body.nil?
90
93
 
91
94
  open(path, "wb") { |file|
92
95
  file.write(response.body)
93
96
  }
94
97
 
95
- raise "Download failed!" unless File.file?(path)
98
+ logger.fatal("Download failed!") unless File.file?(path)
96
99
  end
97
100
 
98
101
  ###############################################################################
99
102
 
100
103
  def verify(file:, path:, sums:)
101
- $logger.info("Checking SHA256 for: #{file}")
104
+ logger.info("Checking SHA256 for: #{file}")
102
105
 
103
106
  result = false
104
107
 
@@ -110,41 +113,41 @@ module TerraformWrapper
110
113
  sum_file = fields["file"]
111
114
  sum_sha256 = fields["sum"]
112
115
  rescue
113
- $logger.warn("Unexpected data in sums file: #{sums}")
116
+ logger.warn("Unexpected data in sums file: #{sums}")
114
117
  next
115
118
  end
116
119
 
117
120
  if sum_file == file then
118
- $logger.info("Expected SHA256 sum: #{sum_sha256}")
119
- $logger.info("Actual SHA256 sum: #{sha256}")
121
+ logger.info("Expected SHA256 sum: #{sum_sha256}")
122
+ logger.info("Actual SHA256 sum: #{sha256}")
120
123
  result = (sum_sha256 == sha256)
121
124
  break
122
125
  end
123
126
  end
124
127
 
125
- raise "Error whilst verifying the SHA256 sum of the downloaded Terraform archive!" unless result
128
+ logger.fatal("Error whilst verifying the SHA256 sum of the downloaded Terraform archive!") unless result
126
129
  end
127
130
 
128
131
  ###############################################################################
129
132
 
130
133
  def extract(archive:, binary:, destination:)
131
- $logger.info("Extracting: #{archive}")
134
+ logger.info("Extracting: #{archive}")
132
135
 
133
- Zip::ZipFile.open(archive) do |zip|
136
+ Zip::File.open(archive) do |zip|
134
137
  zip.each do |file|
135
138
  zip.extract(file, destination) if file.name == binary
136
139
  end
137
140
  end
138
141
 
139
- raise "Extraction of Terraform binary: #{binary}, from archive: #{archive} has failed!" unless File.file?(destination)
142
+ logger.fatal("Extraction of Terraform binary: #{binary}, from archive: #{archive} has failed!") unless File.file?(destination)
140
143
  end
141
144
 
142
145
  ###############################################################################
143
146
 
144
147
  def executable(path:)
145
- $logger.info("Making executable: #{path}")
148
+ logger.info("Making executable: #{path}")
146
149
  FileUtils.chmod("+x", path)
147
- raise "Setting executable bit on file: #{path} has failed!" unless File.executable?(path)
150
+ logger.fatal("Setting executable bit on file: #{path} has failed!") unless File.executable?(path)
148
151
  end
149
152
 
150
153
  ###############################################################################
@@ -152,12 +155,12 @@ module TerraformWrapper
152
155
  def clean(archive:, sums:)
153
156
  [archive, sums].each do |file|
154
157
  if File.file?(file)
155
- $logger.info("Removing file: #{file}")
158
+ logger.info("Removing file: #{file}")
156
159
 
157
160
  begin
158
161
  File.delete(file)
159
162
  rescue
160
- $logger.error("Failed to delete: #{file}, please remove manually.")
163
+ logger.error("Failed to delete: #{file}, please remove manually.")
161
164
  end
162
165
  end
163
166
  end
@@ -1,9 +1,5 @@
1
1
  ###############################################################################
2
2
 
3
- require 'rake/tasklib'
4
-
5
- ###############################################################################
6
-
7
3
  module TerraformWrapper
8
4
 
9
5
  ###############################################################################
@@ -14,6 +10,10 @@ module TerraformWrapper
14
10
 
15
11
  class Clean < ::Rake::TaskLib
16
12
 
13
+ ###############################################################################
14
+
15
+ include TerraformWrapper::Shared::Logging
16
+
17
17
  ###############################################################################
18
18
 
19
19
  @@glob_directories = {
@@ -46,13 +46,13 @@ module TerraformWrapper
46
46
  ###############################################################################
47
47
 
48
48
  def clean_task
49
- desc "Cleans the Terraform workspace of any downloaded providers and modules."
49
+ desc "Cleans a Terraform infrastructure component workspace of any downloaded providers and modules."
50
50
  task :clean do |t, args|
51
- $logger.info("Cleaning Terraform component: #{@code.name}...")
51
+ logger.info("Cleaning Terraform component: #{@code.name}...")
52
52
 
53
53
  directory_counter = 0
54
54
  @@glob_directories.each do |key, value|
55
- $logger.info("Cleaning directories: #{key}")
55
+ logger.info("Cleaning directories: #{key}")
56
56
  directory_item_counter = 0
57
57
 
58
58
  directories = Dir.glob(File.join(@code.path, value))
@@ -62,12 +62,12 @@ module TerraformWrapper
62
62
  directory_counter += 1
63
63
  end
64
64
  end
65
- $logger.info("Cleaned: #{directory_item_counter.to_s} directories.")
65
+ logger.success("Cleaned: #{directory_item_counter.to_s} directories.")
66
66
  end
67
67
 
68
68
  file_counter = 0
69
69
  @@glob_files.each do |key, value|
70
- $logger.info("Cleaning files: #{key}")
70
+ logger.info("Cleaning files: #{key}")
71
71
  file_item_counter = 0
72
72
 
73
73
  files = Dir.glob(File.join(@code.path, value))
@@ -77,10 +77,10 @@ module TerraformWrapper
77
77
  file_counter += 1
78
78
  end
79
79
  end
80
- $logger.info("Cleaned: #{file_item_counter.to_s} files.")
80
+ logger.success("Cleaned: #{file_item_counter.to_s} files.")
81
81
  end
82
82
 
83
- $logger.info("Cleaned total: #{directory_counter.to_s} directories and: #{file_counter.to_s} files.")
83
+ logger.success("Cleaned total: #{directory_counter.to_s} directories and: #{file_counter.to_s} files.")
84
84
  end
85
85
  end
86
86
 
@@ -97,10 +97,10 @@ module TerraformWrapper
97
97
  begin
98
98
  FileUtils.remove_dir(directory)
99
99
  result = true
100
- $logger.info("Deleted directory: #{directory}")
100
+ logger.info("Deleted directory: #{directory}")
101
101
  rescue
102
102
  result = false
103
- $logger.warn("Failed to delete directory: #{directory}")
103
+ logger.warn("Failed to delete directory: #{directory}")
104
104
  end
105
105
  end
106
106
 
@@ -116,10 +116,10 @@ module TerraformWrapper
116
116
  begin
117
117
  File.delete(file)
118
118
  result = true
119
- $logger.info("Deleted file: #{file}")
119
+ logger.info("Deleted file: #{file}")
120
120
  rescue
121
121
  result = false
122
- $logger.warn("Failed to delete file: #{file}")
122
+ logger.warn("Failed to delete file: #{file}")
123
123
  end
124
124
  end
125
125
 
@@ -1,9 +1,5 @@
1
1
  ###############################################################################
2
2
 
3
- require 'rake/tasklib'
4
-
5
- ###############################################################################
6
-
7
3
  module TerraformWrapper
8
4
 
9
5
  ###############################################################################
@@ -16,22 +12,20 @@ module TerraformWrapper
16
12
 
17
13
  ###############################################################################
18
14
 
19
- @backend
15
+ include TerraformWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
20
19
  @binary
21
20
  @code
22
- @configs
23
- @overrides
24
- @service
21
+ @options
25
22
 
26
23
  ###############################################################################
27
24
 
28
- def initialize(backend:, binary:, code:, configs:, overrides:, service:)
29
- @backend = backend
30
- @binary = binary
31
- @code = code
32
- @configs = configs
33
- @overrides = overrides
34
- @service = service
25
+ def initialize(binary:, code:, options:)
26
+ @binary = binary
27
+ @code = code
28
+ @options = options
35
29
 
36
30
  yield self if block_given?
37
31
 
@@ -41,13 +35,17 @@ module TerraformWrapper
41
35
  ###############################################################################
42
36
 
43
37
  def destroy_task
44
- desc "Destroys infrastructure with Terraform for a given configuration on a workspace."
38
+ desc "Destroys infrastructure with Terraform for a given configuration on an infrastructure component."
45
39
  task :destroy, [:config] => :binary do |t, args|
46
- $logger.info("Running Terraform destroy for service: #{@service}, component: #{@code.name}...")
40
+ options = @options.merge({"name" => args[:config]})
47
41
 
48
- config = TerraformWrapper::Shared::Config.new(backend: @backend, base: @configs, code: @code, name: args[:config], overrides: @overrides, service: @service)
42
+ logger.info("Processing configuration for Terraform destroy...")
43
+
44
+ config = TerraformWrapper::Shared::Config.new(code: @code, options: options)
49
45
  runner = TerraformWrapper::Shared::Runner.new(binary: @binary, code: @code)
50
46
 
47
+ logger.info("Running Terraform destroy for service: #{config.service}, component: #{@code.name}...")
48
+
51
49
  runner.init(config: config)
52
50
  runner.destroy
53
51
  end
@@ -0,0 +1,66 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Tasks
8
+
9
+ ###############################################################################
10
+
11
+ class Import < ::Rake::TaskLib
12
+
13
+ ###############################################################################
14
+
15
+ include TerraformWrapper::Shared::Logging
16
+
17
+ ###############################################################################
18
+
19
+ @binary
20
+ @code
21
+ @options
22
+
23
+ ###############################################################################
24
+
25
+ def initialize(binary:, code:, options:)
26
+ @binary = binary
27
+ @code = code
28
+ @options = options
29
+
30
+ yield self if block_given?
31
+
32
+ import_task
33
+ end
34
+
35
+ ###############################################################################
36
+
37
+ def import_task
38
+ desc "Import a piece of existing infrastructure into Terraform state for a given configuration on an infrastructure component."
39
+ task :import, [:config, :address, :id] => :binary do |t, args|
40
+ options = @options.merge({"name" => args[:config]})
41
+
42
+ logger.info("Processing configuration for Terraform import...")
43
+
44
+ config = TerraformWrapper::Shared::Config.new(code: @code, options: options)
45
+ runner = TerraformWrapper::Shared::Runner.new(binary: @binary, code: @code)
46
+
47
+ logger.info("Running Terraform import for service: #{config.service}, component: #{@code.name}...")
48
+
49
+ runner.init(config: config)
50
+ runner.import(address: args[:address], id: args[:id])
51
+ end
52
+ end
53
+
54
+ ###############################################################################
55
+
56
+ end
57
+
58
+ ###############################################################################
59
+
60
+ end
61
+
62
+ ###############################################################################
63
+
64
+ end
65
+
66
+ ###############################################################################