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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 125efdc0ccfadc12dbc06c1f2d19f94337b7e514
4
- data.tar.gz: f63a2992bfcdb73ecf9a60b0d68752b6d1dcc543
3
+ metadata.gz: fab118f04f2357e74aea7dc6cd9a3d41ce176e86
4
+ data.tar.gz: 1184130c5eb929bb545689877cb6b4d86896be7c
5
5
  SHA512:
6
- metadata.gz: 680b4c300b78faeb2992aa52b7d915dfa5ec573c77f2fa57e6dbc8d3c44f80ef831d17ee30a377ec4c870246936971e7c6192753c3a472b3bfdf5f6d3c3bf0b0
7
- data.tar.gz: ade3ff2a56a9ba6febb281de8257006462680d16540c156804128c8b842b669d9cbf772f057f5bd8cb37334f743aede63ed45f292ed937150cfd7b69dda45ce4
6
+ metadata.gz: 2920103244e6bed6c7679692d86a21770f16cad1f6bf8346ef1db3f8f5afc78eba46105c0a7b444cedc227cce550dff0bba56c32f86dbdae23da647dfa1cbe79
7
+ data.tar.gz: e4656ec4baaf076ba378ff90db2c6972c5e25ed3de91024f72bd826c0257aac91a47c8438db1e223f68a64af19759c49ae22bacbb202153fdbb3944bac9409d9
Binary file
data.tar.gz.sig CHANGED
@@ -1,3 +1 @@
1
- <z nZCZ������-0�~�>a*﹈�e8o� v櫘M���h1�=DԬ��'��X��ø�zIu��ZҪ�廂1K{Cˉ�y0�����M@9WP:�Z��8s��+6�w�4���{E�u�YrX�75ؓ
2
- I����I����N,��'�]�=��
3
- ��& �l�4��u���?3���:�#��z��J��^�Ӄ�w�& @���9�?Ȏ���z'�PLAdR �c�8?��<�}�-j�p�v�s8
1
+ ����B]@JFn(D��队g���2e�,��[�����A��������7�ԯ�/W�'��`��Ѭ���~06'��o�n���prL��ۨX��U\yC2� ("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] **(~> 0.6)**
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
- Before running `bundle`, the author's public key must be added as a
40
- trusted certificate:
39
+ Then, use Bundler to install the gems:
41
40
 
42
41
  ```sh
43
- gem cert --add <(curl --location --silent \
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 responsible for ensuring compatibility with Terraform and
74
- destroying existing [Terraform state].
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 validates the installed version of
85
- Terraform against the version supported by kitchen-terraform.
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 responsible for creating Terraform state.
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 applies a constructive Terraform plan to the
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 responsible for verifying the behaviour of any server
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 configured server instances in the Terraform
248
- state using [Inspec profiles].
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
- [Inspec profiles]: https://github.com/chef/inspec/blob/master/docs/profiles.rst
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 [Inspec control] and
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
- [Inspec control]: https://github.com/chef/inspec/blob/master/docs/dsl_inspec.rst
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 Inspec attribute names to Terraform output variable
273
- names to define for the suite's Inspec profile
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 Inspec profile
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
- provisioner.validate_version
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.validate_configuration_files
39
- provisioner.download_modules
40
- provisioner.plan_destructive_execution
41
- provisioner.apply_execution_plan
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/apply_command'
18
+ require 'terraform/apply_timeout_config'
19
+ require 'terraform/color_config'
19
20
  require 'terraform/configurable'
20
- require 'terraform/get_command'
21
- require 'terraform/group'
22
- require 'terraform/output_command'
23
- require 'terraform/plan_command'
24
- require 'terraform/validate_command'
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
- SUPPORTED_VERSION = /v0.6/
31
+ include ::Terraform::ApplyTimeoutConfig
33
32
 
34
- include ::Terraform::Configurable
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
- default_config :color, true
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
- required_config :variable_files do |_, value, provisioner|
69
- provisioner.coerce_variable_files value: value
70
- end
37
+ include ::Terraform::DirectoryConfig
71
38
 
72
- default_config :variable_files, []
39
+ include ::Terraform::PlanConfig
73
40
 
74
- expand_path_for :variable_files
41
+ include ::Terraform::StateConfig
75
42
 
76
- required_config :variables do |_, value, provisioner|
77
- provisioner.coerce_variables value: value
78
- end
43
+ include ::Terraform::VariableFilesConfig
79
44
 
80
- default_config :variables, {}
45
+ include ::Terraform::VariablesConfig
81
46
 
82
- def apply_execution_plan
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
- plan_constructive_execution
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/version'
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
- plugin_version ::Terraform::VERSION
32
+ def add_targets(runner:)
33
+ collect_tests.each { |test| runner.add_target test }
34
+ end
32
35
 
33
- required_config :groups do |_, value, verifier|
34
- verifier.coerce_groups value: value
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
- default_config :groups, []
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 call(state)
40
- config[:groups].each do |group|
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 coerce_groups(value:)
46
- config[:groups] = Array(value).map do |raw_group|
47
- ::Terraform::Group.new value: raw_group, verifier: self
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 evaluate(exit_code:)
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
- def populate(runner:)
60
- collect_tests.each { |test| runner.add target: test }
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