Terraform Format
Introduction
Consistent code formatting is a crucial aspect of collaborative development. When working with Infrastructure as Code (IaC) using Terraform, maintaining a standard code style helps improve readability, reduce errors, and make collaboration more efficient. The Terraform CLI provides a built-in formatting command called terraform fmt
that automatically formats your configuration files according to a standard style.
In this tutorial, you'll learn how to use the terraform fmt
command, understand its options, and see how it helps maintain code consistency across your Terraform projects.
What is Terraform Format?
Terraform Format (often referred to as terraform fmt
) is a built-in command in the Terraform CLI that automatically formats your configuration files to adhere to a standard style convention. This ensures that all Terraform code, regardless of who wrote it, follows consistent formatting rules.
The formatter adjusts:
- Indentation (two spaces)
- Alignment of equals signs and identifiers
- Argument ordering
- Line wrapping for long lines
- Comments positioning
- And other style elements
Why Use Terraform Format?
Using the built-in formatter offers several advantages:
- Consistency - Ensures all code follows the same style rules
- Readability - Makes code easier to read and understand
- Error reduction - Proper formatting can help identify syntax issues
- Team collaboration - Eliminates style debates and personal preferences
- Focus on content - Lets developers focus on code logic rather than style
Using the terraform fmt
Command
Basic Usage
The simplest way to use the command is to run it in a directory containing Terraform files:
terraform fmt
This will scan all .tf
and .tfvars
files in the current directory and its subdirectories, reformat them in place, and display the names of files that were changed.
Example
Let's look at a poorly formatted Terraform file:
provider "aws" {
region="us-west-2"
profile = "default"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
Department="Engineering"
}
}
After running terraform fmt
, the file would be reformatted to:
provider "aws" {
region = "us-west-2"
profile = "default"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
Department = "Engineering"
}
}
Notice how the formatter:
- Aligned the
=
signs - Added consistent indentation (two spaces)
- Organized tags alphabetically
- Applied consistent spacing
Common Command Options
The terraform fmt
command offers several options to customize its behavior:
Option | Description |
---|---|
-list=false | Don't list files that were changed |
-write=false | Don't overwrite the input files (check mode) |
-diff | Display a diff of the formatted changes |
-recursive | Process files in subdirectories |
-check | Return non-zero exit status if files need formatting |
Checking Files Without Modifying Them
If you want to check if files are properly formatted without making changes (useful in CI/CD pipelines):
terraform fmt -check
This will exit with a status code of 0 if all files are properly formatted and non-zero if any files need formatting.
Showing Differences
To see what changes the formatter would make without applying them:
terraform fmt -diff -write=false
This will display a diff of the changes that would be made.
Real-World Usage Examples
Integrating with Git Pre-commit Hooks
You can add Terraform formatting to your Git workflow using pre-commit hooks:
#!/bin/sh
# .git/hooks/pre-commit
# Format Terraform files
terraform fmt -recursive
# Add the formatted files back to the commit
git add $(git diff --name-only --cached | grep '\.tf$')
This ensures all Terraform files are properly formatted before they're committed.
Incorporating in CI/CD Pipelines
In a GitHub Actions workflow file:
name: Terraform Format Check
on: [push, pull_request]
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hashicorp/setup-terraform@v1
- name: Check Terraform formatting
run: terraform fmt -check -recursive
This workflow will fail if any Terraform files aren't properly formatted, ensuring code quality standards are maintained.
Format in VSCode
If you're using Visual Studio Code with the Terraform extension, you can configure it to format on save:
{
"editor.formatOnSave": true,
"[terraform]": {
"editor.defaultFormatter": "hashicorp.terraform"
}
}
With this configuration, your Terraform files will be automatically formatted whenever you save them.
Handling Complex Structures
Lists and Maps
Terraform format handles complex data structures elegantly:
# Before formatting
variable "subnets" {
type = list(object({
name = string
cidr = string
azs = list(string)
}))
default = [
{
name = "public"
cidr = "10.0.1.0/24"
azs = ["us-west-2a","us-west-2b"]
}
]
}
After terraform fmt
:
variable "subnets" {
type = list(object({
name = string
cidr = string
azs = list(string)
}))
default = [
{
name = "public"
cidr = "10.0.1.0/24"
azs = ["us-west-2a", "us-west-2b"]
}
]
}
Multiline Strings
Heredoc strings are preserved but still nicely formatted:
# Before formatting
resource "aws_iam_policy" "example" {
name = "example_policy"
description = "An example policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
After terraform fmt
:
resource "aws_iam_policy" "example" {
name = "example_policy"
description = "An example policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
Notice that while the heredoc content itself isn't reformatted (since it might be JSON or another format), the Terraform code structure around it is properly aligned.
Best Practices for Terraform Formatting
-
Format Early and Often
- Run
terraform fmt
before committing code - Configure your editor to format on save
- Run
-
Enforce in CI/CD Pipelines
- Add format checking to your CI/CD process
- Fail builds if formatting standards aren't met
-
Include in Development Workflow
- Add pre-commit hooks
- Review format changes during code reviews
-
Document Your Standards
- Include information about formatting expectations in your project README
- Reference the official HashiCorp style conventions
-
Format All Files
- Don't just format new files; run it on the entire codebase
Common Issues and Solutions
Issue: Format Changes Breaking JSON or YAML
Sometimes, formatting Terraform files with embedded JSON/YAML in heredocs can cause issues:
Solution: Use the indent
function instead of heredocs for better control:
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["ec2:Describe*"]
Effect = "Allow"
Resource = "*"
},
]
})
Issue: Team Members Not Using Formatting
Solution: Implement pre-commit hooks or CI/CD checks to enforce formatting standards.
Issue: Different Formatting With Different Terraform Versions
Solution: Standardize on a specific Terraform version in your project and document it.
The Terraform Style Convention
The Terraform formatter follows specific style conventions:
- Two-space indentation
- Arguments aligned by equals sign within blocks
- Equal sign alignment within collections (maps)
- Trailing commas on multiline blocks
- One blank line between blocks
- No blank lines within blocks (with some exceptions)
These conventions are based on common practices from languages like Go and are designed for maximum readability.
Summary
The terraform fmt
command is a powerful tool that helps maintain clean, consistent Terraform code. By automatically formatting your configuration files according to standard conventions, it improves readability, reduces errors, and makes collaboration easier. Incorporating formatting into your development workflow through editor integrations, pre-commit hooks, and CI/CD pipelines ensures that your Infrastructure as Code remains clean and maintainable.
Additional Resources
- Terraform Command Documentation
- Terraform Language Style Conventions
- HashiCorp Configuration Language (HCL) Specification
Exercises
- Take a poorly formatted Terraform file and run
terraform fmt
on it. Compare the before and after versions. - Create a Git pre-commit hook that formats your Terraform files automatically.
- Set up a CI workflow that checks if all Terraform files are properly formatted.
- Configure your code editor to format Terraform files on save.
- Try using the
-diff
flag to see what changes the formatter would make without applying them.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)