kitchen-terraform 2.1.0 → 3.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 (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