terraform-wrapper 0.0.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ ###############################################################################