kitchen-terraform 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|