kitchen-terraform 0.5.1 → 0.6.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 +2 -2
- data/README.md +61 -6
- data/lib/kitchen/driver/terraform.rb +37 -22
- data/lib/kitchen/provisioner/terraform.rb +14 -18
- data/lib/kitchen/verifier/terraform.rb +25 -48
- data/lib/terraform/apply_command.rb +11 -20
- data/lib/terraform/apply_timeout_config.rb +9 -11
- data/lib/terraform/cli_config.rb +29 -0
- data/lib/terraform/client.rb +57 -52
- data/lib/terraform/color_coercer.rb +35 -0
- data/lib/terraform/color_config.rb +9 -11
- data/lib/terraform/command.rb +16 -30
- data/lib/terraform/command_factory.rb +111 -0
- data/lib/terraform/command_option.rb +65 -0
- data/lib/terraform/command_options.rb +95 -0
- data/lib/terraform/configurable.rb +42 -17
- data/lib/terraform/{zero_six_output.rb → debug_logger.rb} +10 -7
- data/lib/terraform/deprecated_output_parser.rb +41 -0
- data/lib/terraform/deprecated_variables_coercer.rb +35 -0
- data/lib/terraform/{command_extender.rb → deprecated_version.rb} +10 -7
- data/lib/terraform/destructive_plan_command.rb +35 -0
- data/lib/terraform/directory_config.rb +10 -5
- data/lib/terraform/file_configs.rb +36 -0
- data/lib/terraform/get_command.rb +3 -10
- data/lib/terraform/group.rb +29 -29
- data/lib/terraform/group_attributes.rb +42 -0
- data/lib/terraform/group_hostnames.rb +38 -0
- data/lib/terraform/groups_coercer.rb +43 -0
- data/lib/terraform/groups_config.rb +8 -54
- data/lib/terraform/integer_coercer.rb +37 -0
- data/lib/terraform/{plan_config.rb → no_output_parser.rb} +8 -7
- data/lib/terraform/output_command.rb +3 -39
- data/lib/terraform/output_parser.rb +55 -0
- data/lib/terraform/parallelism_config.rb +9 -11
- data/lib/terraform/pathname_coercer.rb +40 -0
- data/lib/terraform/plan_command.rb +7 -41
- data/lib/terraform/prepare_input_file.rb +34 -0
- data/lib/terraform/{zero_seven_output.rb → prepare_output_file.rb} +11 -9
- data/lib/terraform/project_version.rb +19 -0
- data/lib/terraform/shell_out.rb +59 -0
- data/lib/terraform/show_command.rb +7 -16
- data/lib/terraform/simple_coercer.rb +36 -0
- data/lib/terraform/{state_config.rb → simple_config.rb} +7 -6
- data/lib/terraform/{color_switch.rb → unsupported_version.rb} +6 -8
- data/lib/terraform/validate_command.rb +3 -10
- data/lib/terraform/variable_files_coercer.rb +40 -0
- data/lib/terraform/variable_files_config.rb +9 -10
- data/lib/terraform/variables_coercer.rb +49 -0
- data/lib/terraform/variables_config.rb +9 -24
- data/lib/terraform/version.rb +55 -1
- data/lib/terraform/version_command.rb +3 -10
- metadata +58 -9
- metadata.gz.sig +0 -0
- data/lib/terraform/command_executor.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ad31536d7fa989d59755d148c04a6ea0895a2f6
|
4
|
+
data.tar.gz: c817dde749927ce21795cdde40a8c9d1e65713b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7882c3a7f177c5325210d8ecb5c4681ab3c0bff524b20e0d9ff929c4f6f69ec18a72c18b25e796a05ac7c512b3b0dd3db53ac113d3a1bb0bc4f43eecb66edd22
|
7
|
+
data.tar.gz: 770b9530932c84a4ecfef885f6d2c5800d4960f225d4522301b4c8edf258baff7102bd9e5ec48e9f45cfc72fcd8e44d2a1163c54bcea010e17a511359e269c26
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
)!"��k���O��؝�L��j꾧$3+�F��O��،$��/�>����s���*��~�S�=W������S0��w�:c����`z�DR�xC�Ѽ��6n����g�lgꞾb�&�j8���w�$�6]��1| �Ѭ�9l��)�Ԫ�e��7��0���zKGgA����簃3H���t��r��QM��/�p~���O��[]d���.w�OPs�3�Z��
|
2
|
+
��k�����3
|
data/README.md
CHANGED
@@ -38,7 +38,7 @@ Once Bundler is installed, add kitchen-terraform to the project's Gemfile:
|
|
38
38
|
|
39
39
|
```rb
|
40
40
|
source 'https://rubygems.org/' do
|
41
|
-
gem 'kitchen-terraform', '~> 0.
|
41
|
+
gem 'kitchen-terraform', '~> 0.6'
|
42
42
|
end
|
43
43
|
```
|
44
44
|
|
@@ -60,7 +60,7 @@ Terraform configuration.
|
|
60
60
|
|
61
61
|
[Test Kitchen configuration]: https://docs.chef.io/config_yml_kitchen.html
|
62
62
|
|
63
|
-
Refer to [Getting Started Readme](examples/getting_started
|
63
|
+
Refer to [Getting Started Readme](examples/aws_provider/getting_started.md) for a detailed walkthrough of setting up and using kitchen-terraform.
|
64
64
|
|
65
65
|
Refer to the [examples directory] for a detailed example project.
|
66
66
|
|
@@ -97,16 +97,29 @@ provisioner.
|
|
97
97
|
|
98
98
|
#### Configuration
|
99
99
|
|
100
|
-
|
100
|
+
##### cli
|
101
101
|
|
102
|
-
|
102
|
+
The pathname of the Terraform command-line interface (CLI) executable or
|
103
|
+
an executable that implements an equivalent interface.
|
104
|
+
|
105
|
+
[command-line interface]: https://www.terraform.io/docs/commands/index.html
|
106
|
+
|
107
|
+
###### Example .kitchen.yml
|
103
108
|
|
104
109
|
```yaml
|
105
110
|
---
|
106
111
|
driver:
|
107
112
|
name: terraform
|
113
|
+
cli: /usr/local/bin/terraform
|
108
114
|
```
|
109
115
|
|
116
|
+
###### Default
|
117
|
+
|
118
|
+
The default `cli` is `'terraform'`, and is assumed to exist in the
|
119
|
+
user's [PATH].
|
120
|
+
|
121
|
+
[PATH]: http://www.linfo.org/path_env_var.html
|
122
|
+
|
110
123
|
### Provisioner
|
111
124
|
|
112
125
|
The [provisioner] is the bridge between Terraform and Test Kitchen. It
|
@@ -198,6 +211,47 @@ provisioner:
|
|
198
211
|
|
199
212
|
The default `parallelism` is 10.
|
200
213
|
|
214
|
+
##### plan
|
215
|
+
|
216
|
+
The pathname of the [execution plan] that Terraform will generate and
|
217
|
+
apply.
|
218
|
+
|
219
|
+
[execution plan]: https://www.terraform.io/docs/commands/plan.html#_out_path
|
220
|
+
|
221
|
+
###### Example .kitchen.yml
|
222
|
+
|
223
|
+
```yaml
|
224
|
+
---
|
225
|
+
provisioner:
|
226
|
+
name: terraform
|
227
|
+
plan: /terraform/plan
|
228
|
+
```
|
229
|
+
|
230
|
+
###### Default
|
231
|
+
|
232
|
+
The default `plan` is under the current working directory of Test
|
233
|
+
Kitchen at `.kitchen/kitchen-terraform/<suite_name>/terraform.tfplan`.
|
234
|
+
|
235
|
+
##### state
|
236
|
+
|
237
|
+
The pathname of the [state file] that Terraform will generate.
|
238
|
+
|
239
|
+
[state file]: https://www.terraform.io/docs/commands/apply.html#_state_out_path
|
240
|
+
|
241
|
+
###### Example .kitchen.yml
|
242
|
+
|
243
|
+
```yaml
|
244
|
+
---
|
245
|
+
provisioner:
|
246
|
+
name: terraform
|
247
|
+
state: /terraform/state
|
248
|
+
```
|
249
|
+
|
250
|
+
###### Default
|
251
|
+
|
252
|
+
The default `state` is under the current working directory of Test
|
253
|
+
Kitchen at `.kitchen/kitchen-terraform/<suite_name>/terraform.tfstate`.
|
254
|
+
|
201
255
|
##### variable_files
|
202
256
|
|
203
257
|
A collection of pathnames of [Terraform variable files] to be evaluated
|
@@ -338,8 +392,9 @@ The default `groups` collection is empty.
|
|
338
392
|
For each group:
|
339
393
|
|
340
394
|
- the default `attributes` mapping consists of equivalently named
|
341
|
-
attributes for each output variable
|
342
|
-
|
395
|
+
attributes for each output variable as well as a "terraform_state"
|
396
|
+
attribute containing the pathname of the state file; additional or
|
397
|
+
overridden associations can be added.
|
343
398
|
|
344
399
|
- the default `controls` collection is empty
|
345
400
|
|
@@ -14,16 +14,16 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require 'fileutils'
|
18
17
|
require 'kitchen'
|
19
|
-
require 'terraform/
|
18
|
+
require 'terraform/cli_config'
|
20
19
|
require 'terraform/configurable'
|
20
|
+
require 'terraform/version'
|
21
21
|
|
22
22
|
module Kitchen
|
23
23
|
module Driver
|
24
24
|
# Terraform state lifecycle activities manager
|
25
|
-
class Terraform < Base
|
26
|
-
|
25
|
+
class Terraform < ::Kitchen::Driver::Base
|
26
|
+
extend ::Terraform::CLIConfig
|
27
27
|
|
28
28
|
include ::Terraform::Configurable
|
29
29
|
|
@@ -31,31 +31,46 @@ module Kitchen
|
|
31
31
|
|
32
32
|
no_parallel_for
|
33
33
|
|
34
|
-
def create(_state = nil)
|
35
|
-
%i(plan state)
|
36
|
-
.each { |option| FileUtils.mkdir_p File.dirname provisioner[option] }
|
37
|
-
end
|
34
|
+
def create(_state = nil); end
|
38
35
|
|
39
36
|
def destroy(_state = nil)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
validate_configuration_files
|
44
|
-
download_modules
|
45
|
-
plan_execution destroy: true
|
46
|
-
apply_execution_plan
|
37
|
+
load_state { client.apply_destructively }
|
38
|
+
rescue ::Kitchen::StandardError, ::SystemCallError => error
|
39
|
+
raise ::Kitchen::ActionFailed, error.message
|
47
40
|
end
|
48
41
|
|
49
42
|
def verify_dependencies
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
43
|
+
verify_supported_version
|
44
|
+
check_deprecated_version
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def check_deprecated_version
|
50
|
+
version.if_deprecated do
|
51
|
+
log_deprecation aspect: version.to_s,
|
52
|
+
remediation: "Install #{::Terraform::Version.latest}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def load_state(&block)
|
57
|
+
silent_client.load_state(&block)
|
58
|
+
rescue ::Errno::ENOENT => error
|
59
|
+
debug error.message
|
60
|
+
end
|
61
|
+
|
62
|
+
def verify_supported_version
|
63
|
+
version.if_not_supported do
|
64
|
+
raise ::Kitchen::UserError,
|
65
|
+
"#{version} is not supported\nInstall " \
|
66
|
+
"#{::Terraform::Version.latest}"
|
57
67
|
end
|
58
68
|
end
|
69
|
+
|
70
|
+
def version
|
71
|
+
@version ||=
|
72
|
+
::Terraform::Client.new(config: self, logger: debug_logger).version
|
73
|
+
end
|
59
74
|
end
|
60
75
|
end
|
61
76
|
end
|
@@ -19,41 +19,37 @@ require 'terraform/apply_timeout_config'
|
|
19
19
|
require 'terraform/color_config'
|
20
20
|
require 'terraform/configurable'
|
21
21
|
require 'terraform/directory_config'
|
22
|
+
require 'terraform/file_configs'
|
22
23
|
require 'terraform/parallelism_config'
|
23
|
-
require 'terraform/plan_config'
|
24
|
-
require 'terraform/state_config'
|
25
24
|
require 'terraform/variable_files_config'
|
26
25
|
require 'terraform/variables_config'
|
27
26
|
|
28
27
|
module Kitchen
|
29
28
|
module Provisioner
|
30
|
-
# Terraform
|
31
|
-
class Terraform < Base
|
32
|
-
|
29
|
+
# Applies constructive Terraform plans
|
30
|
+
class Terraform < ::Kitchen::Provisioner::Base
|
31
|
+
extend ::Terraform::ApplyTimeoutConfig
|
33
32
|
|
34
|
-
|
33
|
+
extend ::Terraform::ColorConfig
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
include ::Terraform::DirectoryConfig
|
35
|
+
extend ::Terraform::DirectoryConfig
|
39
36
|
|
40
|
-
|
37
|
+
extend ::Terraform::FileConfigs
|
41
38
|
|
42
|
-
|
39
|
+
extend ::Terraform::ParallelismConfig
|
43
40
|
|
44
|
-
|
41
|
+
extend ::Terraform::VariableFilesConfig
|
45
42
|
|
46
|
-
|
43
|
+
extend ::Terraform::VariablesConfig
|
47
44
|
|
48
|
-
include ::Terraform::
|
45
|
+
include ::Terraform::Configurable
|
49
46
|
|
50
47
|
kitchen_provisioner_api_version 2
|
51
48
|
|
52
49
|
def call(_state = nil)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
driver.apply_execution_plan
|
50
|
+
client.apply_constructively
|
51
|
+
rescue ::Kitchen::StandardError, ::SystemCallError => error
|
52
|
+
raise ::Kitchen::ActionFailed, error.message
|
57
53
|
end
|
58
54
|
end
|
59
55
|
end
|
@@ -22,71 +22,48 @@ module Kitchen
|
|
22
22
|
module Verifier
|
23
23
|
# Runs tests post-converge to confirm that instances in the Terraform state
|
24
24
|
# are in an expected state
|
25
|
-
class Terraform < Inspec
|
26
|
-
|
25
|
+
class Terraform < ::Kitchen::Verifier::Inspec
|
26
|
+
extend ::Terraform::GroupsConfig
|
27
27
|
|
28
|
-
include ::Terraform::
|
28
|
+
include ::Terraform::Configurable
|
29
29
|
|
30
30
|
kitchen_verifier_api_version 2
|
31
31
|
|
32
32
|
def call(state)
|
33
|
-
|
33
|
+
resolve_groups do |group|
|
34
|
+
self.group = group
|
35
|
+
config[:attributes] = {
|
36
|
+
'terraform_state' => provisioner[:state].to_path
|
37
|
+
}.merge group.attributes
|
38
|
+
info "Verifying #{group.description}"
|
39
|
+
super
|
40
|
+
end
|
41
|
+
rescue ::Kitchen::StandardError, ::SystemCallError => error
|
42
|
+
raise ::Kitchen::ActionFailed, error.message
|
34
43
|
end
|
35
44
|
|
36
45
|
private
|
37
46
|
|
38
|
-
|
39
|
-
collect_tests.each { |test| runner.add_target test }
|
40
|
-
end
|
47
|
+
attr_accessor :group
|
41
48
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
add_targets runner: runner
|
46
|
-
validate exit_code: runner.run
|
49
|
+
def configure_backend(options:)
|
50
|
+
/(local)host/.match group.hostname do |match|
|
51
|
+
options.merge! 'backend' => match[1]
|
47
52
|
end
|
48
53
|
end
|
49
54
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
execute group: group, options: options
|
54
|
-
end
|
55
|
-
|
56
|
-
def execute_remote(group:, options:)
|
57
|
-
driver.output_value list: true, name: group.hostnames do |hostname|
|
58
|
-
options[:host] = hostname
|
59
|
-
info "Verifying host '#{hostname}' of group '#{group.name}'"
|
60
|
-
execute group: group, options: options
|
61
|
-
end
|
55
|
+
def resolve_groups(&block)
|
56
|
+
config[:groups]
|
57
|
+
.each { |group| group.resolve client: silent_client, &block }
|
62
58
|
end
|
63
59
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
group.store_attribute key: key,
|
70
|
-
value: driver.output_value(name: output_name)
|
60
|
+
def runner_options(transport, state = {}, platform = nil, suite = nil)
|
61
|
+
super.tap do |options|
|
62
|
+
options.merge! controls: group.controls, 'host' => group.hostname,
|
63
|
+
'port' => group.port, 'user' => group.username
|
64
|
+
configure_backend options: options
|
71
65
|
end
|
72
66
|
end
|
73
|
-
|
74
|
-
def validate(exit_code:)
|
75
|
-
return if exit_code.zero?
|
76
|
-
|
77
|
-
raise ::Kitchen::InstanceFailure, "Inspec Runner returns #{exit_code}"
|
78
|
-
end
|
79
|
-
|
80
|
-
def verify(group:, options:)
|
81
|
-
resolve_attributes group: group
|
82
|
-
group.if_local { return execute_local group: group, options: options }
|
83
|
-
execute_remote group: group, options: options
|
84
|
-
end
|
85
|
-
|
86
|
-
def verify_groups(options:)
|
87
|
-
config[:groups]
|
88
|
-
.each { |group| verify group: group, options: options.dup }
|
89
|
-
end
|
90
67
|
end
|
91
68
|
end
|
92
69
|
end
|
@@ -14,30 +14,21 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
require 'terraform/command'
|
18
|
+
require 'terraform/prepare_input_file'
|
19
|
+
require 'terraform/prepare_output_file'
|
19
20
|
|
20
21
|
module Terraform
|
21
|
-
#
|
22
|
-
class ApplyCommand < Command
|
23
|
-
include ColorSwitch
|
24
|
-
|
25
|
-
def name
|
26
|
-
'apply'
|
27
|
-
end
|
28
|
-
|
29
|
-
def options
|
30
|
-
"-input=false -parallelism=#{parallelism} -state=#{state} #{color_switch}"
|
31
|
-
end
|
32
|
-
|
22
|
+
# A command to apply an execution plan
|
23
|
+
class ApplyCommand < ::Terraform::Command
|
33
24
|
private
|
34
25
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
26
|
+
def initialize(target: '')
|
27
|
+
super
|
28
|
+
preparations.concat [
|
29
|
+
::Terraform::PrepareInputFile.new(file: target),
|
30
|
+
::Terraform::PrepareOutputFile.new(file: options.state)
|
31
|
+
]
|
41
32
|
end
|
42
33
|
end
|
43
34
|
end
|
@@ -14,21 +14,19 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require 'terraform/integer_coercer'
|
18
|
+
require 'terraform/simple_config'
|
19
|
+
|
17
20
|
module Terraform
|
18
21
|
# Behaviour for the [:apply_timeout] config option
|
19
22
|
module ApplyTimeoutConfig
|
20
|
-
|
21
|
-
configurable_class
|
22
|
-
.required_config :apply_timeout do |_, value, configurable|
|
23
|
-
configurable.coerce_apply_timeout value: value
|
24
|
-
end
|
25
|
-
configurable_class.default_config :apply_timeout, 600
|
26
|
-
end
|
23
|
+
include ::Terraform::SimpleConfig
|
27
24
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
def self.extended(configurable_class)
|
26
|
+
configurable_class
|
27
|
+
.configure_required attr: :apply_timeout,
|
28
|
+
coercer_class: ::Terraform::IntegerCoercer,
|
29
|
+
default_value: 600
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2016 New Context Services, Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'ptools'
|
18
|
+
|
19
|
+
module Terraform
|
20
|
+
# Behaviour for the [:cli] config option
|
21
|
+
module CLIConfig
|
22
|
+
def self.extended(configurable_class)
|
23
|
+
configurable_class.required_config :cli do |key, value, configurable|
|
24
|
+
configurable[key] = ::File.expand_path value
|
25
|
+
end
|
26
|
+
configurable_class.default_config(:cli) { ::File.which 'terraform' }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|