kitchen-terraform 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +40 -43
  5. data/lib/kitchen/{terraform/client.rb → driver.rb} +4 -5
  6. data/lib/kitchen/driver/terraform.rb +367 -300
  7. data/lib/kitchen/provisioner.rb +22 -0
  8. data/lib/kitchen/provisioner/terraform.rb +70 -13
  9. data/lib/kitchen/terraform/client_version_verifier.rb +8 -3
  10. data/lib/kitchen/terraform/config_attribute.rb +0 -5
  11. data/lib/kitchen/terraform/config_attribute/backend_configurations.rb +21 -5
  12. data/lib/kitchen/terraform/config_attribute/color.rb +15 -4
  13. data/lib/kitchen/terraform/config_attribute/command_timeout.rb +7 -4
  14. data/lib/kitchen/terraform/config_attribute/groups.rb +63 -27
  15. data/lib/kitchen/terraform/config_attribute/lock_timeout.rb +16 -7
  16. data/lib/kitchen/terraform/config_attribute/parallelism.rb +12 -4
  17. data/lib/kitchen/terraform/config_attribute/plugin_directory.rb +13 -6
  18. data/lib/kitchen/terraform/config_attribute/{directory.rb → root_module_directory.rb} +9 -8
  19. data/lib/kitchen/terraform/config_attribute/variable_files.rb +19 -2
  20. data/lib/kitchen/terraform/config_attribute/variables.rb +18 -4
  21. data/lib/kitchen/terraform/configurable.rb +0 -19
  22. data/lib/kitchen/terraform/shell_out.rb +66 -0
  23. data/lib/kitchen/terraform/version.rb +1 -1
  24. data/lib/kitchen/verifier.rb +22 -0
  25. data/lib/kitchen/verifier/terraform.rb +116 -60
  26. data/lib/kitchen/verifier/terraform/configure_inspec_runner_attributes.rb +37 -24
  27. data/lib/kitchen/verifier/terraform/enumerate_groups_and_hostnames.rb +35 -17
  28. metadata +29 -12
  29. metadata.gz.sig +3 -2
  30. data/lib/kitchen/terraform/clear_directory.rb +0 -38
  31. data/lib/kitchen/terraform/client/command.rb +0 -168
  32. data/lib/kitchen/terraform/client/options.rb +0 -275
  33. data/lib/kitchen/terraform/config_attribute/state.rb +0 -55
  34. data/lib/kitchen/terraform/config_attribute/verify_plugins.rb +0 -52
  35. data/lib/kitchen/terraform/create_directories.rb +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9c484cfa1fce45ee648ee3e184937331b74e2d92
4
- data.tar.gz: 6feb2f68cf8e842426720b8a4f5b036243529e9f
2
+ SHA256:
3
+ metadata.gz: 8a3511bbc6d10c08da856558d9f41949651cb0e38db183909d0f46ae885e6cdc
4
+ data.tar.gz: dc2fdad8698f10114a5adfce900a60f2d203eef807350d71810a63e1958a8315
5
5
  SHA512:
