Note:

Build a Terraform Validation Pipeline using Terraform Test Framework and Oracle Cloud Infrastructure DevOps

Introduction

Organizations frequently utilize Terraform modules to manage intricate resource provisioning and offer a straightforward interface for developers to input the necessary parameters for deploying the desired infrastructure. Modules facilitate code reuse and provide organizations with a way to standardize the deployment of common workloads, such as a three-tier web application, a cloud networking environment, or a data analytics pipeline. When developing Terraform modules, authors typically begin with manual testing. This involves using commands like terraform validate for syntax validation, terraform plan to preview the execution plan, and terraform apply, followed by manually inspecting the resource configurations in the Oracle Cloud Infrastructure (OCI) Console. Manual testing, however, is prone to human error, not scalable, and can lead to unintended issues. Since modules are used by multiple teams within an organization, it is crucial to thoroughly test any changes before release.

Terraform test is a new testing framework designed for module authors to conduct unit and integration tests for Terraform modules. It allows the creation of infrastructure as defined in the module, performs validation checks on the infrastructure, and destroys test resources regardless of whether the tests pass or fail. Additionally, Terraform test provides warnings if any resources cannot be destroyed. Using the same HashiCorp Configuration Language (HCL) syntax as Terraform modules, it minimizes the need for authors to learn other tools or programming languages.

Each Terraform test is in a test file. Terraform discovers test files based on their file extension: .tftest.hcl or .tftest.json. Every test file is composed of root-level attributes and blocks as follows:

Terraform carries out run blocks sequentially, mimicking a sequence of Terraform commands being run in the configuration directory. The sequence in which the variables and provider blocks are arranged does not matter, as Terraform evaluates all values within these blocks at the start of the testing process. For clarity, placing your variables and provider blocks at the start of the test file is advisable.

Objectives

Prerequisites

Task 1: Write Terraform Test to Validate Resource Creation

  1. We have covered the fundamental structure of a Terraform test file, let us write some basic tests to verify the functionality of the following Terraform configuration. The following Terraform configuration will create an OCI Object Storage Bucket of Standard tier.

    #main.tf
    
    resource "oci_objectstorage_bucket" "test_bucket" {
    
        compartment_id = var.compartment_id
        name = var.bucket_name
        namespace = var.bucket_namespace
        storage_tier = var.bucket_storage_tier
        versioning = var.bucket_versioning
    }
    
  2. Create the var.tf file with required variables.

    variable compartment_id { default = "<compartment-ocid>" }
    variable region { default = "<region>" }
    variable bucket_name { default = "<bucket-name>"}
    variable bucket_namespace { default = "<object-storage-namespace>"}
    variable bucket_access_type { default = "ObjectRead"}
    variable bucket_storage_tier { default = "Standard"}
    variable bucket_versioning {default = "Enabled"}
    
  3. Configure the OCI Terraform provider with the resource principal authorization, allows the provider to make API calls without needing to provide credentials within the provider definition. To set up the resource principal authorization for OCI provider, see Resource Principal Authorization.

  4. Create a Terraform test file in the tests directory. Here is an example of the directory structure:

    ├── main.tf 
    └── tests 
    └── test.tftest.hcl
    
  5. Update the test.tftest.hcl file, which checks whether the tier of created bucket is Standard or not.

    # test.tftest.hcl
    
    run "valid_bucket_tier" {
    
      command = plan
    
      assert {
        condition     = oci_objectstorage_bucket.test_bucket.storage_tier == "Standard"
        error_message = "bucket tier is not standard"
      }
    
    }
    

    Note: If the storage tier of the bucket is not standard, the test will fail.

  6. Push the above terraform files to the OCI code repository. We will use this code repository with our CI/CD pipeline.

Task 2: Build OCI DevOps Build Pipeline for Validating Terraform Configuration

In the build_spec.yamlfile, the terraform init and terraform validate commands are used to initialize Terraform and verify that the configuration is valid. Then, the terraform test command runs the configured tests. If any terraform tests fail, the pipeline will also fail.

version: 0.1
component: build
timeoutInSeconds: 10000
shell: bash      
failImmediatelyOnError: true

steps:
  - type: Command
    name: "Initialize Terraform"
    command: |
      terraform init
      terraform validate
  - type: Command
    name: "Test Terraform"
    command: |
      terraform test 

Next Steps

We have performed a simple assertion test in our Terraform configuration. You can perform different types of testing like Integration testing, Unit Testing, End to End testing and so on. For more information, see Terraform Tests.

This Terraform validation pipeline can be integrated with application CI/CD pipeline. Terraform validation pipeline will pull the artifacts from the prior stages and test the configuration before implementing the changes.

Acknowledgments

More Learning Resources

Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.