kitchen-terraform 0.7.0 → 1.0.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -1
  4. data/README.md +33 -359
  5. data/lib/kitchen/driver/terraform.rb +273 -57
  6. data/lib/kitchen/driver/terraform/verify_client_version.rb +44 -0
  7. data/lib/kitchen/driver/terraform/workflow.rb +90 -0
  8. data/lib/kitchen/provisioner/terraform.rb +31 -37
  9. data/lib/{terraform/get_command.rb → kitchen/terraform.rb} +3 -5
  10. data/lib/{terraform/deprecated_version.rb → kitchen/terraform/client.rb} +5 -12
  11. data/lib/kitchen/terraform/client/apply.rb +38 -0
  12. data/lib/kitchen/terraform/client/execute_command.rb +56 -0
  13. data/lib/kitchen/terraform/client/get.rb +35 -0
  14. data/lib/kitchen/terraform/client/output.rb +50 -0
  15. data/lib/kitchen/terraform/client/plan.rb +42 -0
  16. data/lib/kitchen/terraform/client/process_options.rb +87 -0
  17. data/lib/kitchen/terraform/client/validate.rb +35 -0
  18. data/lib/kitchen/terraform/client/version.rb +48 -0
  19. data/lib/{terraform/apply_timeout_config.rb → kitchen/terraform/create_directories.rb} +18 -11
  20. data/lib/kitchen/terraform/define_config_attribute.rb +39 -0
  21. data/lib/kitchen/terraform/define_integer_config_attribute.rb +43 -0
  22. data/lib/kitchen/terraform/define_string_config_attribute.rb +43 -0
  23. data/lib/kitchen/verifier/terraform.rb +186 -38
  24. data/lib/kitchen/verifier/terraform/configure_inspec_runner_attributes.rb +93 -0
  25. data/lib/kitchen/verifier/terraform/configure_inspec_runner_backend.rb +32 -0
  26. data/lib/kitchen/verifier/terraform/configure_inspec_runner_controls.rb +39 -0
  27. data/lib/{terraform/apply_command.rb → kitchen/verifier/terraform/configure_inspec_runner_host.rb} +11 -15
  28. data/lib/{terraform/deprecated_output_parser.rb → kitchen/verifier/terraform/configure_inspec_runner_port.rb} +16 -20
  29. data/lib/{terraform/deprecated_variables_coercer.rb → kitchen/verifier/terraform/configure_inspec_runner_user.rb} +16 -14
  30. data/lib/kitchen/verifier/terraform/enumerate_groups_and_hostnames.rb +67 -0
  31. data/lib/{terraform/version_command.rb → terraform.rb} +1 -5
  32. data/lib/terraform/configurable.rb +18 -61
  33. data/lib/terraform/debug_logger.rb +12 -12
  34. data/lib/terraform/project_version.rb +1 -1
  35. metadata +72 -135
  36. metadata.gz.sig +0 -0
  37. data/lib/terraform/cli_config.rb +0 -29
  38. data/lib/terraform/client.rb +0 -96
  39. data/lib/terraform/color_coercer.rb +0 -35
  40. data/lib/terraform/color_config.rb +0 -32
  41. data/lib/terraform/command.rb +0 -53
  42. data/lib/terraform/command_factory.rb +0 -111
  43. data/lib/terraform/command_option.rb +0 -65
  44. data/lib/terraform/command_options.rb +0 -103
  45. data/lib/terraform/destructive_plan_command.rb +0 -35
  46. data/lib/terraform/directory_config.rb +0 -32
  47. data/lib/terraform/file_configs.rb +0 -36
  48. data/lib/terraform/group.rb +0 -61
  49. data/lib/terraform/group_attributes.rb +0 -42
  50. data/lib/terraform/group_hostnames.rb +0 -38
  51. data/lib/terraform/groups_coercer.rb +0 -43
  52. data/lib/terraform/groups_config.rb +0 -32
  53. data/lib/terraform/integer_coercer.rb +0 -37
  54. data/lib/terraform/no_output_parser.rb +0 -28
  55. data/lib/terraform/output_command.rb +0 -23
  56. data/lib/terraform/output_parser.rb +0 -55
  57. data/lib/terraform/parallelism_config.rb +0 -32
  58. data/lib/terraform/pathname_coercer.rb +0 -40
  59. data/lib/terraform/plan_command.rb +0 -30
  60. data/lib/terraform/prepare_input_file.rb +0 -34
  61. data/lib/terraform/prepare_output_file.rb +0 -36
  62. data/lib/terraform/shell_out.rb +0 -59
  63. data/lib/terraform/show_command.rb +0 -30
  64. data/lib/terraform/simple_coercer.rb +0 -36
  65. data/lib/terraform/simple_config.rb +0 -28
  66. data/lib/terraform/unsupported_version.rb +0 -26
  67. data/lib/terraform/validate_command.rb +0 -23
  68. data/lib/terraform/variable_files_coercer.rb +0 -40
  69. data/lib/terraform/variable_files_config.rb +0 -32
  70. data/lib/terraform/variables_coercer.rb +0 -49
  71. data/lib/terraform/variables_config.rb +0 -32
  72. data/lib/terraform/version.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1b74665cdd2f600d9baab71615afcc2f514e2e2
