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.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +2 -0
- data/Gemfile +0 -4
- data/lib/terraform-wrapper.rb +36 -16
- data/lib/terraform-wrapper/common.rb +12 -23
- data/lib/terraform-wrapper/shared.rb +7 -1
- data/lib/terraform-wrapper/shared/auths.rb +9 -0
- data/lib/terraform-wrapper/shared/auths/azure.rb +179 -0
- data/lib/terraform-wrapper/shared/auths/common.rb +95 -0
- data/lib/terraform-wrapper/shared/backends/aws.rb +71 -33
- data/lib/terraform-wrapper/shared/backends/azure.rb +38 -39
- data/lib/terraform-wrapper/shared/backends/common.rb +18 -14
- data/lib/terraform-wrapper/shared/backends/local.rb +20 -18
- data/lib/terraform-wrapper/shared/binary.rb +16 -5
- data/lib/terraform-wrapper/shared/code.rb +15 -4
- data/lib/terraform-wrapper/shared/config.rb +61 -31
- data/lib/terraform-wrapper/shared/latest.rb +11 -7
- data/lib/terraform-wrapper/shared/logger.rb +80 -0
- data/lib/terraform-wrapper/shared/logging.rb +77 -0
- data/lib/terraform-wrapper/shared/runner.rb +79 -21
- data/lib/terraform-wrapper/shared/variables.rb +66 -0
- data/lib/terraform-wrapper/tasks.rb +6 -0
- data/lib/terraform-wrapper/tasks/apply.rb +16 -18
- data/lib/terraform-wrapper/tasks/binary.rb +26 -23
- data/lib/terraform-wrapper/tasks/clean.rb +15 -15
- data/lib/terraform-wrapper/tasks/destroy.rb +16 -18
- data/lib/terraform-wrapper/tasks/import.rb +66 -0
- data/lib/terraform-wrapper/tasks/init.rb +16 -18
- data/lib/terraform-wrapper/tasks/plan.rb +16 -18
- data/lib/terraform-wrapper/tasks/plandestroy.rb +16 -18
- data/lib/terraform-wrapper/tasks/upgrade.rb +58 -0
- data/lib/terraform-wrapper/tasks/validate.rb +7 -7
- data/lib/terraform-wrapper/version.rb +1 -1
- data/terraform-wrapper.gemspec +3 -0
- metadata +39 -4
- 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
|
-
|
15
|
+
include TerraformWrapper::Shared::Logging
|
16
|
+
|
17
|
+
###############################################################################
|
18
|
+
|
20
19
|
@binary
|
21
20
|
@code
|
22
|
-
@
|
23
|
-
@overrides
|
24
|
-
@service
|
21
|
+
@options
|
25
22
|
|
26
23
|
###############################################################################
|
27
24
|
|
28
|
-
def initialize(
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@
|
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
|
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
|
-
|
40
|
+
options = @options.merge({"name" => args[:config]})
|
47
41
|
|
48
|
-
|
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
|
-
|
44
|
+
logger.info("Checking Terraform binary for platform: #{@binary.platform}, version: #{@binary.version}")
|
42
45
|
|
43
46
|
if not @binary.exists then
|
44
|
-
|
47
|
+
logger.info("Terraform binary not found. Preparing binary...")
|
45
48
|
|
46
|
-
|
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
|
-
|
71
|
+
logger.info("Terraform binary not executable. Setting permissions...")
|
69
72
|
executable(path: @binary.path)
|
70
73
|
end
|
71
74
|
|
72
|
-
|
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
|
-
|
86
|
+
logger.info("Downloading: #{uri}")
|
84
87
|
|
85
88
|
response = Net::HTTP.get_response(URI(uri))
|
86
89
|
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
119
|
-
|
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
|
-
|
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
|
-
|
134
|
+
logger.info("Extracting: #{archive}")
|
132
135
|
|
133
|
-
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
|
-
|
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
|
-
|
148
|
+
logger.info("Making executable: #{path}")
|
146
149
|
FileUtils.chmod("+x", path)
|
147
|
-
|
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
|
-
|
158
|
+
logger.info("Removing file: #{file}")
|
156
159
|
|
157
160
|
begin
|
158
161
|
File.delete(file)
|
159
162
|
rescue
|
160
|
-
|
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
|
49
|
+
desc "Cleans a Terraform infrastructure component workspace of any downloaded providers and modules."
|
50
50
|
task :clean do |t, args|
|
51
|
-
|
51
|
+
logger.info("Cleaning Terraform component: #{@code.name}...")
|
52
52
|
|
53
53
|
directory_counter = 0
|
54
54
|
@@glob_directories.each do |key, value|
|
55
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
80
|
+
logger.success("Cleaned: #{file_item_counter.to_s} files.")
|
81
81
|
end
|
82
82
|
|
83
|
-
|
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
|
-
|
100
|
+
logger.info("Deleted directory: #{directory}")
|
101
101
|
rescue
|
102
102
|
result = false
|
103
|
-
|
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
|
-
|
119
|
+
logger.info("Deleted file: #{file}")
|
120
120
|
rescue
|
121
121
|
result = false
|
122
|
-
|
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
|
-
|
15
|
+
include TerraformWrapper::Shared::Logging
|
16
|
+
|
17
|
+
###############################################################################
|
18
|
+
|
20
19
|
@binary
|
21
20
|
@code
|
22
|
-
@
|
23
|
-
@overrides
|
24
|
-
@service
|
21
|
+
@options
|
25
22
|
|
26
23
|
###############################################################################
|
27
24
|
|
28
|
-
def initialize(
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@
|
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
|
38
|
+
desc "Destroys infrastructure with Terraform for a given configuration on an infrastructure component."
|
45
39
|
task :destroy, [:config] => :binary do |t, args|
|
46
|
-
|
40
|
+
options = @options.merge({"name" => args[:config]})
|
47
41
|
|
48
|
-
|
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
|
+
###############################################################################
|