kitchen-terraform 0.2.0 → 0.3.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -3
- data/README.md +31 -28
- data/lib/kitchen/driver/terraform.rb +24 -8
- data/lib/kitchen/provisioner/terraform.rb +20 -144
- data/lib/kitchen/verifier/terraform.rb +32 -19
- data/lib/terraform/apply_command.rb +2 -2
- data/lib/terraform/apply_timeout_config.rb +34 -0
- data/lib/terraform/client.rb +76 -0
- data/lib/terraform/color_config.rb +34 -0
- data/lib/terraform/color_switch.rb +6 -2
- data/lib/terraform/command.rb +22 -27
- data/lib/terraform/command_executor.rb +41 -0
- data/lib/terraform/command_extender.rb +27 -0
- data/lib/terraform/configurable.rb +25 -10
- data/lib/terraform/directory_config.rb +27 -0
- data/lib/terraform/group.rb +26 -63
- data/lib/terraform/groups_config.rb +78 -0
- data/lib/terraform/inspec_runner.rb +5 -15
- data/lib/terraform/output_command.rb +13 -6
- data/lib/terraform/plan_command.rb +3 -4
- data/lib/terraform/plan_config.rb +27 -0
- data/lib/terraform/show_command.rb +39 -0
- data/lib/terraform/state_config.rb +27 -0
- data/lib/terraform/validate_command.rb +4 -0
- data/lib/terraform/variable_files_config.rb +33 -0
- data/lib/terraform/variables_config.rb +47 -0
- data/lib/terraform/version.rb +1 -1
- data/lib/terraform/version_command.rb +4 -0
- data/lib/terraform/zero_seven_output.rb +33 -0
- data/lib/terraform/zero_six_output.rb +30 -0
- metadata +90 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fab118f04f2357e74aea7dc6cd9a3d41ce176e86
|
4
|
+
data.tar.gz: 1184130c5eb929bb545689877cb6b4d86896be7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2920103244e6bed6c7679692d86a21770f16cad1f6bf8346ef1db3f8f5afc78eba46105c0a7b444cedc227cce550dff0bba56c32f86dbdae23da647dfa1cbe79
|
7
|
+
data.tar.gz: e4656ec4baaf076ba378ff90db2c6972c5e25ed3de91024f72bd826c0257aac91a47c8438db1e223f68a64af19759c49ae22bacbb202153fdbb3944bac9409d9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1,3 +1 @@
|
|
1
|
-
|
2
|
-
I����I����N,��'�]�=��
|
3
|
-
��&�l�4��u���?3���:�#��z��J��^�Ӄ�w�& @���9�?Ȏ���z'�PLAdR�c�8?��<�}�-j�p�v�s8
|
1
|
+
����B]@J�Fn(D��队g���2e�,��[�����A��������7�ԯ�/W�'��`��Ѭ���~06'��o�n���prL��ۨX��U\yC�2� ("x֝?���ɭ�o����p�ת~��ă�(�Fu�"%5�w�8�0� UKT���c(��
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ kitchen-terraform is a set of [Test Kitchen] plugins for testing
|
|
13
13
|
|
14
14
|
- [Bundler] **(~> 1.12)**
|
15
15
|
|
16
|
-
- [Terraform] **(
|
16
|
+
- [Terraform] **(>= 0.6, < 0.8)**
|
17
17
|
|
18
18
|
[Ruby]: https://www.ruby-lang.org/en/index.html
|
19
19
|
|
@@ -36,18 +36,10 @@ source 'https://rubygems.org'
|
|
36
36
|
gem 'kitchen-terraform', '~> 0.1'
|
37
37
|
```
|
38
38
|
|
39
|
-
|
40
|
-
trusted certificate:
|
39
|
+
Then, use Bundler to install the gems:
|
41
40
|
|
42
41
|
```sh
|
43
|
-
|
44
|
-
https://raw.githubusercontent.com/newcontext/kitchen-terraform/master/certs/ncs-alane-public_cert.pem)
|
45
|
-
```
|
46
|
-
|
47
|
-
Then, install the bundle and verify all of the gems:
|
48
|
-
|
49
|
-
```sh
|
50
|
-
bundle install --trust-policy LowSecurity
|
42
|
+
bundle install
|
51
43
|
```
|
52
44
|
|
53
45
|
[Ruby Gem]: http://guides.rubygems.org/what-is-a-gem/index.html
|
@@ -62,6 +54,8 @@ Terraform configuration.
|
|
62
54
|
|
63
55
|
[Test Kitchen configuration]: https://docs.chef.io/config_yml_kitchen.html
|
64
56
|
|
57
|
+
Refer to [Getting Started Readme](examples/getting_started/README.md) for a detailed walkthrough of setting up and using kitchen-terraform.
|
58
|
+
|
65
59
|
Refer to the [examples directory] for a detailed example project.
|
66
60
|
|
67
61
|
[examples directory]: examples/
|
@@ -70,19 +64,22 @@ Refer to the [examples directory] for a detailed example project.
|
|
70
64
|
|
71
65
|
### Driver
|
72
66
|
|
73
|
-
The [driver] is
|
74
|
-
|
67
|
+
The [driver] is a wrapper around the [Terraform command-line interface].
|
68
|
+
It is responsible for enforcing Terraform version support and works with
|
69
|
+
the provisioner to manage the [Terraform state].
|
75
70
|
|
76
71
|
[driver]: lib/kitchen/driver/terraform.rb
|
77
72
|
|
73
|
+
[Terraform command-line interface]: https://www.terraform.io/docs/commands/index.html
|
74
|
+
|
78
75
|
[Terraform state]: https://www.terraform.io/docs/state/index.html
|
79
76
|
|
80
77
|
#### Actions
|
81
78
|
|
82
79
|
##### kitchen create
|
83
80
|
|
84
|
-
The driver
|
85
|
-
|
81
|
+
The driver ensures that the parent directories of the plan and state
|
82
|
+
files exist.
|
86
83
|
|
87
84
|
##### kitchen destroy
|
88
85
|
|
@@ -106,7 +103,10 @@ driver:
|
|
106
103
|
|
107
104
|
### Provisioner
|
108
105
|
|
109
|
-
The [provisioner] is
|
106
|
+
The [provisioner] is the bridge between Terraform and Test Kitchen. It
|
107
|
+
is responsible for managing the Test Kitchen configuration options related to
|
108
|
+
the Terraform configuration and works with the driver to manage the
|
109
|
+
Terraform state.
|
110
110
|
|
111
111
|
[provisioner]: lib/kitchen/provisioner/terraform.rb
|
112
112
|
|
@@ -114,8 +114,8 @@ The [provisioner] is responsible for creating Terraform state.
|
|
114
114
|
|
115
115
|
##### kitchen converge
|
116
116
|
|
117
|
-
The provisioner
|
118
|
-
Terraform state based on the provided Terraform configuration.
|
117
|
+
The provisioner uses the driver to apply a constructive Terraform plan
|
118
|
+
to the Terraform state based on the provided Terraform configuration.
|
119
119
|
|
120
120
|
#### Configuration
|
121
121
|
|
@@ -235,19 +235,22 @@ The default `variables` collection is empty.
|
|
235
235
|
|
236
236
|
### Verifier
|
237
237
|
|
238
|
-
The [verifier] is
|
239
|
-
instances in the Terraform state.
|
238
|
+
The [verifier] is a wrapper around [InSpec]. It is responsible for
|
239
|
+
verifying the behaviour of any server instances in the Terraform state.
|
240
240
|
|
241
241
|
[verifier]: lib/kitchen/verifier/terraform.rb
|
242
242
|
|
243
|
+
[InSpec]: http://inspec.io
|
244
|
+
|
243
245
|
#### Actions
|
244
246
|
|
245
247
|
##### kitchen verify
|
246
248
|
|
247
|
-
The verifier verifies the
|
248
|
-
state using [
|
249
|
+
The verifier verifies the test suite's configured groups of server
|
250
|
+
instances in the Terraform state using an [InSpec profiles] located in
|
251
|
+
`<Test Kitchen working directory>/test/integration/<suite name>`.
|
249
252
|
|
250
|
-
[
|
253
|
+
[InSpec profiles]: http://inspec.io/docs/reference/profiles
|
251
254
|
|
252
255
|
#### Configuration
|
253
256
|
|
@@ -259,20 +262,20 @@ configuration defined by that plugin with the exception of the `port` and
|
|
259
262
|
|
260
263
|
##### groups
|
261
264
|
|
262
|
-
A collection of group mappings containing [
|
265
|
+
A collection of group mappings containing [InSpec control] and
|
263
266
|
connection options for the different server instance groups in the
|
264
267
|
Terraform configuration.
|
265
268
|
|
266
|
-
[
|
269
|
+
[InSpec control]: http://inspec.io/docs/reference/dsl_inspec/
|
267
270
|
|
268
271
|
Each group consists of:
|
269
272
|
|
270
273
|
- a name to use for logging purposes
|
271
274
|
|
272
|
-
- a mapping of
|
273
|
-
names to define for the suite's
|
275
|
+
- a mapping of InSpec attribute names to Terraform output variable
|
276
|
+
names to define for the suite's InSpec profile
|
274
277
|
|
275
|
-
- a collection of controls to include from the suite's
|
278
|
+
- a collection of controls to include from the suite's InSpec profile
|
276
279
|
|
277
280
|
- a hostnames output variable name to use for extracting hostnames from
|
278
281
|
the Terraform state; the output value is assumed to be in CSV format
|
@@ -14,31 +14,47 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require 'fileutils'
|
17
18
|
require 'kitchen'
|
19
|
+
require 'terraform/client'
|
18
20
|
require 'terraform/configurable'
|
19
|
-
require 'terraform/version'
|
20
21
|
|
21
22
|
module Kitchen
|
22
23
|
module Driver
|
23
24
|
# Terraform state lifecycle activities manager
|
24
25
|
class Terraform < Base
|
26
|
+
include ::Terraform::Client
|
27
|
+
|
25
28
|
include ::Terraform::Configurable
|
26
29
|
|
27
30
|
kitchen_driver_api_version 2
|
28
31
|
|
29
|
-
plugin_version ::Terraform::VERSION
|
30
|
-
|
31
32
|
no_parallel_for
|
32
33
|
|
33
34
|
def create(_state = nil)
|
34
|
-
|
35
|
+
%i(plan state)
|
36
|
+
.each { |option| FileUtils.mkdir_p File.dirname provisioner[option] }
|
35
37
|
end
|
36
38
|
|
37
39
|
def destroy(_state = nil)
|
38
|
-
provisioner.
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
return if !File.exist?(provisioner[:state]) || current_state.empty?
|
41
|
+
|
42
|
+
create
|
43
|
+
validate_configuration_files
|
44
|
+
download_modules
|
45
|
+
plan_execution destroy: true
|
46
|
+
apply_execution_plan
|
47
|
+
end
|
48
|
+
|
49
|
+
def verify_dependencies
|
50
|
+
case version
|
51
|
+
when /v0\.7/
|
52
|
+
when /v0\.6/
|
53
|
+
log_deprecation aspect: 'v0.6', remediation: 'Update to v0.7',
|
54
|
+
version: '1.0'
|
55
|
+
else
|
56
|
+
raise Kitchen::UserError, 'Only Terraform v0.7 and v0.6 are supported'
|
57
|
+
end
|
42
58
|
end
|
43
59
|
end
|
44
60
|
end
|
@@ -15,166 +15,42 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
17
|
require 'kitchen'
|
18
|
-
require 'terraform/
|
18
|
+
require 'terraform/apply_timeout_config'
|
19
|
+
require 'terraform/color_config'
|
19
20
|
require 'terraform/configurable'
|
20
|
-
require 'terraform/
|
21
|
-
require 'terraform/
|
22
|
-
require 'terraform/
|
23
|
-
require 'terraform/
|
24
|
-
require 'terraform/
|
25
|
-
require 'terraform/version'
|
26
|
-
require 'terraform/version_command'
|
21
|
+
require 'terraform/directory_config'
|
22
|
+
require 'terraform/plan_config'
|
23
|
+
require 'terraform/state_config'
|
24
|
+
require 'terraform/variable_files_config'
|
25
|
+
require 'terraform/variables_config'
|
27
26
|
|
28
27
|
module Kitchen
|
29
28
|
module Provisioner
|
30
29
|
# Terraform configuration applier
|
31
30
|
class Terraform < Base
|
32
|
-
|
31
|
+
include ::Terraform::ApplyTimeoutConfig
|
33
32
|
|
34
|
-
include ::Terraform::
|
35
|
-
|
36
|
-
kitchen_provisioner_api_version 2
|
37
|
-
|
38
|
-
plugin_version ::Terraform::VERSION
|
39
|
-
|
40
|
-
required_config :apply_timeout do |_, value, provisioner|
|
41
|
-
provisioner.coerce_apply_timeout value: value
|
42
|
-
end
|
43
|
-
|
44
|
-
default_config :apply_timeout, 600
|
33
|
+
include ::Terraform::ColorConfig
|
45
34
|
|
46
|
-
|
47
|
-
|
48
|
-
required_config :color do |_, value, provisioner|
|
49
|
-
provisioner.coerce_color value: value
|
50
|
-
end
|
51
|
-
|
52
|
-
default_config(:directory) { |provisioner| provisioner[:kitchen_root] }
|
53
|
-
|
54
|
-
expand_path_for :directory
|
55
|
-
|
56
|
-
default_config :plan do |provisioner|
|
57
|
-
provisioner.instance_pathname filename: 'terraform.tfplan'
|
58
|
-
end
|
59
|
-
|
60
|
-
expand_path_for :plan
|
61
|
-
|
62
|
-
default_config :state do |provisioner|
|
63
|
-
provisioner.instance_pathname filename: 'terraform.tfstate'
|
64
|
-
end
|
65
|
-
|
66
|
-
expand_path_for :state
|
35
|
+
include ::Terraform::Configurable
|
67
36
|
|
68
|
-
|
69
|
-
provisioner.coerce_variable_files value: value
|
70
|
-
end
|
37
|
+
include ::Terraform::DirectoryConfig
|
71
38
|
|
72
|
-
|
39
|
+
include ::Terraform::PlanConfig
|
73
40
|
|
74
|
-
|
41
|
+
include ::Terraform::StateConfig
|
75
42
|
|
76
|
-
|
77
|
-
provisioner.coerce_variables value: value
|
78
|
-
end
|
43
|
+
include ::Terraform::VariableFilesConfig
|
79
44
|
|
80
|
-
|
45
|
+
include ::Terraform::VariablesConfig
|
81
46
|
|
82
|
-
|
83
|
-
::Terraform::ApplyCommand.execute \
|
84
|
-
logger: logger, state: config[:state], target: config[:plan],
|
85
|
-
color: config[:color], timeout: config[:apply_timeout]
|
86
|
-
end
|
47
|
+
kitchen_provisioner_api_version 2
|
87
48
|
|
88
49
|
def call(_state = nil)
|
89
|
-
validate_configuration_files
|
90
|
-
download_modules
|
91
|
-
|
92
|
-
apply_execution_plan
|
93
|
-
end
|
94
|
-
|
95
|
-
def coerce_apply_timeout(value:)
|
96
|
-
config[:apply_timeout] = Integer value
|
97
|
-
rescue ArgumentError, TypeError
|
98
|
-
config_error attribute: 'apply_timeout', expected: 'an integer'
|
99
|
-
end
|
100
|
-
|
101
|
-
def coerce_color(value:)
|
102
|
-
raise TypeError unless [TrueClass, FalseClass].include?(value.class)
|
103
|
-
config[:color] = value
|
104
|
-
rescue TypeError
|
105
|
-
config_error attribute: 'color', expected: 'a boolean'
|
106
|
-
end
|
107
|
-
|
108
|
-
def coerce_variable_files(value:)
|
109
|
-
config[:variable_files] = Array value
|
110
|
-
end
|
111
|
-
|
112
|
-
def coerce_variables(value:)
|
113
|
-
config[:variables] =
|
114
|
-
if value.is_a?(Array) || value.is_a?(String)
|
115
|
-
deprecated_variables_format value: value
|
116
|
-
else
|
117
|
-
Hash value
|
118
|
-
end
|
119
|
-
rescue ArgumentError, TypeError
|
120
|
-
config_error attribute: 'variables',
|
121
|
-
expected: 'a mapping of Terraform variable assignments'
|
122
|
-
end
|
123
|
-
|
124
|
-
def download_modules
|
125
|
-
::Terraform::GetCommand.execute logger: logger,
|
126
|
-
target: config[:directory]
|
127
|
-
end
|
128
|
-
|
129
|
-
def each_list_output(name:, &block)
|
130
|
-
output(name: name).split(',').each(&block)
|
131
|
-
end
|
132
|
-
|
133
|
-
def instance_pathname(filename:)
|
134
|
-
File.join config[:kitchen_root], '.kitchen', 'kitchen-terraform',
|
135
|
-
instance.name, filename
|
136
|
-
end
|
137
|
-
|
138
|
-
def output(name:)
|
139
|
-
::Terraform::OutputCommand
|
140
|
-
.execute logger: logger, state: config[:state], target: name, &:chomp
|
141
|
-
end
|
142
|
-
|
143
|
-
def plan_constructive_execution
|
144
|
-
::Terraform::PlanCommand
|
145
|
-
.execute destroy: false, logger: logger, out: config[:plan],
|
146
|
-
state: config[:state], target: config[:directory],
|
147
|
-
variables: config[:variables], color: config[:color],
|
148
|
-
variable_files: config[:variable_files]
|
149
|
-
end
|
150
|
-
|
151
|
-
def plan_destructive_execution
|
152
|
-
::Terraform::PlanCommand
|
153
|
-
.execute destroy: true, logger: logger, out: config[:plan],
|
154
|
-
state: config[:state], target: config[:directory],
|
155
|
-
variables: config[:variables], color: config[:color],
|
156
|
-
variable_files: config[:variable_files]
|
157
|
-
end
|
158
|
-
|
159
|
-
def validate_configuration_files
|
160
|
-
::Terraform::ValidateCommand.execute logger: logger,
|
161
|
-
target: config[:directory]
|
162
|
-
end
|
163
|
-
|
164
|
-
def validate_version
|
165
|
-
::Terraform::VersionCommand.execute logger: logger do |output|
|
166
|
-
raise UserError,
|
167
|
-
"Terraform version must match #{SUPPORTED_VERSION}" unless
|
168
|
-
SUPPORTED_VERSION.match output
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
private
|
173
|
-
|
174
|
-
def deprecated_variables_format(value:)
|
175
|
-
config_deprecated attribute: 'variables',
|
176
|
-
expected: 'a mapping rather than a list or string'
|
177
|
-
Hash[Array(value).map { |string| string.split '=' }]
|
50
|
+
driver.validate_configuration_files
|
51
|
+
driver.download_modules
|
52
|
+
driver.plan_execution destroy: false
|
53
|
+
driver.apply_execution_plan
|
178
54
|
end
|
179
55
|
end
|
180
56
|
end
|
@@ -14,10 +14,9 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require 'kitchen'
|
18
17
|
require 'kitchen/verifier/inspec'
|
19
18
|
require 'terraform/configurable'
|
20
|
-
require 'terraform/
|
19
|
+
require 'terraform/groups_config'
|
21
20
|
|
22
21
|
module Kitchen
|
23
22
|
module Verifier
|
@@ -26,38 +25,52 @@ module Kitchen
|
|
26
25
|
class Terraform < Inspec
|
27
26
|
include ::Terraform::Configurable
|
28
27
|
|
28
|
+
include ::Terraform::GroupsConfig
|
29
|
+
|
29
30
|
kitchen_verifier_api_version 2
|
30
31
|
|
31
|
-
|
32
|
+
def add_targets(runner:)
|
33
|
+
collect_tests.each { |test| runner.add_target test }
|
34
|
+
end
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
def call(state)
|
37
|
+
self.inspec_runner_options = runner_options transport, state
|
38
|
+
config[:groups].each { |group| group.evaluate verifier: self }
|
35
39
|
end
|
36
40
|
|
37
|
-
|
41
|
+
def execute
|
42
|
+
::Terraform::InspecRunner.new(inspec_runner_options)
|
43
|
+
.tap do |inspec_runner|
|
44
|
+
inspec_runner.evaluate verifier: self
|
45
|
+
end
|
46
|
+
end
|
38
47
|
|
39
|
-
def
|
40
|
-
|
41
|
-
group.verify_each_host options: runner_options(transport, state)
|
42
|
-
end
|
48
|
+
def merge(options:)
|
49
|
+
inspec_runner_options.merge! options
|
43
50
|
end
|
44
51
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
52
|
+
def resolve_attributes(group:)
|
53
|
+
group.each_attribute do |key, output_name|
|
54
|
+
group.store_attribute key: key,
|
55
|
+
value: driver.output_value(name: output_name)
|
48
56
|
end
|
49
|
-
rescue UserError
|
50
|
-
config_error attribute: 'groups',
|
51
|
-
expected: 'a collection of group mappings'
|
52
57
|
end
|
53
58
|
|
54
|
-
def
|
59
|
+
def resolve_hostnames(group:, &block)
|
60
|
+
driver.output_value list: true, name: group.hostnames, &block
|
61
|
+
end
|
62
|
+
|
63
|
+
def verify(exit_code:)
|
55
64
|
raise InstanceFailure, "Inspec Runner returns #{exit_code}" unless
|
56
65
|
exit_code.zero?
|
57
66
|
end
|
58
67
|
|
59
|
-
|
60
|
-
|
68
|
+
private
|
69
|
+
|
70
|
+
attr_accessor :inspec_runner_options
|
71
|
+
|
72
|
+
def load_needed_dependencies!
|
73
|
+
require 'terraform/inspec_runner'
|
61
74
|
end
|
62
75
|
end
|
63
76
|
end
|