6
- metadata.gz: 2add7730329949a50da2911e2fd05868f67c7a2dab984aa68343f49c2bfd956a23174378907801bca3a17fc597dda7eebfb9344fbc4bbb3c55d0d5e5e1c1fa6e
7
- data.tar.gz: e67c2f15793a4a0dde35df3b24228228fec45af008b3d202d96cc294c365b8d4e079fc544af00d6a1b6ceab0ec9cbefc6270c8996586854ac0b5b2a2dd5faa97
6
+ metadata.gz: 378c750cd2ddd73a30b04d3518a0f40d9fa01e4080d5a1014115793a51f999773c056cc46b908ca364e32780975792d77d0982b2d170316a9ec47bc63e043719
7
+ data.tar.gz: 1fd8130d68184e45c1cffa8ee5fffebdd6bf2364eb24963b92411ed6ad64dc68bf9110b8d3add81bcfa1023df8b90c03b2e649d9b9a53a46321c755d0d934e18
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -6,21 +6,26 @@
6
6
  [![Build Status Master](https://travis-ci.org/newcontext-oss/kitchen-terraform.svg?branch=master)](https://travis-ci.org/newcontext-oss/kitchen-terraform)
7
7
  [![Test Coverage](https://codeclimate.com/github/newcontext-oss/kitchen-terraform/badges/coverage.svg)](https://codeclimate.com/github/newcontext-oss/kitchen-terraform/coverage)
8
8
 
9
- kitchen-terraform is a set of [Test Kitchen] plugins for testing
10
- [Terraform configuration].
9
+ kitchen-terraform is a set of
10
+ [Test Kitchen](http://kitchen.ci/index.html) plugins for testing
11
+ [Terraform configuration](https://www.terraform.io/docs/configuration/index.html)
12
+ .
11
13
 
12
14
  ## Requirements
13
15
 
14
- - [Ruby] **(~> 2.2)**
16
+ - [Ruby](https://www.ruby-lang.org/en/index.html) **(~> 2.2)**
15
17
 
16
- - [Bundler] **(~> 1.12)**
18
+ - [Bundler](https://bundler.io/index.html) **(~> 1.12)**
17
19
 
18
- - [Terraform] **(~> 0.10.2)**
20
+ - [Terraform](https://www.terraform.io/index.html)
21
+ **(>= 0.10.2, < 0.12.0)**
19
22
 
20
23
  ## Installation
21
24
 
22
- kitchen-terraform is packaged as a cryptographically signed [Ruby gem]
23
- which means it can be [installed with Bundler].
25
+ kitchen-terraform is packaged as a cryptographically signed
26
+ [Ruby gem](http://guides.rubygems.org/what-is-a-gem/index.html) which
27
+ means it can be
28
+ [installed with Bundler](https://bundler.io/index.html#getting-started).
24
29
 
25
30
  ### Adding kitchen-terraform to a Terraform project
26
31
 
@@ -29,7 +34,7 @@ Gemfile:
29
34
 
30
35
  ```rb
31
36
  source "https://rubygems.org/" do
32
- gem "kitchen-terraform", "~> 2.0"
37
+ gem "kitchen-terraform", "~> 3.0"
33
38
  end
34
39
  ```
35
40
 
@@ -42,38 +47,30 @@ bundle install
42
47
  ## Usage
43
48
 
44
49
  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:
47
-
48
- - a [driver] that creates and destroys [Terraform state];
49
-
50
- - a [provisioner] that applies changes to existing Terraform state;
51
-
52
- - a [verifier] that verifies the state and behaviour of resources in the
53
- Terraform state.
54
-
55
- Refer to the [gem documentation] for more information about
56
- kitchen-terraform's design and behaviour.
57
-
58
- Refer to the [Getting Started README] for a detailed walkthrough of
59
- setting up and using kitchen-terraform.
60
-
61
- Refer to the [examples directory] for example Terraform projects using
62
- various [Terraform providers].
63
-
64
- [Bundler]: https://bundler.io/index.html
65
- [Getting Started README]: https://github.com/newcontext-oss/kitchen-terraform/blob/master/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
70
- [Terraform state]: https://www.terraform.io/docs/state/index.html
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/blob/master/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
50
+ together in the
51
+ [Test Kitchen configuration](https://docs.chef.io/config_yml_kitchen.html)
52
+ in order to successfully test Terraform configuration:
53
+
54
+ - a [driver](http://www.rubydoc.info/github/newcontext-oss/kitchen-terraform/Kitchen/Driver/Terraform)
55
+ that creates and destroys
56
+ [Terraform state](https://www.terraform.io/docs/state/index.html);
57
+
58
+ - a [provisioner](http://www.rubydoc.info/github/newcontext-oss/kitchen-terraform/Kitchen/Provisioner/Terraform)
59
+ that applies changes to existing Terraform state;
60
+
61
+ - a [verifier](http://www.rubydoc.info/github/newcontext-oss/kitchen-terraform/Kitchen/Verifier/Terraform)
62
+ that verifies the state and behaviour of resources in the Terraform
63
+ state.
64
+
65
+ Refer to the [gem documentation](http://www.rubydoc.info/github/newcontext-oss/kitchen-terraform/)
66
+ for more information about kitchen-terraform's design and behaviour.
67
+
68
+ Refer to the
69
+ [Getting Started Tutorial](https://newcontext-oss.github.io/kitchen-terraform/tutorials/amazon_provider_ec2.html)
70
+ for a detailed walkthrough of setting up and using kitchen-terraform.
71
+
72
+ Refer to the
73
+ [tutorials](https://newcontext-oss.github.io/kitchen-terraform/tutorials)
74
+ for example Terraform projects using various
75
+ [Terraform providers](https://www.terraform.io/docs/configuration/providers.html)
76
+ .
@@ -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/terraform"
17
+ require "kitchen"
18
18
 
19
- # The namespace for functions that wrap the Terraform command-line interface (CLI) commands.
20
- #
21
- # @see https://www.terraform.io/docs/commands/index.html Terraform CLI
22
- module ::Kitchen::Terraform::Client
19
+ # This is the namespace for Test Kitchen driver plugins. This namespace is already defined in Test Kitchen but YARD
20
+ # requires it to be redefined here in order to include documenation from the Kitchen::Terraform namespace.
21
+ module Kitchen::Driver
23
22
  end
@@ -15,73 +15,159 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "dry/monads"
18
- require "fileutils"
19
18
  require "json"
20
- require "kitchen"
21
- require "kitchen/terraform/clear_directory"
22
- require "kitchen/terraform/client/command"
23
- require "kitchen/terraform/client/options"
19
+ require "kitchen/driver/base"
20
+ require "kitchen/errors"
24
21
  require "kitchen/terraform/client_version_verifier"
25
22
  require "kitchen/terraform/config_attribute/backend_configurations"
26
23
  require "kitchen/terraform/config_attribute/color"
27
24
  require "kitchen/terraform/config_attribute/command_timeout"
28
- require "kitchen/terraform/config_attribute/directory"
29
25
  require "kitchen/terraform/config_attribute/lock_timeout"
30
26
  require "kitchen/terraform/config_attribute/parallelism"
31
27
  require "kitchen/terraform/config_attribute/plugin_directory"
32
- require "kitchen/terraform/config_attribute/state"
28
+ require "kitchen/terraform/config_attribute/root_module_directory"
33
29
  require "kitchen/terraform/config_attribute/variable_files"
34
30
  require "kitchen/terraform/config_attribute/variables"
35
- require "kitchen/terraform/config_attribute/verify_plugins"
36
- require "kitchen/terraform/create_directories"
37
31
  require "kitchen/terraform/configurable"
32
+ require "kitchen/terraform/shell_out"
38
33
 
39
- # The kitchen-terraform driver is the bridge between Test Kitchen and Terraform.
34
+ # The driver is the bridge between Test Kitchen and Terraform. It manages the
35
+ # {https://www.terraform.io/docs/state/index.html state} of the Terraform root module by shelling out and running
36
+ # Terraform commands.
40
37
  #
41
- # It manages the state of the configured root Terraform module by invoking its workflow in a constructive or destructive
42
- # manner.
38
+ # === Commands
43
39
  #
44
- # === Test Kitchen Configuration
40
+ # The following command-line commands are provided by the driver.
45
41
  #
46
- # The configuration of the driver is used to control the behaviour of the Terraform Client commands.
42
+ # ==== kitchen create
47
43
  #
48
- # More information about the available configuration attributes is located with the respective modules.
44
+ # A Test Kitchen instance is created through the following steps.
49
45
  #
50
- # Test Kitchen configuration is defined in +.kitchen.yml+ and optionally overridden in +.kitchen.local.yml+.
46
+ # ===== Initializing the Terraform Working Directory
51
47
  #
52
- # ==== Example
48
+ # terraform init \
49
+ # -input=false \
50
+ # -lock=true \
51
+ # -lock-timeout=<lock_timeout>s \
52
+ # [-no-color] \
53
+ # -upgrade \
54
+ # -force-copy \
55
+ # -backend=true \
56
+ # [-backend-config=<backend_configurations.first> ...] \
57
+ # -get=true \
58
+ # -get-plugins=true \
59
+ # [-plugin-dir=<plugin_directory>] \
60
+ # -verify-plugins=true \
61
+ # <root_module_directory>
62
+ #
63
+ # ===== Creating a Test Terraform Workspace
64
+ #
65
+ # terraform workspace <new|select> kitchen-terraform-<instance>
66
+ #
67
+ # ==== kitchen destroy
68
+ #
69
+ # A Test Kitchen instance is destroyed through the following steps.
70
+ #
71
+ # ===== Initializing the Terraform Working Directory
72
+ #
73
+ # terraform init \
74
+ # -input=false \
75
+ # -lock=true \
76
+ # -lock-timeout=<lock_timeout>s \
77
+ # [-no-color] \
78
+ # -force-copy \
79
+ # -backend=true \
80
+ # [-backend-config=<backend_configurations.first>...] \
81
+ # -get=true \
82
+ # -get-plugins=true \
83
+ # [-plugin-dir=<plugin_directory>] \
84
+ # -verify-plugins=true \
85
+ # <root_module_directory>
86
+ #
87
+ # ===== Selecting the Test Terraform Workspace
88
+ #
89
+ # terraform workspace <select|new> kitchen-terraform-<instance>
90
+ #
91
+ # ===== Destroying the Terraform State
92
+ #
93
+ # terraform destroy \
94
+ # -force \
95
+ # -lock=true \
96
+ # -lock-timeout=<lock_timeout>s \
97
+ # -input=false \
98
+ # [-no-color] \
99
+ # -parallelism=<parallelism> \
100
+ # -refresh=true \
101
+ # [-var=<variables.first>...] \
102
+ # [-var-file=<variable_files.first>...] \
103
+ # <root_module_directory>
104
+ #
105
+ # ===== Selecting the Default Terraform Workspace
106
+ #
107
+ # terraform workspace select default
108
+ #
109
+ # ===== Deleting the Test Terraform Workspace
110
+ #
111
+ # terraform workspace delete kitchen-terraform-<instance>
112
+ #
113
+ # === Shelling Out
114
+ #
115
+ # {include:Kitchen::Terraform::ShellOut}
116
+ #
117
+ # === Configuration Attributes
118
+ #
119
+ # The configuration attributes of the driver control the behaviour of the Terraform commands that are run. Within the
120
+ # {http://kitchen.ci/docs/getting-started/kitchen-yml Test Kitchen configuration file}, these attributes must be
121
+ # declared in the +driver+ mapping along with the plugin name.
53
122
  #
54
123
  # driver:
55
- # name: "terraform"
56
- # backend_configurations:
57
- # argument_name: "argument_value"
58
- # command_timeout: 1000
59
- # color: false
60
- # directory: "/directory/containing/terraform/configuration"
61
- # lock_timeout: 2000
62
- # parallelism: 2
63
- # plugin_directory: "/plugin/directory"
64
- # state: "/terraform/state"
65
- # variable_files:
66
- # - "/first/terraform/variable/file"
67
- # - "/second/terraform/variable/file"
68
- # variables:
69
- # variable_name: "variable_value"
70
- # verify_plugins: false
71
- #
72
- # @see ::Kitchen::Terraform::Client::Command
73
- # @see ::Kitchen::Terraform::ConfigAttribute::BackendConfigurations
74
- # @see ::Kitchen::Terraform::ConfigAttribute::CommandTimeout
75
- # @see ::Kitchen::Terraform::ConfigAttribute::Color
76
- # @see ::Kitchen::Terraform::ConfigAttribute::Directory
77
- # @see ::Kitchen::Terraform::ConfigAttribute::LockTimeout
78
- # @see ::Kitchen::Terraform::ConfigAttribute::Parallelism
79
- # @see ::Kitchen::Terraform::ConfigAttribute::PluginDirectory
80
- # @see ::Kitchen::Terraform::ConfigAttribute::State
81
- # @see ::Kitchen::Terraform::ConfigAttribute::VariableFiles
82
- # @see ::Kitchen::Terraform::ConfigAttribute::Variables
83
- # @see ::Kitchen::Terraform::ConfigAttribute::VerifyPlugins
84
- # @see http://kitchen.ci/docs/getting-started/kitchen-yml Test Kitchen: .kitchen.yml
124
+ # name: terraform
125
+ # a_configuration_attribute: some value
126
+ #
127
+ # ==== backend_configurations
128
+ #
129
+ # {include:Kitchen::Terraform::ConfigAttribute::BackendConfigurations}
130
+ #
131
+ # ==== color
132
+ #
133
+ # {include:Kitchen::Terraform::ConfigAttribute::Color}
134
+ #
135
+ # ==== command_timeout
136
+ #
137
+ # {include:Kitchen::Terraform::ConfigAttribute::CommandTimeout}
138
+ #
139
+ # ==== root_module_directory
140
+ #
141
+ # {include:Kitchen::Terraform::ConfigAttribute::RootModuleDirectory}
142
+ #
143
+ # ==== lock_timeout
144
+ #
145
+ # {include:Kitchen::Terraform::ConfigAttribute::LockTimeout}
146
+ #
147
+ # ==== parallelism
148
+ #
149
+ # {include:Kitchen::Terraform::ConfigAttribute::Parallelism}
150
+ #
151
+ # ==== plugin_directory
152
+ #
153
+ # {include:Kitchen::Terraform::ConfigAttribute::PluginDirectory}
154
+ #
155
+ # ==== variable_files
156
+ #
157
+ # {include:Kitchen::Terraform::ConfigAttribute::VariableFiles}
158
+ #
159
+ # ==== variables
160
+ #
161
+ # {include:Kitchen::Terraform::ConfigAttribute::Variables}
162
+ #
163
+ # @example Describe the create command
164
+ # kitchen help create
165
+ # @example Create a Test Kitchen instance
166
+ # kitchen create default-ubuntu
167
+ # @example Describe the destroy command
168
+ # kitchen help destroy
169
+ # @example Destroy a Test Kitchen instance
170
+ # kitchen destroy default-ubuntu
85
171
  # @version 2
86
172
  class ::Kitchen::Driver::Terraform < ::Kitchen::Driver::Base
87
173
  kitchen_driver_api_version 2
@@ -98,337 +184,318 @@ class ::Kitchen::Driver::Terraform < ::Kitchen::Driver::Base
98
184
 
99
185
  include ::Kitchen::Terraform::ConfigAttribute::CommandTimeout
100
186
 
101
- include ::Kitchen::Terraform::ConfigAttribute::Directory
102
-
103
187
  include ::Kitchen::Terraform::ConfigAttribute::LockTimeout
104
188
 
105
189
  include ::Kitchen::Terraform::ConfigAttribute::Parallelism
106
190
 
107
191
  include ::Kitchen::Terraform::ConfigAttribute::PluginDirectory
108
192
 
109
- include ::Kitchen::Terraform::ConfigAttribute::State
193
+ include ::Kitchen::Terraform::ConfigAttribute::RootModuleDirectory
110
194
 
111
195
  include ::Kitchen::Terraform::ConfigAttribute::VariableFiles
112
196
 
113
197
  include ::Kitchen::Terraform::ConfigAttribute::Variables
114
198
 
115
- include ::Kitchen::Terraform::ConfigAttribute::VerifyPlugins
116
-
117
199
  include ::Kitchen::Terraform::Configurable
118
200
 
119
- # The driver invokes its workflow in a constructive manner by applying changes to the Terraform state.
201
+ # Applies changes to the state by selecting the test workspace, updating the dependency modules, validating the root
202
+ # module, applying the state changes, and retrieving the state output.
203
+ #
204
+ # @return [::Dry::Monads::Either] the result of the action.
205
+ def apply
206
+ apply_run_workspace_select_instance
207
+ .bind do
208
+ apply_run_get
209
+ end
210
+ .bind do
211
+ apply_run_validate
212
+ end
213
+ .bind do
214
+ apply_run_apply
215
+ end
216
+ .bind do
217
+ apply_run_output
218
+ end
219
+ end
220
+
221
+ # Creates a Test Kitchen instance by initializing the working directory and creating a test workspace.
120
222
  #
121
- # @example
122
- # `kitchen help create`
123
- # @example
124
- # `kitchen create suite-name`
125
- # @note The user must ensure that different suites utilize separate Terraform state files if they are to run
126
- # the create action concurrently.
127
223
  # @param _state [::Hash] the mutable instance and driver state.
128
224
  # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
129
- # @see ::Kitchen::Driver::Terraform#run_apply
130
- # @see ::Kitchen::Driver::Terraform#workflow
131
225
  def create(_state)
132
- workflow do
133
- run_apply
134
- end
226
+ create_run_init
227
+ .bind do
228
+ create_run_workspace_new_instance
229
+ .or do
230
+ create_run_workspace_select_instance
231
+ end
232
+ end
233
+ .or do |failure|
234
+ raise(
235
+ ::Kitchen::ActionFailed,
236
+ failure
237
+ )
238
+ end
135
239
  end
136
240
 
137
- # The driver invokes its workflow in a destructive manner by destroying the Terraform state and removing the instance
138
- # directory.
241
+ # Destroys a Test Kitchen instance by initializing the working directory, selecting the test workspace,
242
+ # deleting the state, selecting the default workspace, and deleting the test workspace.
139
243
  #
140
- # @example
141
- # `kitchen help destroy`
142
- # @example
143
- # `kitchen destroy suite-name`
144
- # @note The user must ensure that different suites utilize separate Terraform state files if they are to run
145
- # the destroy action concurrently.
146
244
  # @param _state [::Hash] the mutable instance and driver state.
147
245
  # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
148
- # @see ::Kitchen::Driver::Terraform#remove_instance_directory
149
- # @see ::Kitchen::Driver::Terraform#run_destroy
150
- # @see ::Kitchen::Driver::Terraform#workflow
151
246
  def destroy(_state)
152
- workflow do
153
- run_destroy.bind do
154
- remove_instance_directory
247
+ destroy_run_init
248
+ .bind do
249
+ destroy_run_workspace_select_instance
250
+ .or do
251
+ destroy_run_workspace_new_instance
252
+ end
155
253
  end
156
- end
157
- end
158
-
159
- # The driver parses the Terraform Client output subcomannd output as JSON.
160
- #
161
- # @return [::Dry::Monads::Either] the result of parsing the output.
162
- # @see ::Kitchen::Terraform::Client::Command.Output
163
- # @see ::JSON.parse
164
- def output
165
- run_output
166
- .bind do |output|
167
- Try ::JSON::ParserError do
168
- ::JSON.parse output
169
- end
170
- .to_either
254
+ .bind do
255
+ destroy_run_destroy
171
256
  end
172
- .or do |error|
173
- Left "parsing Terraform client output as JSON failed\n#{error}"
257
+ .bind do
258
+ destroy_run_workspace_select_default
259
+ end
260
+ .bind do
261
+ destroy_run_workspace_delete_instance
262
+ end
263
+ .or do |failure|
264
+ raise(
265
+ ::Kitchen::ActionFailed,
266
+ failure
267
+ )
174
268
  end
175
269
  end
176
270
 
177
- # The driver verifies that the client version is supported.
271
+ # Verifies that the Terraform version available to the driver is supported.
178
272
  #
179
273
  # @raise [::Kitchen::UserError] if the version is not supported.
180
- # @see ::Kitchen::Terraform::Client::Command.version
181
- # @see ::Kitchen::Terraform::ClientVersionVerifier#verify
182
274
  def verify_dependencies
183
- run_version
275
+ ::Kitchen::Terraform::ShellOut
276
+ .run(
277
+ command: "version",
278
+ logger: logger
279
+ )
184
280
  .bind do |output|
185
281
  ::Kitchen::Terraform::ClientVersionVerifier
186
282
  .new
187
283
  .verify version_output: output
188
284
  end
189
- .bind do |verified_client_version|
190
- Right logger.warn verified_client_version
191
- end
192
285
  .or do |failure|
193
286
  raise(
194
287
  ::Kitchen::UserError,
195
288
  failure
196
289
  )
197
290
  end
291
+ .bind do |verified_client_version|
292
+ logger.warn verified_client_version
293
+ end
198
294
  end
199
295
 
200
296
  private
201
297
 
202
- # The driver creates the instance directory or clears it of Terraform configuration if it already exists.
203
- #
204
298
  # @api private
205
- # @return [::Dry::Monads::Either] the result of creating or clearing the instance directory.
206
- # @see ::KItchen::Terraform::ClearDirectory.call
207
- # @see ::Kitchen::Driver::Terraform#instance_directory
208
- # @see ::Kitchen::Terraform::CreateDirectories.call
209
- def prepare_instance_directory
210
- ::Kitchen::Terraform::CreateDirectories
211
- .call(
212
- directories: [instance_directory]
299
+ def apply_run_apply
300
+ ::Kitchen::Terraform::ShellOut
301
+ .run(
302
+ command:
303
+ "apply " \
304
+ "-lock=true " \
305
+ "#{config_lock_timeout_flag} " \
306
+ "-input=false " \
307
+ "-auto-approve=true " \
308
+ "#{config_color_flag} " \
309
+ "#{config_parallelism_flag} " \
310
+ "-refresh=true " \
311
+ "#{config_variables_flags} " \
312
+ "#{config_variable_files_flags} " \
313
+ "#{config_root_module_directory}",
314
+ duration: config_command_timeout,
315
+ logger: logger
213
316
  )
214
- .bind do |created_directories|
215
- logger.debug created_directories
216
- ::Kitchen::Terraform::ClearDirectory
217
- .call(
218
- directory: instance_directory,
219
- files: [
220
- "*.tf",
221
- "*.tf.json"
222
- ]
223
- )
224
- end
225
- .bind do |cleared_directory|
226
- Right logger.debug cleared_directory
227
- end
228
317
  end
229
318
 
230
- # The driver removes the instance directory.
231
- #
232
319
  # @api private
233
- # @see ::FileUtils.remove_dir
234
- # @see ::Kitchen::Driver::Terraform#instance_directory
235
- def remove_instance_directory
236
- Try do
237
- ::FileUtils.remove_dir instance_directory
238
- end
239
- .to_either
320
+ def apply_run_get
321
+ ::Kitchen::Terraform::ShellOut
322
+ .run(
323
+ command: "get -update #{config_root_module_directory}",
324
+ duration: config_command_timeout,
325
+ logger: logger
326
+ )
240
327
  end
241
328
 
242
- # Runs a Terraform Client command shell out with the default logger and the configured timeout.
243
- #
244
329
  # @api private
245
- # @param result [::Dry::Monads::Either] the result of a shell out creation
246
- # @return [::Dry::Monads::Either] the result of running the shell out
247
- def run(result:)
248
- result
249
- .bind do |shell_out|
250
- ::Kitchen::Terraform::Client::Command
251
- .run(
252
- logger: logger,
253
- shell_out: shell_out,
254
- timeout: config_command_timeout
255
- )
330
+ def apply_run_output
331
+ ::Kitchen::Terraform::ShellOut
332
+ .run(
333
+ command: "output -json",
334
+ duration: config_command_timeout,
335
+ logger: logger
336
+ )
337
+ .bind do |output|
338
+ Try ::JSON::ParserError do
339
+ ::JSON.parse output
340
+ end
341
+ .to_either
342
+ .or do |error|
343
+ Left "Parsing Terraform output as JSON failed: #{error}"
344
+ end
256
345
  end
257
346
  end
258
347
 
259
- # Runs the Terraform Client apply subcommand.
260
- #
261
348
  # @api private
262
- # @return [::Dry::Monads::Either] the result of the apply subcommand.
263
- # @see ::Kitchen::Terraform::Client::Command.apply
264
- def run_apply
265
- run(
266
- result:
267
- ::Kitchen::Terraform::Client::Command
268
- .apply(
269
- options:
270
- ::Kitchen::Terraform::Client::Options
271
- .new
272
- .enable_lock
273
- .lock_timeout(duration: config_lock_timeout)
274
- .disable_input
275
- .enable_auto_approve
276
- .maybe_no_color(toggle: !config_color)
277
- .parallelism(concurrent_operations: config_parallelism)
278
- .enable_refresh
279
- .state(path: config_state)
280
- .state_out(path: config_state)
281
- .vars(keys_and_values: config_variables)
282
- .var_files(paths: config_variable_files),
283
- working_directory: instance_directory
284
- )
285
- )
349
+ def apply_run_workspace_select_instance
350
+ ::Kitchen::Terraform::ShellOut
351
+ .run(
352
+ command: "workspace select kitchen-terraform-#{instance.name}",
353
+ duration: config_command_timeout,
354
+ logger: logger
355
+ )
286
356
  end
287
357
 
288
- # Runs the Terraform Client destroy subcommand.
289
- #
290
358
  # @api private
291
- # @return [::Dry::Monads::Either] the result of the destroy subcommand.
292
- # @see ::Kitchen::Terraform::Client::Command.destroy
293
- def run_destroy
294
- run(
295
- result:
296
- ::Kitchen::Terraform::Client::Command
297
- .destroy(
298
- options:
299
- ::Kitchen::Terraform::Client::Options
300
- .new
301
- .enable_lock
302
- .lock_timeout(duration: config_lock_timeout)
303
- .disable_input
304
- .maybe_no_color(toggle: !config_color)
305
- .parallelism(concurrent_operations: config_parallelism)
306
- .enable_refresh
307
- .state(path: config_state)
308
- .state_out(path: config_state)
309
- .vars(keys_and_values: config_variables)
310
- .var_files(paths: config_variable_files)
311
- .force,
312
- working_directory: instance_directory
313
- )
314
- )
359
+ def apply_run_validate
360
+ ::Kitchen::Terraform::ShellOut
361
+ .run(
362
+ command:
363
+ "validate " \
364
+ "-check-variables=true " \
365
+ "#{config_color_flag} " \
366
+ "#{config_variables_flags} " \
367
+ "#{config_variable_files_flags} " \
368
+ "#{config_root_module_directory}",
369
+ duration: config_command_timeout,
370
+ logger: logger
371
+ )
315
372
  end
316
373
 
317
- # Runs the Terraform Client init subcommand.
318
- #
319
374
  # @api private
320
- # @return [::Dry::Monads::Either] the result of the init subcommand.
321
- # @see ::Kitchen::Terraform::Client::Command.init
322
- def run_init
323
- run(
324
- result:
325
- ::Kitchen::Terraform::Client::Command
326
- .init(
327
- options:
328
- ::Kitchen::Terraform::Client::Options
329
- .new
330
- .disable_input
331
- .enable_lock
332
- .lock_timeout(duration: config_lock_timeout)
333
- .maybe_no_color(toggle: !config_color)
334
- .upgrade
335
- .from_module(source: config_directory)
336
- .enable_backend
337
- .force_copy
338
- .backend_configs(keys_and_values: config_backend_configurations)
339
- .enable_get
340
- .maybe_plugin_dir(path: config_plugin_directory)
341
- .verify_plugins(toggle: config_verify_plugins),
342
- working_directory: instance_directory
343
- )
344
- )
375
+ def create_run_init
376
+ ::Kitchen::Terraform::ShellOut
377
+ .run(
378
+ command:
379
+ "init " \
380
+ "-input=false " \
381
+ "-lock=true " \
382
+ "#{config_lock_timeout_flag} " \
383
+ "#{config_color_flag} " \
384
+ "-upgrade " \
385
+ "-force-copy " \
386
+ "-backend=true " \
387
+ "#{config_backend_configurations_flags} " \
388
+ "-get=true " \
389
+ "-get-plugins=true " \
390
+ "#{config_plugin_directory_flag} " \
391
+ "-verify-plugins=true " \
392
+ "#{config_root_module_directory}",
393
+ duration: config_command_timeout,
394
+ logger: logger
395
+ )
345
396
  end
346
397
 
347
- # Runs the Terraform Client output subcommand.
348
- #
349
398
  # @api private
350
- # @return [::Dry::Monads::Either] the result of the init subcommand.
351
- # @see ::Kitchen::Terraform::Client::Command.output
352
- def run_output
353
- run(
354
- result:
355
- ::Kitchen::Terraform::Client::Command.output(
356
- options:
357
- ::Kitchen::Terraform::Client::Options
358
- .new
359
- .json
360
- .state(path: config_state),
361
- working_directory: instance_directory
362
- )
363
- )
399
+ def create_run_workspace_new_instance
400
+ ::Kitchen::Terraform::ShellOut
401
+ .run(
402
+ command: "workspace new kitchen-terraform-#{instance.name}",
403
+ duration: config_command_timeout,
404
+ logger: logger
405
+ )
364
406
  end
365
407
 
366
- # Runs the Terraform Client validate subcommand.
367
- #
368
408
  # @api private
369
- # @return [::Dry::Monads::Either] the result of the validate subcommand.
370
- # @see ::Kitchen::Terraform::Client::Command.validate
371
- def run_validate
372
- run(
373
- result:
374
- ::Kitchen::Terraform::Client::Command
375
- .validate(
376
- options:
377
- ::Kitchen::Terraform::Client::Options
378
- .new
379
- .enable_check_variables
380
- .maybe_no_color(toggle: !config_color)
381
- .vars(keys_and_values: config_variables)
382
- .var_files(paths: config_variable_files),
383
- working_directory: instance_directory
384
- )
385
- )
409
+ def create_run_workspace_select_instance
410
+ ::Kitchen::Terraform::ShellOut
411
+ .run(
412
+ command: "workspace select kitchen-terraform-#{instance.name}",
413
+ duration: config_command_timeout,
414
+ logger: logger
415
+ )
386
416
  end
387
417
 
388
- # Runs the Terraform Client version subcommand.
389
- #
390
418
  # @api private
391
- # @return [::Dry::Monads::Either] the result of the version subcommand.
392
- # @see ::Kitchen::Terraform::Client::Command.version
393
- def run_version
394
- run result: ::Kitchen::Terraform::Client::Command.version(working_directory: config.fetch(:kitchen_root))
419
+ def destroy_run_destroy
420
+ ::Kitchen::Terraform::ShellOut
421
+ .run(
422
+ command:
423
+ "destroy " \
424
+ "-force " \
425
+ "-lock=true " \
426
+ "#{config_lock_timeout_flag} " \
427
+ "-input=false " \
428
+ "#{config_color_flag} " \
429
+ "#{config_parallelism_flag} " \
430
+ "-refresh=true " \
431
+ "#{config_variables_flags} " \
432
+ "#{config_variable_files_flags} " \
433
+ "#{config_root_module_directory}",
434
+ duration: config_command_timeout,
435
+ logger: logger
436
+ )
395
437
  end
396
438
 
397
- # Memoizes the path to the Test Kitchen suite instance directory at `.kitchen/kitchen-terraform/<suite>-<platform>`.
398
- #
399
439
  # @api private
400
- # @return [::String] the path to the Test Kitchen suite instance directory.
401
- def instance_directory
402
- @instance_directory ||= instance_pathname filename: "/"
440
+ def destroy_run_init
441
+ ::Kitchen::Terraform::ShellOut
442
+ .run(
443
+ command:
444
+ "init " \
445
+ "-input=false " \
446
+ "-lock=true " \
447
+ "#{config_lock_timeout_flag} " \
448
+ "#{config_color_flag} " \
449
+ "-force-copy " \
450
+ "-backend=true " \
451
+ "#{config_backend_configurations_flags} " \
452
+ "-get=true " \
453
+ "-get-plugins=true " \
454
+ "#{config_plugin_directory_flag} " \
455
+ "-verify-plugins=true " \
456
+ "#{config_root_module_directory}",
457
+ duration: config_command_timeout,
458
+ logger: logger
459
+ )
403
460
  end
404
461
 
405
- # 1. Prepares the instance directory
406
- # 2. Executes `terraform init` in the instance directory
407
- # 3. Executes `terraform validate` in the instance directory
408
- # 4. Executes a provided subcommand in the instance directory
409
- #
410
462
  # @api private
411
- # @raise [::Kitchen::ActionFailed] if the result of the action is a failure.
412
- # @see ::Kitchen::Driver::Terraform#prepare_instance_directory
413
- # @see ::Kitchen::Driver::Terraform#run_init
414
- # @see ::Kitchen::Driver::Terraform#run_validate
415
- # @yieldreturn [::Dry::Monads::Either] the result of a Terraform Client subcommand.
416
- def workflow
417
- prepare_instance_directory
418
- .bind do
419
- run_init
420
- end
421
- .bind do
422
- run_validate
423
- end
424
- .bind do
425
- yield
426
- end
427
- .or do |failure|
428
- raise(
429
- ::Kitchen::ActionFailed,
430
- failure
431
- )
432
- end
463
+ def destroy_run_workspace_delete_instance
464
+ ::Kitchen::Terraform::ShellOut
465
+ .run(
466
+ command: "workspace delete kitchen-terraform-#{instance.name}",
467
+ duration: config_command_timeout,
468
+ logger: logger
469
+ )
470
+ end
471
+
472
+ # @api private
473
+ def destroy_run_workspace_new_instance
474
+ ::Kitchen::Terraform::ShellOut
475
+ .run(
476
+ command: "workspace new kitchen-terraform-#{instance.name}",
477
+ duration: config_command_timeout,
478
+ logger: logger
479
+ )
480
+ end
481
+
482
+ # @api private
483
+ def destroy_run_workspace_select_default
484
+ ::Kitchen::Terraform::ShellOut
485
+ .run(
486
+ command: "workspace select default",
487
+ duration: config_command_timeout,
488
+ logger: logger
489
+ )
490
+ end
491
+
492
+ # @api private
493
+ def destroy_run_workspace_select_instance
494
+ ::Kitchen::Terraform::ShellOut
495
+ .run(
496
+ command: "workspace select kitchen-terraform-#{instance.name}",
497
+ duration: config_command_timeout,
498
+ logger: logger
499
+ )
433
500
  end
434
501
  end