1.6.4.1. terrafmt

In large-scale infrastructure automation projects, Terraform configurations often exist not only within .tf files themselves but are also embedded in Markdown documents, test code, template strings, and even Go source code. How can we maintain high quality and consistent code style while ensuring the readability of these embedded HCL snippets? This is precisely the purpose for which terrafmt was created.

terrafmt is a command-line tool designed to extract, format, upgrade, and check Terraform configuration blocks embedded in various types of files. Its goal is similar to terraform fmt, but with a broader scope, supporting the handling of multiple nesting scenarios in both code and documentation.

1.6.4.1.1. Core Features of terrafmt

  • Extracting and Formatting Embedded Terraform Blocks

terrafmt automatically recognizes HCL code snippets within the following blocks and formats them:

start end
```hcl ```
```tf `,
```terraform `,
return fmt.Sprintf(` `,
return fmt.Sprintf(` `)
return ` `

For example, consider the following Markdown file:

```hcl
resource "aws_instance" "example" {
ami           = "ami-2757f631"
instance_type = "t2.micro"
}

```

With terrafmt, this can be automatically formatted into a clearer, properly indented form:

```hcl
resource "aws_instance" "example" {
  ami           = "ami-2757f631"
  instance_type = "t2.micro"
}
```
  • Batch Processing and Diff Checking

You can batch format Terraform blocks in all .md files within a directory using the following command:

find . | egrep ".md" | sort | while read f; do terrafmt fmt -f $f; done

You can also use the diff command to preview which parts will be formatted:

terrafmt diff -f README.md
  • Rich Output and Integration Options

terrafmt supports outputting extracted code blocks in various formats, such as plain text and JSON, facilitating automation integration and code analysis. Additionally, it returns different exit codes for different outcomes, making it convenient to perform automatic format checks and blocking in CI/CD pipelines.

1.6.4.1.2. Typical Command Usage

  • Extract Terraform blocks from a file

terrafmt blocks README.md

  • Show only the differences requiring formatting

terrafmt diff -f README.md

  • Format and update the file directly

terrafmt fmt -f README.md

  • Check format differences and block in CI using exit codes

terrafmt diff --check -f .

1.6.4.1.3. Differences and Advantages Over Traditional terraform fmt

Unlike the official terraform fmt tool, terrafmt is capable of handling embedded configuration blocks in files other than pure .tf files. Whether in Markdown documentation, Provider test code, or template strings, as long as the code block is wrapped in appropriate markers, it can be automatically extracted and standardized. This is crucial for teams that need to uniformly govern a large volume of documentation, tests, and module examples.

Furthermore, terrafmt offers excellent compatibility with Go templates (such as %[1]s), solving the issue where terraform fmt cannot directly process such strings.

1.6.4.1.4. Usage of terrafmt in AVM

AVM uses the following scripts to format HCL code within documentation and potential Terratest code:

echo "==> Fixing test and document terraform blocks code with terrafmt..."

files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md" -e "README-generated.md")
for f in $files; do
  terrafmt fmt -f "$f"
  retValue=$?
  if [ $retValue -ne 0 ]; then
    echo "------------------------------------------------"
    echo ""
    echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors."
    echo ""
    exit $retValue
  fi
done

Then, the following script is used to check if changes submitted in a Pull Request have messed up the formatting of HCL code in the documentation:

#!/usr/bin/env bash
echo "==> Checking documentation terraform blocks are formatted..."
files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md")
error=false
for f in $files; do
  terrafmt diff -c -q "$f"
  retValue=$?
  if [ $retValue -ne 0 ] && [ $retValue -ne 2 ]; then
      error=true
  fi
done
if ${error}; then
  echo "------------------------------------------------"
  echo ""
  echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors."
  echo "You can fix this by running make tools and then terrafmt on them."
  echo ""
  echo "to easily fix all terraform blocks:"
  echo "$ make terrafmt"
  echo ""
  exit 1
fi
exit 0

results matching ""

    No results matching ""