kitchen-terraform 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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"