TFLint: Static Analysis for Terraform
Continuous integration is a key part of the CI/CD pipeline. One of the main components is static analysis, which I cover in my post Static Analysis, the First Step in any Application.
If you're working with Terraform, keeping your code clean, consistent, and error-free is key to maintaining infrastructure as code. That's where TFLint comes in. It's a powerful linter specifically for Terraform that helps you catch potential issues early.
What Is TFLint?
TFLint is a pluggable Terraform linter that checks for common issues like:
- Invalid resource names
- Deprecated syntax
- Best practices
- Cloud provider-specific issues (via plugins)
It works great alongside terraform fmt
and terraform validate
for a complete Terraform hygiene routine.
Installing TFLint
You can install TFLint using Homebrew on macOS:
brew install tflint
Or download a binary from the TFLint GitHub releases.
Basic Usage
Navigate to your Terraform project root, then run:
tflint
TFLint will scan .tf
files and print out warnings and errors.
If you have multiple directories, then run it recursively
tflint --recursive
Example .tflint.hcl
Configuration
Here’s a simple config file that enables AWS plugin checks:
config {
force = false
call_module_type = "local"
disabled_by_default = false
}
plugin "terraform" {
enabled = true
preset = "recommended"
}
plugin "aws" {
enabled = true
version = "0.29.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
region = "us-east-1"
}
rule "terraform_unused_declarations" {
enabled = false
}
Place this file in your project root as .tflint.hcl
.
Then run:
tflint --init
tflint
I added it to my aws-cld project on github and received a few errors:
Error: Reference to undeclared input variable
on aws-cld/examples/s3-website/env/main.tf line 7, in module "website":
7: project = var.project
An input variable with the name "project" has not been declared. This variable can be declared with a variable "project" {} block.
Error: Reference to undeclared input variable
on aws-cld/examples/s3-website/env/main.tf line 8, in module "website":
8: environment = var.environment
An input variable with the name "environment" has not been declared. This variable can be declared with a variable "environment" {} block.
Pro Tip: CI Integration
TFLint integrates well into Github actions pipelines. Add the following to your pull request actions, or create a new one just for linting.
- uses: actions/cache@v4
name: Cache plugin dir
with:
path: ~/.tflint.d/plugins
key: ${{ matrix.os }}-tflint-${{ hashFiles('.tflint.hcl') }}
- uses: terraform-linters/setup-tflint@v4
name: Setup TFLint
with:
tflint_version: v0.52.0
- name: Show version
run: tflint --version
- name: Init TFLint
run: tflint --init
env:
# https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
GITHUB_TOKEN: ${{ github.token }}
- name: Run TFLint
run: tflint -f compact
Final word
Static analysis is a key component of any CI/CD pipeline. Use tflint for all your Terraform code bases.