1.6.1.1. Terraform

It goes without saying that maintaining a Terraform module requires the use of Terraform itself. When maintaining modules, we rely on Terraform to perform the following tasks for us:

  • Code formatting and format checking
  • Code syntax validation

1.6.1.1.1. Code Formatting and Format Checking

When maintaining large-scale Terraform modules, ensuring consistent code style and high readability is key to team collaboration and long-term maintenance. Terraform provides the terraform fmt command to automatically format configuration files, ensuring they adhere to official standards and styles.

1.6.1.1.1.1. What is terraform fmt

The terraform fmt command is used to rewrite Terraform configuration files to a canonical format and style. This command automatically adjusts indentation, alignment, and spacing to make the code more readable and consistent. This is particularly important for multi-person collaboration and code reviews.

By default, terraform fmt scans all .tf files in the current directory and formats them. If a file is already compliant, the command makes no changes.

1.6.1.1.1.2. -check

Using terraform fmt -check allows you to verify if the configuration files are already formatted according to the canonical style. If all files are compliant, the command returns an exit status of 0; otherwise, it returns a non-zero status and lists the unformatted files. This option does not modify any files, making it suitable as a formatting check step in CI/CD pipelines.

1.6.1.1.1.3. -recursive

By default, terraform fmt only processes files in the current directory. Adding the -recursive option causes the command to process .tf files in all subdirectories recursively. This is essential for large projects containing multiple modules or submodules.

1.6.1.1.1.4. Example Commands

Here are some commonly used command examples:

# Format all .tf files in the current directory
terraform fmt

# Check if .tf files in the current directory and all subdirectories are formatted
terraform fmt -check -recursive

1.6.1.1.1.5. Using terraform fmt in CI/CD Pipelines

Integrating terraform fmt into your CI/CD pipeline allows for automatic checking of code formatting, ensuring that all committed code adheres to standards. For example, the following script can be used to check module code formatting:

#!/usr/bin/env bash
echo "==> Checking terraform codes are formatted..."
error=false
terraform fmt -check -recursive || error=true
if ${error}; then
  echo "------------------------------------------------"
  echo ""
  echo "The preceding files contain terraform codes that are not correctly formatted or contain errors."
  echo ""
  echo "to easily fix all terraform codes:"
  echo "$ make fmt"
  echo ""
  exit 1
fi
exit 0

1.6.1.1.1.6. Considerations

  • Version Compatibility: Different versions of Terraform may have slight adjustments to formatting standards. After upgrading your Terraform version, it is recommended to rerun terraform fmt to ensure all files comply with the new standards.
  • Opinionated Nature: terraform fmt is an "opinionated" tool and does not provide options for custom formatting rules. Its goal is to encourage a unified style across all Terraform projects.
  • Manual Adjustments: For certain complex expressions or specific formatting needs, terraform fmt might not yield the desired result. In such cases, developers may need to adjust the format manually or reach a consensus during code review.

1.6.1.1.2. Code Syntax Validation

In a CI/CD pipeline, aside from using terraform fmt to maintain code style, another critical step is using the terraform validate command to verify the syntax and structure of configuration files.

1.6.1.1.2.1. What is terraform validate

The terraform validate command validates the .tf or .tf.json configuration files in the current directory. It checks for syntax correctness and verifies that resource blocks, module calls, and variable references adhere to Terraform's syntax specifications.

This command does not connect to remote state files or cloud provider APIs, making it suitable for local development and early validation steps in Continuous Integration (CI) processes.

1.6.1.1.2.2. Usage

Before using terraform validate, ensure the working directory has been initialized (i.e., terraform init has been run). If you do not wish to connect to a remote backend, you can use the following command to initialize (-backend=false is crucial here; it ensures Terraform does not attempt to connect to a remote backend. Connecting would require user credentials, and since we only want to perform a syntax check—often on code from potentially unknown third parties that could contain malicious code designed to steal credentials—skipping backend connection is safer and more convenient):

terraform init -backend=false

Then, run the following command to perform validation:

terraform validate

If the configuration syntax is correct and the structure is consistent, the command will output:

Success! The configuration is valid.

Otherwise, it will display error messages to help locate and fix the issues.

1.6.1.1.2.3. Using terraform validate in CI/CD Pipelines

Integrating terraform validate into CI/CD pipelines allows for automatic verification of configuration file syntax and structure before code merging or deployment, ensuring validity. For example, the following script can be used to validate module configuration files:

#!/usr/bin/env bash
echo "==> Validating module terraform codes..."
error=false
(terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true
if ${error}; then
     echo "------------------------------------------------"
     echo ""
     echo "Some Terraform codes contain errors."
     echo "$(terraform validate -json)"
     echo ""
     exit 1
fi
echo "==> Checking examples terraform codes are validate..."
examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d)
for d in $examples; do
  (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true
  if ${error}; then
     echo "------------------------------------------------"
     echo ""
     echo "Some Terraform codes contain errors."
     pwd
     echo "$(cd $d && terraform validate -json)"
     echo ""
     exit 1
  fi
done

echo "==> Checking module terraform code are validate..."
if [ ! -d modules ]; then
  echo "==> Warning - no modules directory found"
else
  modules=$(find ./modules -maxdepth 1 -mindepth 1 -type d)
  for d in $modules; do
    (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true
    if ${error}; then
      echo "------------------------------------------------"
      echo ""
      echo "Some Terraform codes contain errors."
      pwd
      echo "$(cd $d && terraform validate -json)"
      echo ""
      exit 1
    fi
  done
fi

exit 0

By adding this validation step to the CI/CD pipeline, configuration errors can be detected early, reducing issues during subsequent deployments and improving module stability and reliability.

results matching ""

    No results matching ""