Class: Kitchen::Driver::Terraform

Overview

The Terraform driver is the bridge between Test Kitchen and Terraform. It manages the state of the Terraform root module under test by shelling out and running Terraform commands.

Commands

The following command-line commands are provided by the driver.

kitchen create

A Test Kitchen instance is created through the following steps.

Initializing the Terraform Working Directory
Terraform >= 0.15.0

The working directory is initialized by running a command like the following example:

terraform init \
  -backend=true \
  [-backend-config=<backend_configurations[0]> ...] \
  -force-copy \
  -get=true \
  -input=false \
  [-no-color] \
  [-plugin-dir=<plugin_directory>] \
  [-upgrade=true] \
  <root_module_directory>

Terraform < 0.15.0

The working directory is initialized by running a command like the following example:

terraform init \
  -backend=true \
  [-backend-config=<backend_configurations[0]> ...] \
  -force-copy \
  -get=true \
  -get-plugins=true \
  -input=false \
  -lock=<lock> \
  -lock-timeout=<lock_timeout>s \
  [-no-color] \
  [-plugin-dir=<plugin_directory>] \
  [-upgrade=true] \
  -verify-plugins=true \
  <root_module_directory>

Creating or Selecting the Test Terraform Workspace

The workspace is created by running a command like the following example:

terraform workspace new <name>

The workspace is selected by running a command like the following example:

terraform workspace select <name>

kitchen destroy

A Test Kitchen instance is destroyed through the following steps.

Initializing the Terraform Working Directory
Terraform >= 0.15.0

The working directory is initialized by running a command like the following example:

terraform init \
  -backend=true \
  [-backend-config=<backend_configurations[0]> ...] \
  -force-copy \
  -get=true \
  -input=false \
  [-no-color] \
  [-plugin-dir=<plugin_directory>] \
  [-upgrade=true] \
  <root_module_directory>

Terraform < 0.15.0

The working directory is initialized by running a command like the following example:

terraform init \
  -backend=true \
  [-backend-config=<backend_configurations[0]> ...] \
  -force-copy \
  -get=true \
  -get-plugins=true \
  -input=false \
  -lock=<lock> \
  -lock-timeout=<lock_timeout>s \
  [-no-color] \
  [-plugin-dir=<plugin_directory>] \
  [-upgrade=true] \
  -verify-plugins=true \
  <root_module_directory>

Selecting or Creating the Test Terraform Workspace

The workspace is selected by running a command like the following example:

terraform workspace select <name>

The workspace is created by running a command like the following example:

terraform workspace new <name>

Destroying the Terraform State

The state is destroyed by running a command like the following example:

terraform destroy \
  -auto-approve \
  -lock=<lock> \
  -lock-timeout=<lock_timeout>s \
  -input=false \
  [-no-color] \
  -parallelism=<parallelism> \
  -refresh=true \
  [-var=<variables.first>...] \
  [-var-file=<variable_files.first>...] \
  <root_module_directory>

Selecting the Default Terraform Workspace

The workspace is selected by running a command like the following example:

terraform workspace select <name>

Deleting the Test Terraform Workspace

The workspace is deleted by running a command like the following example:

terraform workspace delete <name>

Configuration Attributes

The configuration attributes of the driver control the behaviour of the Terraform commands that are run. Within the Test Kitchen configuration file, these attributes must be declared in the driver mapping along with the plugin name.

driver:
  name: terraform
  a_configuration_attribute: some value

backend_configurations

This attribute comprises Terraform backend configuration arguments to complete a partial backend configuration.

Type

Mapping of scalars to scalars

Required

False

Default

{}

Example

_

backend_configurations:
  address: demo.consul.io
  path: example_app/terraform_state

client

driver.client is deprecated; use transport.client instead.

This attribute contains the pathname of the Terraform client to be used by Kitchen-Terraform.

If the value is not an absolute pathname or a relative pathname then Kitchen-Terraform will attempt to find the value in the directories of the ) PATH.

The pathname of any executable file which implements the interfaces of the following Terraform client commands may be specified: apply; destroy; get; init; validate; workspace.

Type

Scalar

Required

False

Default

terraform

Example

client: /usr/local/bin/terraform

Example

client: ./bin/terraform

Example

client: terraform

color

This attribute toggles colored output from systems invoked by the plugin.

Type

Boolean

Required

False

Default

If a terminal emulator is associated with the Test Kitchen process then true; else false.

Example

color: false

Caveat

This attribute does not toggle colored output from the Test Kitchen core, though it does use the same default logic. To toggle colored output from the core, the --color and --no-color command-line flags must be used.

command_timeout

driver.command_timeout is deprecated; use transport.command_timeout instead.

This attribute controls the number of seconds that the plugin will wait for Terraform commands to finish running.

Type

Integer

Required

False

Default

600

Example

command_timeout: 1200

lock

This attribute toggles locking of the Terraform state file.

Type

Boolean

Required

False

Default

true

Example

lock: false

lock_timeout

This attribute controls the number of seconds that Terraform will wait for a lock on the state to be obtained during operations related to state.

Type

Integer

Required

False

Default

0

Example

lock_timeout: 10

parallelism

This attribute controls the number of concurrent operations to use while Terraform walks the resource graph.

Type

Integer

Required

False

Default

10

Example

parallelism: 50

plugin_directory

This attribute contains the path to the directory which contains customized Terraform provider plugins to install in place of the official Terraform provider plugins.

Type

Scalar

Required

False

Default