4
- data.tar.gz: 1f473db97e5328bdc08d380e0ea31dc2fd1ee3da
3
+ metadata.gz: a7c30b59401be69f125e4b9ac0d57b91d2152c5c
4
+ data.tar.gz: 7f46bce8b7f4bfaec2c82f1ae1f522ddf9ba3baa
5
5
  SHA512:
6
- metadata.gz: 852b9d8ee05805080905138c2fd1936b4827d5dbfe41c291e90b7abcbff86a183fdd9eac0fc03f1e432e2db366413fc1c3b722f8ad9bc8c746b0408b5452931e
7
- data.tar.gz: 64748a06ccf9b202a100bb6a9a651884e60e4a3a723aeb91f2ff0c5c30f6b1d0eb6e54f0ff8ef236dc13d3aed1dc0d87f45f13b9d0692fba866bde04fa25ef15
6
+ metadata.gz: 7c235d1d29893628ee848e48b6ad087b01358cea304b004a9c56b90fb5b23cc5d5ad0ecace68e76feec8206a7202fca61500e8d07408c6068b7a13ec88e51546
7
+ data.tar.gz: fada5a0befd2b5be3de085dd7a22be9b2b80185ceae98f32ca1f8e03036f1e81faa48c89f590be220ceef327bf1c69c8adecd0414ec5c4787abd0553b4d92bc1
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
@@ -1 +1,3 @@
1
- <�ON`|��%;A���܎��텣���=��=��.���ci��&!KYd)!e��B����P�#X��}��kN��(���(K���9d4����ʋ]����[�����I,\����o���-��)�6״V��*���iA��Շ� �XIf��v�lLD�5���'HW�l�ԅ���!��No�ݲ⃵����{��{h��X����HɭTa�=�������VH�O�\ϛ���w�t���83�����
1
+ e��J].�0��!���@�eD^E�� %�O4
2
+ �kIH�WaX��S)���:��6^
3
+ �o�<v��-���l�����1b�1�p6'�X�HBL<k����Ӵm$;0��̄d[_�f�ˆ�d���u�~���G�yPZ��z�{�3�����/\Td�w�C�[P�v���ާR�r�1j���RQ�~:��R &޳M�S�LO���zj׬�ą���}NUػ�U�0B<B�Ml܍�y�j���
data/README.md CHANGED
@@ -9,23 +9,13 @@
9
9
  kitchen-terraform is a set of [Test Kitchen] plugins for testing
10
10
  [Terraform configuration].
11
11
 
12
- [Test Kitchen]: http://kitchen.ci/index.html
13
-
14
- [Terraform configuration]: https://www.terraform.io/docs/configuration/index.html
15
-
16
12
  ## Requirements
17
13
 
18
14
  - [Ruby] **(~> 2.1)**
19
15
 
20
16
  - [Bundler] **(~> 1.12)**
21
17
 
22
- - [Terraform] **(>= 0.6, < 0.10)**
23
-
24
- [Ruby]: https://www.ruby-lang.org/en/index.html
25
-
26
- [Bundler]: https://bundler.io/index.html
27
-
28
- [Terraform]: https://www.terraform.io/index.html
18
+ - [Terraform] **(>= 0.7, < 0.10)**
29
19
 
30
20
  ## Installation
31
21
 
@@ -34,11 +24,12 @@ which means it can be [installed with Bundler].
34
24
 
35
25
  ### Adding kitchen-terraform to a Terraform project
36
26
 
37
- Once Bundler is installed, add kitchen-terraform to the project's Gemfile:
27
+ Once Bundler is installed, add kitchen-terraform to the project's
28
+ Gemfile:
38
29
 
39
30
  ```rb
