Terraform test context

The terraform context allows to apply Terraform configurations from within the test code. It exposes the full init(), apply() and destroy() lifecycle that can be used either to test Terraform modules, or to prepare an environment for other tests. When used the test context as well as the factory methods will always download the correct version for the architecture executing the tests, supporting Linux, MacOS and Windows on x86 and arm.

Test a Terraform config

Given a folder containing Terraform files, like for example

/module1/main.tf
resource "random_string" "string1" {
  length = 12
}

output "string1" {
  value = random_string.string1.id
}

The resources described in this file can be created using the Terraform test context

Test a terraform setup
package solidblocks.test.gradle.terraform

import de.solidblocks.infra.test.SolidblocksTest
import de.solidblocks.infra.test.SolidblocksTestContext
import kotlinx.serialization.Serializable
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(SolidblocksTest::class)
public class TerraformContext {

    @Serializable
    data class OutputType(val name: String)

    @Test
    fun terraformExtension(context: SolidblocksTestContext) {
        val modulePath = TerraformContext::class.java.getResource("/module").path

        val terraform = context.terraform(modulePath)
        terraform.init()
        terraform.apply()

        val output = terraform.output()

        val string1 = output.getString("string1")
        val number1 = output.getNumber("number1")
        val boolean1 = output.getBoolean("boolean1")

        val json1: OutputType = output.getObject("json1", OutputType::class)
        val json2: List<OutputType> = output.getList("jsonList1", OutputType::class)

        // destroy will be called automatically when all tests from the class are finished
    }
}
Options

The following options can be set to configure the Terraform process

package solidblocks.test.gradle.terraform

import de.solidblocks.infra.test.SolidblocksTest
import de.solidblocks.infra.test.SolidblocksTestContext
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(SolidblocksTest::class)
public class TerraformOptions {

    @Test
    fun terraformExtension(context: SolidblocksTestContext) {
        val modulePath = TerraformOptions::class.java.getResource("/module").path

        // use a specific Terraform version
        val terraform = context.terraform(modulePath, "1.14.1")

        // set terraform variable (implicitly sets the
        // environment variable 'TF_VAR_variable1'
        terraform.addVariable("variable1", "foo-bar")

        /// set environment variable for the terraform process, can be
        // used to pass credentials to the terraform providers
        terraform.addEnvironmentVariable("PROVIDER_TOKEN", "foo-bar")

        // do not clean up any resources when the test run fails,
        // e.g. destroy will not be executed after test run is finished
        context.cleanupAfterTestFailure(false)
    }
}