There is no default value because any value will disable the normal Terraform plugin retrieval process.

Example

plugin_directory: /path/to/terraform/plugins

root_module_directory

driver.root_module_directory is deprecated; use transport.root_module_directory instead.

This attribute contains the path to the directory which contains the root Terraform module to be tested.

Type

Scalar

Required

False

Default

The working directory of the Test Kitchen process.

Example

root_module_directory: /path/to/terraform/root/module/directory

variable_files

This attribute comprises paths to Terraform variable files.

Type

Sequence of scalars

Required

False

Example

_

variable_files:
  - /path/to/first/variable/file
  - /path/to/second/variable/file

variables

This attribute comprises Terraform variables.

Type

Mapping of scalars to scalars

Required

False

Example

_

variables:
  image: image-1234
  zone: zone-5

verify_version

This attribute toggles strict or permissive verification of support for the version of the Terraform client specified by the client attribute.

Type

Boolean

Required

False

Default

</code>true</code>

Example

verify_version: false

Ruby Interface

This class implements the interface of Kitchen::Configurable which requires the following Reek suppressions: :reek:MissingSafeMethod { exclude: [ finalize_config! ] }

Examples:

Describe the create command

kitchen help create

Create a Test Kitchen instance

kitchen create default-ubuntu

Describe the destroy command

kitchen help destroy

Destroy a Test Kitchen instance

kitchen destroy default-ubuntu

Version:

  • 2

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Terraform::Configurable

included

Methods included from Terraform::ConfigAttribute::VariableFiles

#config_variable_files_default_value, included, to_sym

Methods included from Terraform::ConfigAttributeCacher

#define_cache, extended

Methods included from Terraform::ConfigAttribute::RootModuleDirectory

#config_root_module_directory_default_value, included, to_sym

Methods included from Terraform::ConfigAttribute::PluginDirectory

#config_plugin_directory_default_value, included, to_sym

Methods included from Terraform::ConfigAttribute::Client

#config_client_default_value, #doctor_config_client, included, to_sym

Constructor Details

#initialize(config = {}) ⇒ Kitchen::Driver::Terraform

#initialize prepares a new instance of the class.

Parameters:

  • config (Hash) (defaults to: {})

    the driver configuration.



261
262
263
264
# File 'lib/kitchen/driver/terraform.rb', line 261

def initialize(config = {})
  super config
  self.action_failed = ::Kitchen::Terraform::Raise::ActionFailed.new logger: logger
end

Instance Attribute Details

#transportObject

Returns the value of attribute transport.



174
175
176
# File 'lib/kitchen/driver/terraform.rb', line 174

def transport
  @transport
end

Instance Method Details

#create(state) ⇒ void

This method returns an undefined value.

Creates a Test Kitchen instance by initializing the working directory and creating a test workspace.

Parameters:

  • state (Hash)

    the mutable instance and driver state.

Raises:

  • (Kitchen::ActionFailed)

    if the result of the action is a failure.



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/kitchen/driver/terraform.rb', line 181

def create(state)
  ::Kitchen::Terraform::Driver::Create.new(
    config: config,
    connection: transport.connection(state),
    logger: logger,
    version_requirement: version_requirement,
    workspace_name: workspace_name,
  ).call
rescue => error
  action_failed.call message: error.message
end

#destroy(state) ⇒ void

This method returns an undefined value.

Destroys a Test Kitchen instance by initializing the working directory, selecting the test workspace, deleting the state, selecting the default workspace, and deleting the test workspace.

Parameters:

  • state (Hash)

    the mutable instance and driver state.

Raises:

  • (Kitchen::ActionFailed)

    if the result of the action is a failure.



199
200
201
202
203
204
205
206
207
208
209
# File 'lib/kitchen/driver/terraform.rb', line 199

def destroy(state)
  ::Kitchen::Terraform::Driver::Destroy.new(
    config: config,
    connection: transport.connection(state.merge(environment: { "TF_WARN_OUTPUT_ERRORS" => "true" })),
    logger: logger,
    version_requirement: version_requirement,
    workspace_name: workspace_name,
  ).call
rescue => error
  action_failed.call message: error.message
end

#doctor(state) ⇒ Boolean

doctor checks the system and configuration for common errors.

Parameters:

  • state (Hash)

    the mutable Kitchen instance state.

Returns:

  • (Boolean)

    true if any errors are found; false if no errors are found.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/kitchen/driver/terraform.rb', line 215

def doctor(state)
  errors = false

  deprecated_config.each_pair do |attribute, message|
    errors = true
    logger.warn "driver.#{attribute} is deprecated: #{message}"
  end

  methods.each do |method|
    next if !method.match? /doctor_config_.*/

    config_error = send method
    errors = errors || config_error
  end

  transport_errors = transport.doctor state
  verifier_errors = instance.verifier.doctor state

  errors || transport_errors || verifier_errors
end

#finalize_config!(instance) ⇒ self

#finalize_config! invokes the super implementation and then initializes the strategies.

Parameters:

  • instance (Kitchen::Instance)

    an associated instance.

Returns:

  • (self)

Raises:

  • (Kitchen::ClientError)

    if the instance is nil.



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/kitchen/driver/terraform.rb', line 241

def finalize_config!(instance)
  super

  self.deprecated_config ||= {}

  transport = instance.transport

  self.transport = if ::Kitchen::Transport::Terraform == transport.class
      transport
    else
      ::Kitchen::Transport::Terraform.new(config).finalize_config! instance
    end

  self
end