Overview
TFLint is a pluggable Terraform linter that catches errors, enforces best practices, and validates provider-specific issues. It goes beyond basic Terraform validation to ensure code quality and maintainability.
Integration
| Command | Description |
|---|---|
make lint | Run TFLint across all environments |
make validate-full | Run TFLint as part of full validation |
Running manually
# Using make
make lint
# Or directly
cd environments/staging/
tflint --init # Download plugins (first time)
tflint --format=compact
Run on all environments:
tflint --recursive
Common issues detected
Code quality
| Issue | Rule | Example |
|---|---|---|
| Naming | terraform_naming_convention | Enforces snake_case |
| Missing docs | terraform_documented_variables | Requires descriptions |
| Unused code | terraform_unused_declarations | Warns about unused variables |
Naming convention:
# Bad
variable "instanceType" { type = string }
# Good
variable "instance_type" { type = string }
Documentation:
# Bad
variable "bucket_name" { type = string }
# Good
variable "bucket_name" {
description = "Name of the S3 bucket for application data"
type = string
}
AWS-specific issues
| Issue | Description |
|---|---|
| Invalid instance types | t2.invalid |
| Deprecated patterns | Outdated resource configurations |
| Invalid AMI IDs | Non-existent AMIs |
| Region availability | Resources not available in target region |
Configuration
The starter kit includes .tflint.hcl:
plugin "aws" {
enabled = true
version = "0.32.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
plugin "terraform" {
enabled = true
preset = "recommended"
}
rule "terraform_naming_convention" {
enabled = true
format = "snake_case"
}
rule "terraform_documented_variables" {
enabled = true
}
rule "terraform_documented_outputs" {
enabled = true
}
rule "terraform_typed_variables" {
enabled = true
}
rule "terraform_unused_declarations" {
enabled = true
}
rule "terraform_deprecated_index" {
enabled = true
}
rule "terraform_required_version" {
enabled = true
}
rule "terraform_required_providers" {
enabled = true
}
Suppressing rules
Per-file
# tflint-ignore: terraform_naming_convention
variable "legacyName" {
type = string
}
Inline
# tflint-ignore: terraform_documented_variables
variable "internal_var" {
type = string
}
Configuration file
rule "terraform_documented_variables" {
enabled = false
}
Output formats
| Format | Command | Use case |
|---|---|---|
| Compact | tflint --format=compact | Local development |
| JSON | tflint --format=json | CI/CD pipelines |
| JUnit | tflint --format=junit | Test reporting |
| Checkstyle | tflint --format=checkstyle | IDE integration |
Best practices
- Run locally first: Use
make lintbefore committing - Keep plugins updated: Regularly update TFLint and plugins
- Review all warnings: Don't ignore maintainability issues
- Configure consistently: Use
.tflint.hclfor team consistency - Fix formatting first: Run
make formatbefore linting
Troubleshooting
Plugin download fails
rm -rf ~/.tflint.d/plugins
tflint --init
Module errors
terraform init # Initialize first
tflint
Next steps
- Checkov - Security scanning
- Makefile - Validation commands
- Linting Configuration - Full configuration