40
- source 'https://rubygems.org/' do
41
- gem 'kitchen-terraform', '~> 0.7'
31
+ source "https://rubygems.org/" do
32
+ gem "kitchen-terraform", "~> 1.0"
42
33
  end
43
34
  ```
44
35
 
@@ -48,358 +39,41 @@ Then, use Bundler to install the gems:
48
39
  bundle install
49
40
  ```
50
41
 
51
- [Ruby Gem]: http://guides.rubygems.org/what-is-a-gem/index.html
52
-
53
- [installed with Bundler]: https://bundler.io/index.html#getting-started
54
-
55
42
  ## Usage
56
43
 
57
- The provided plugins must all be used together in the
58
- [Test Kitchen configuration] in order to successfully test the provided
59
- Terraform configuration.
60
-
61
- [Test Kitchen configuration]: https://docs.chef.io/config_yml_kitchen.html
62
-
63
- Refer to [Getting Started Readme](examples/aws_provider/getting_started.md) for a detailed walkthrough of setting up and using kitchen-terraform.
64
-
65
- Refer to the [examples directory] for a detailed example project.
44
+ kitchen-terraform provides three Test Kitchen plugins which must be used
45
+ together in the [Test Kitchen configuration] in order to successfully
46
+ test Terraform configuration:
66
47
 
67
- [examples directory]: examples/
48
+ - a [driver] that creates and destroys [Terraform state];
68
49
 
69
- ## Plugins
50
+ - a [provisioner] that applies changes to existing Terraform state;
70
51
 
71
- ### Driver
52
+ - a [verifier] that verifies the state and behaviour of resources in the
53
+ Terraform state.
72
54
 
73
- The [driver] is a wrapper around the [Terraform command-line interface].
74
- It is responsible for enforcing Terraform version support and works with
75
- the provisioner to manage the [Terraform state].
55
+ Refer to the [gem documentation] for more information about
56
+ kitchen-terraform's design and behaviour.
76
57
 
77
- [driver]: lib/kitchen/driver/terraform.rb
58
+ Refer to the [Getting Started README] for a detailed walkthrough of
59
+ setting up and using kitchen-terraform.
78
60
 
79
- [Terraform command-line interface]: https://www.terraform.io/docs/commands/index.html
61
+ Refer to the [examples directory] for example Terraform projects using
62
+ various [Terraform providers].
80
63
 
64
+ [Bundler]: https://bundler.io/index.html
65
+ [Getting Started README]: https://github.com/newcontext-oss/kitchen-terraform/examples/aws_provider/getting_started.md
66
+ [Ruby Gem]: http://guides.rubygems.org/what-is-a-gem/index.html
67
+ [Ruby]: https://www.ruby-lang.org/en/index.html
68
+ [Terraform configuration]: https://www.terraform.io/docs/configuration/index.html
69
+ [Terraform providers]: https://www.terraform.io/docs/configuration/providers.html
81
70
  [Terraform state]: https://www.terraform.io/docs/state/index.html
82
-
83
- #### Actions
84
-
85
- ##### kitchen create
86
-
87
- The driver ensures that the parent directories of the plan and state
88
- files exist.
89
-
90
- ##### kitchen destroy
91
-
92
- The driver applies a destructive [Terraform plan] to the
93
- Terraform state based on the Terraform configuration provided to the
94
- provisioner.
95
-
96
- [Terraform plan]: https://www.terraform.io/docs/commands/plan.html
97
-
98
- #### Configuration
99
-
100
- ##### cli
101
-
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
108
-
109
- ```yaml
110
- ---
111
- driver:
112
- name: terraform
113
- cli: /usr/local/bin/terraform
114
- ```
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
-
123
- ### Provisioner
124
-
125
- The [provisioner] is the bridge between Terraform and Test Kitchen. It
126
- is responsible for managing the Test Kitchen configuration options related to
127
- the Terraform configuration and works with the driver to manage the
128
- Terraform state.
129
-
130
- [provisioner]: lib/kitchen/provisioner/terraform.rb
131
-
132
- #### Actions
133
-
134
- ##### kitchen converge
135
-
136
- The provisioner uses the driver to apply a constructive Terraform plan
137
- to the Terraform state based on the provided Terraform configuration.
138
-
139
- #### Configuration
140
-
141
- ##### apply_timeout
142
-
143
- The number of seconds to wait for the Terraform `apply` command to be
144
- successful before raising an error.
145
-
146
- ###### Example .kitchen.yml
147
-
148
- ```yaml
149
- ---
150
- provisioner:
151
- name: terraform
152
- apply_timeout: 1000
153
- ```
154
-
155
- ###### Default
156
-
157
- The default `apply_timeout` is 600 seconds.
158
-
159
- ##### color
160
-
161
- Enable or disable colored output from the Terraform command.
162
-
163
- ###### Example .kitchen.yml
164
-
165
- ```yaml
166
- ---
167
- provisioner:
168
- name: terraform
169
- color: false
170
- ```
171
-
172
- ###### Default
173
-
174
- The default value for `color` is true.
175
-
176
- ##### directory
177
-
178
- The pathname of the directory containing the Terraform configuration
179
- to be tested; corresponds to the [directory specified] in several
180
- Terraform commands.
181
-
182
- [directory specified]: https://www.terraform.io/docs/configuration/load.html
183
-
184
- ###### Example .kitchen.yml
185
-
186
- ```yaml
187
- ---
188
- provisioner:
189
- name: terraform
190
- directory: directory/containing/terraform/configuration
191
- ```
192
-
193
- ###### Default
194
-
195
- The default `directory` is the current working directory of Test Kitchen.
196
-
197
- ##### parallelism
198
-
199
- The number of concurrent operations to allow for the Terraform `apply` and
200
- `plan` commands.
201
-
202
- ###### Example .kitchen.yml
203
-
204
- ```yaml
205
- provisioner:
206
- name: terraform
207
- parallelism: 2
208
- ```
209
-
210
- ###### Default
211
-
212
- The default `parallelism` is 10.
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
-
255
- ##### variable_files
256
-
257
- A collection of pathnames of [Terraform variable files] to be evaluated
258
- for the configuration.
259
-
260
- [Terraform variable files]: https://www.terraform.io/docs/configuration/variables.html#variable-files
261
-
262
- ###### Example .kitchen.yml
263
-
264
- ```yaml
265
- ---
266
- provisioner:
267
- name: terraform
268
- variable_files:
269
- - first/terraform/variable/file
270
- - second/terraform/variable/file
271
- ---
272
- provisioner:
273
- name: terraform
274
- variable_files: a/terraform/variable/file
275
- ```
276
-
277
- ###### Default
278
-
279
- The default `variable_files` collection is empty.
280
-
281
- ##### variables
282
-
283
- A mapping of [Terraform variables] to be set in the configuration.
284
-
285
- [Terraform variables]: https://www.terraform.io/docs/configuration/variables.html
286
-
287
- ###### Example .kitchen.yml
288
-
289
- ```yaml
290
- ---
291
- provisioner:
292
- name: terraform
293
- variables:
294
- foo: bar
295
- # deprecated
296
- ---
297
- provisioner:
298
- name: terraform
299
- variables:
300
- - foo=bar
301
- - biz=baz
302
- ---
303
- # deprecated
304
- provisioner:
305
- name: terraform
306
- variables: foo=bar
307
- ```
308
-
309
- ###### Default
310
-
311
- The default `variables` collection is empty.
312
-
313
- ### Verifier
314
-
315
- The [verifier] is a wrapper around [InSpec]. It is responsible for
316
- verifying the behaviour of any server instances in the Terraform state.
317
-
318
- [verifier]: lib/kitchen/verifier/terraform.rb
319
-
320
- [InSpec]: http://inspec.io
321
-
322
- #### Actions
323
-
324
- ##### kitchen verify
325
-
326
- The verifier verifies the test suite's configured groups of server
327
- instances in the Terraform state using an [InSpec profiles] located in
328
- `<Test Kitchen working directory>/test/integration/<suite name>`.
329
-
330
- [InSpec profiles]: http://inspec.io/docs/reference/profiles
331
-
332
- #### Configuration
333
-
334
- The verifier inherits from [kitchen-inspec] and should support any
335
- configuration defined by that plugin with the exception of the `port` and
336
- `username` configuration which are specified under `groups`.
337
-
338
- [kitchen-inspec]: https://github.com/chef/kitchen-inspec/
339
-
340
- ##### groups
341
-
342
- A collection of mappings that define how to test different resources in the
343
- Terraform configuration.
344
-
345
- Each group consists of:
346
-
347
- - a `name` to use for logging purposes
348
-
349
- - an optional `attributes` mapping of InSpec profile attribute names to
350
- Terraform output variable names to define for the suite's InSpec profile
351
-
352
- - a `controls` collection of [InSpec controls] to include from the suite's
353
- InSpec profile
354
-
355
- - a mapping of InSpec profile attribute names to Terraform output variable
356
- names; the attributes will be with the resolved output values
357
-
358
- - an optional `hostnames` output variable name to use for extracting hostnames
359
- from the Terraform state; the resolved output value is assumed to be a
360
- list of strings or a string in CSV format
361
-
362
- - an optional `port` to use when connecting to the group's hosts
363
-
364
- - an optional `username` to use when connecting to the group's hosts
365
-
366
- If `hostnames` is empty then the group's `controls` will be executed
367
- locally; this enables testing of a provider's API to verify non-server
368
- resources.
369
-
370
- [InSpec controls]: http://inspec.io/docs/reference/dsl_inspec/
371
-
372
- ###### Example .kitchen.yml
373
-
374
- ```yaml
375
- verifier:
376
- name: terraform
377
- groups:
378
- - name: arbitrary
379
- attributes:
380
- foo: bar
381
- controls:
382
- - biz
383
- hostnames: hostnames_output
384
- port: 123
385
- username: test-user
386
- ```
387
-
388
- ###### Defaults
389
-
390
- The default `groups` collection is empty.
391
-
392
- For each group:
393
-
394
- - the default `attributes` mapping consists of equivalently named
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.
398
-
399
- - the default `controls` collection is empty
400
-
401
- - the default `hostnames` string is empty
402
-
403
- - the default `port` is obtained from the transport
404
-
405
- - the default `username` is obtained from the transport
71
+ [Terraform]: https://www.terraform.io/index.html
72
+ [Test Kitchen configuration]: https://docs.chef.io/config_yml_kitchen.html
73
+ [Test Kitchen]: http://kitchen.ci/index.html
74
+ [driver]: http://www.rubydoc.info/gems/kitchen-terraform/Kitchen/Driver/Terraform
75
+ [examples directory]: https://github.com/newcontext-oss/kitchen-terraform/examples/
76
+ [gem documentation]: http://www.rubydoc.info/gems/kitchen-terraform/index
77
+ [installed with Bundler]: https://bundler.io/index.html#getting-started
78
+ [provisioner]: http://www.rubydoc.info/gems/kitchen-terraform/Kitchen/Provisioner/Terraform
79
+ [verifier]: http://www.rubydoc.info/gems/kitchen-terraform/Kitchen/Verifier/Terraform
@@ -14,63 +14,279 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require 'kitchen'
18
- require 'terraform/cli_config'
19
- require 'terraform/configurable'
20
- require 'terraform/version'
21
-
22
- module Kitchen
23
- module Driver
24
- # Terraform state lifecycle activities manager
25
- class Terraform < ::Kitchen::Driver::Base
26
- extend ::Terraform::CLIConfig
27
-
28
- include ::Terraform::Configurable
29
-
30
- kitchen_driver_api_version 2
31
-
32
- no_parallel_for
33
-
34
- def create(_state = nil); end
35
-
36
- def destroy(_state = nil)
37
- load_state { client.apply_destructively }
38
- rescue ::Kitchen::StandardError, ::SystemCallError => error
39
- raise ::Kitchen::ActionFailed, error.message
40
- end
41
-
42
- def verify_dependencies
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}"
67
- end
68
- end
69
-
70
- def version
71
- @version ||=
72
- ::Terraform::Client.new(config: self, logger: debug_logger).version
73
- end
17
+ require "dry/monads"
18
+ require "kitchen"
19
+ require "kitchen/terraform/client/output"
20
+ require "kitchen/terraform/client/plan"
21
+ require "kitchen/terraform/client/version"
22
+ require "kitchen/terraform/define_config_attribute"
23
+ require "kitchen/terraform/define_integer_config_attribute"
24
+ require "kitchen/terraform/define_string_config_attribute"
25
+ require "terraform/configurable"
26
+
27
+ # The kitchen-terraform driver is the bridge between Test Kitchen and Terraform. It manages the state of the configured
28
+ # root Terraform module by invoking its workflow in a constructive or destructive manner.
29
+ #
30
+ # === Configuration
31
+ #
32
+ # ==== Example .kitchen.yml snippet
33
+ #
34
+ # driver:
35
+ # name: terraform
36
+ # command_timeout: 1000
37
+ # cli: /usr/local/bin/terraform
38
+ # color: false
39
+ # directory: /directory/containing/terraform/configuration
40
+ # parallelism: 2
41
+ # plan: /terraform/plan
42
+ # state: /terraform/state
43
+ # variable_files:
44
+ # - /first/terraform/variable/file
45
+ # - /second/terraform/variable/file
46
+ # variables:
47
+ # variable_name: variable_value
48
+ #
49
+ # ==== Attributes
50
+ #
51
+ # ===== cli
52
+ #
53
+ # Description:: The path of the Terraform CLI to use for command execution.
54
+ #
55
+ # Type:: String
56
+ #
57
+ # Status:: Optional
58
+ #
59
+ # Default:: +"terraform"+
60
+ #
61
+ # ===== color
62
+ #
63
+ # Description:: Toggle to enable or disable colored output from the Terraform CLI commands.
64
+ #
65
+ # Type:: Boolean
66
+ #
67
+ # Status:: Optional
68
+ #
69
+ # Default:: +true+ if the Test Kitchen process is associated with a terminal device (tty); +false+ if it is not.
70
+ #
71
+ # ===== command_timeout
72
+ #
73
+ # Description:: The number of seconds to wait for the Terraform CLI commands to finish.
74
+ #
75
+ # Type:: Integer
76
+ #
77
+ # Status:: Optional
78
+ #
79
+ # Default:: +600+
80
+ #
81
+ # ===== directory
82
+ #
83
+ # Description:: The path of the directory containing the root Terraform module to be tested.
84
+ #
85
+ # Type:: String
86
+ #
87
+ # Status:: Optional
88
+ #
89
+ # Default:: The working directory of the Test Kitchen process.
90
+ #
91
+ # ===== parallelism
92
+ #
93
+ # Description:: The maximum number of concurrent operations to allow while walking the resource graph for the Terraform
94
+ # CLI apply and plan commands.
95
+ # Type:: Integer
96
+ #
97
+ # Status:: Optional
98
+ #
99
+ # Default:: +10+
100
+ #
101
+ # ===== plan
102
+ #
103
+ # Description:: The path of the Terraform execution plan that will be generated and applied.
104
+ #
105
+ # Type:: String
106
+ #
107
+ # Status:: Optional
108
+ #
109
+ # Default:: A descendant of the working directory of the Test Kitchen process:
110
+ # +".kitchen/kitchen-terraform/<suite_name>/terraform.tfplan"+
111
+ #
112
+ # ===== state
113
+ #
114
+ # Description:: The path of the Terraform state that will be generated and managed.
115
+ #
116
+ # Type:: String
117
+ #
118
+ # Status:: Optional
119
+ #
120
+ # Default:: A descendant of the working directory of the Test Kitchen process:i
121
+ # +".kitchen/kitchen-terraform/<suite_name>/terraform.tfstate"+.
122
+ #
123
+ # ===== variable_files
124
+ #
125
+ # Description:: A collection of paths of Terraform variable files to be evaluated during the creation of the Terraform
126
+ # execution plan.
127
+ #
128
+ # Type:: Array
129
+ #
130
+ # Status:: Optional
131
+ #
132
+ # Default:: +[]+
133
+ #
134
+ # ===== variables
135
+ #
136
+ # Description:: A mapping of Terraform variable names and values to be overridden during the creation of the Terraform
137
+ # execution plan.
138
+ #
139
+ # Type:: Hash
140
+ #
141
+ # Status:: Optional
142
+ #
143
+ # Default:: +{}+
144
+ #
145
+ # @see ::Kitchen::Driver::Terraform::Workflow
146
+ # @see https://en.wikipedia.org/wiki/Working_directory Working directory
147
+ # @see https://www.terraform.io/docs/commands/plan.html Terraform execution plan
148
+ # @see https://www.terraform.io/docs/configuration/variables.html Terraform variables
149
+ # @see https://www.terraform.io/docs/internals/graph.html Terraform resource graph
150
+ # @see https://www.terraform.io/docs/state/index.html Terraform state
151
+ # @version 2
152
+ class ::Kitchen::Driver::Terraform < ::Kitchen::Driver::Base
153
+ kitchen_driver_api_version 2
154
+
155
+ no_parallel_for
156
+
157
+ ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :cli,
158
+ plugin_class: self do
159
+ "terraform"
160
+ end
161
+
162
+ ::Kitchen::Terraform::DefineIntegerConfigAttribute.call attribute: :command_timeout,
163
+ plugin_class: self do
164
+ 600
165
+ end
166
+
167
+ ::Kitchen::Terraform::DefineConfigAttribute.call(
168
+ attribute: :color,
169
+ initialize_default_value: lambda do |_plugin|
170
+ ::Kitchen.tty?
171
+ end,
172
+ plugin_class: self,
173
+ schema: lambda do
174
+ required(:value).filled :bool?
175
+ end
176
+ )
177
+
178
+ ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :directory,
179
+ plugin_class: self do |plugin|
180
+ plugin[:kitchen_root]
181
+ end
182
+
183
+ ::Kitchen::Terraform::DefineIntegerConfigAttribute.call attribute: :parallelism,
184
+ plugin_class: self do
185
+ 10
186
+ end
187
+
188
+ ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :plan,
189
+ plugin_class: self do |plugin|
190
+ plugin.instance_pathname filename: "terraform.tfplan"
191
+ end
192
+
193
+ ::Kitchen::Terraform::DefineStringConfigAttribute.call attribute: :state,
194
+ plugin_class: self do |plugin|
195
+ plugin.instance_pathname filename: "terraform.tfstate"
196
+ end
197
+
198
+ ::Kitchen::Terraform::DefineConfigAttribute.call(
199
+ attribute: :variable_files,
200
+ initialize_default_value: lambda do |_plugin|
201
+ []
202
+ end,
203
+ plugin_class: self,
204
+ schema: lambda do
205
+ required(:value).each :filled?, :str?
206
+ end
207
+ )
208
+
209
+ ::Kitchen::Terraform::DefineConfigAttribute.call(
210
+ attribute: :variables,
211
+ initialize_default_value: lambda do |_plugin|
212
+ {}
213
+ end,
214
+ plugin_class: self,
215
+ schema: lambda do
216
+ required(:value).value :hash?
217
+ end
218
+ )
219
+
220
+ include ::Terraform::Configurable
221
+
222
+ # The driver invokes its workflow in a constructive manner.
223
+ #
224
+ # @example
225
+ # `kitchen create suite-name`
226
+ # @note The user must ensure that different suites utilize separate Terraform plan and state files if they are to run
227
+ # the create action concurrently.
228
+ # @param _state [::Hash] the mutable instance and driver state; this parameter is ignored.
229
+ # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
230
+ # @return [::Dry::Monads::Either] the result of the workflow function.
231
+ # @see ::Kitchen::Driver::Terraform::Workflow
232
+ def create(_state)
233
+ self.class::Workflow.call(
234
+ config: config,
235
+ logger: logger
236
+ ).or do |failure|
237
+ raise ::Kitchen::ActionFailed, failure
238
+ end
239
+ end
240
+
241
+ # The driver invokes its workflow in a destructive manner.
242
+ #
243
+ # @example
244
+ # `kitchen destroy suite-name`
245
+ # @note The user must ensure that different suites utilize separate Terraform plan and state files if they are to run
246
+ # the destroy action concurrently.
247
+ # @param _state [::Hash] the mutable instance and driver state; this parameter is ignored.
248
+ # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
249
+ # @return [::Dry::Monads::Either] the result of the action.
250
+ # @see ::Kitchen::Driver::Terraform::Workflow
251
+ def destroy(_state)
252
+ self.class::Workflow.call(
253
+ config: config,
254
+ destroy: true,
255
+ logger: logger
256
+ ).or do |failure|
257
+ raise ::Kitchen::ActionFailed, failure
258
+ end
259
+ end
260
+
261
+ # The driver proxies the client output function.
262
+ #
263
+ # @return [::Dry::Monads::Either] the result of the Terraform Client Output function.
264
+ # @see ::Kitchen::Terraform::Client::Output
265
+ def output
266
+ ::Kitchen::Terraform::Client::Output.call cli: config.fetch(:cli), logger: debug_logger,
267
+ options: {color: config.fetch(:color), state: config.fetch(:state)},
268
+ timeout: config.fetch(:command_timeout)
269
+ end
270
+
271
+ # The driver verifies that the client version is supported.
272
+ #
273
+ # @raise [::Kitchen::UserError] if the version is not supported.
274
+ # @return [::Dry::Monads::Either] the result of the client version verification function.
275
+ # @see ::Kitchen::Driver::Terraform::VerifyClientVersion
276
+ # @see ::Kitchen::Terraform::Client::Version
277
+ def verify_dependencies
278
+ ::Kitchen::Terraform::Client::Version.call(
279
+ cli: config.fetch(:cli), logger: debug_logger, timeout: config.fetch(:command_timeout)
280
+ ).bind do |version|
281
+ self.class::VerifyClientVersion.call version: version
282
+ end.fmap do |verified_client_version|
283
+ logger.warn verified_client_version
284
+ verified_client_version
285
+ end.or do |failure|
286
+ raise ::Kitchen::UserError, failure
74
287
  end
75
288
  end
76
289
  end
290
+
291
+ require "kitchen/driver/terraform/workflow"
292
+ require "kitchen/driver/terraform/verify_client_version"