TFLint is a pluggable Terraform linter focused on catching errors, enforcing best practices, and validating provider-specific issues. It goes beyond basic Terraform validation to ensure code quality and maintainability.
How the Starter Kit Uses TFLint
| Integration Point | Command | Description |
|---|---|---|
| Local validation | make lint | Runs TFLint across all environment directories to catch issues before committing |
| CI enforcement | make validate-full | Calls TFLint before any Terraform deployment; failing checks block the pipeline |
| Full validation | make validate-full | Includes TFLint as part of comprehensive validation suite alongside Terraform validate, Checkov, and formatting checks |
Running TFLint manually
The starter kit provides convenient make commands:
make lint
Or run TFLint directly on a specific environment:
cd environments/test/
tflint --init # Download plugins (first time only)
tflint --format=compact
Run on all environments from the repository root:
tflint --recursive
Common Issues Detected
TFLint catches a wide range of code quality and provider-specific issues.
Code Quality Issues
| Issue | Check | Example |
|---|---|---|
| Naming conventions | terraform_naming_convention | Enforces snake_case over camelCase |
| Missing documentation | terraform_documented_variables | Requires descriptions on variables |
| Unused declarations | terraform_unused_declarations | Warns about declared but unused variables |
Naming Convention Example:
# Bad: Uses camelCase
variable "instanceType" {
type = string
}
# Good: Uses snake_case
variable "instance_type" {
type = string
}
Documentation Example:
# Bad: No description
variable "bucket_name" {
type = string
}
# Good: Includes description
variable "bucket_name" {
description = "Name of the S3 bucket for application data"
type = string
}
AWS-Specific Issues
| Issue Type | Examples |
|---|---|
| Invalid instance types | t2.invalid |
| Deprecated patterns | Outdated resource configurations |
| Invalid AMI IDs | Non-existent or inaccessible AMIs |
| Misconfigured properties | Invalid resource property values |
| Region availability | Resources not available in target region |
Example Output:
Warning: instance_type "t2.nano" is not available in region "us-west-2"
on main.tf line 12:
12: instance_type = "t2.nano"
Configuration
The starter kit includes a pre-configured .tflint.hcl file. For details on the default configuration and how to customize it, see the TFLint configuration section.
TFLint configuration file
Create a .tflint.hcl file in the repository root:
# .tflint.hcl
config {
module = true
force = false
}
plugin "terraform" {
enabled = true
preset = "recommended"
}
plugin "aws" {
enabled = true
version = "0.30.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
rule "terraform_naming_convention" {
enabled = true
}
rule "terraform_documented_variables" {
enabled = true
}
rule "terraform_unused_declarations" {
enabled = true
}
Plugin System
| Command | Description |
|---|---|
tflint --init | Initialize plugins (downloads configured plugins) |
tflint --version | List installed plugins and versions |
Available Plugins:
| Plugin | Provider | Description |
|---|---|---|
tflint-ruleset-aws | AWS | AWS provider-specific rules |
tflint-ruleset-azurerm | Azure | Azure provider-specific rules |
tflint-ruleset-google | GCP | GCP provider-specific rules |
Disabling specific rules
Per-file suppression
Disable a rule for the entire file:
# tflint-ignore: terraform_naming_convention
variable "legacyName" {
type = string
}
Inline suppression
Disable a rule for a specific block:
# tflint-ignore: terraform_documented_variables
variable "internal_var" {
type = string
}
Configuration file
Disable rules globally in .tflint.hcl:
rule "terraform_documented_variables" {
enabled = false
}
Output Formats
| Format | Command | Use Case |
|---|---|---|
| Compact (default) | tflint --format=compact | Human-readable output for local development |
| JSON | tflint --format=json | Parsing results in CI/CD pipelines or custom tooling |
| JUnit | tflint --format=junit > tflint-results.xml | Test reporting systems |
| Checkstyle | tflint --format=checkstyle | Compatible with many CI/CD tools and IDEs |
Compact Format Example:
environments/test/main.tf:10:1: Warning: Missing variable description (terraform_documented_variables)
environments/test/variables.tf:5:1: Error: variable "instanceType" should be snake_case (terraform_naming_convention)
Integration with CI/CD
The GitHub Actions workflow includes TFLint as part of the validation stage:
- name: Validate infrastructure
run: make validate-full
This runs all validation tools including TFLint, ensuring code quality checks pass before deployment. Failed checks block the pipeline, preventing code quality issues from reaching production.
For complete details on how TFLint integrates into the automated workflow, see the CI/CD Workflows documentation.
Performance tips
Recursive linting
Lint all directories at once:
tflint --recursive
Parallel execution
Speed up linting with parallel execution:
find environments -name "*.tf" -type f | xargs -P 4 -I {} dirname {} | sort -u | xargs -P 4 -I {} sh -c 'cd {} && tflint'
Caching
TFLint caches plugin downloads. Run tflint --init once, then subsequent runs are faster.
Best practices
- Run locally first: Use
make lintbefore committing to catch issues early - Keep plugins updated: Regularly update TFLint and its plugins for new rules and fixes
- Review all warnings: Don't ignore warnings—they often indicate maintainability issues
- Configure consistently: Use
.tflint.hclto ensure all team members use the same rules - Combine with Checkov: Use both tools together—TFLint focuses on code quality while Checkov focuses on security
- Fix formatting first: Run
make formatbefore linting to avoid formatting-related errors
Troubleshooting
Plugin download fails
If tflint --init fails:
# Clear plugin cache
rm -rf ~/.tflint.d/plugins
# Reinitialize
tflint --init
Module errors
If TFLint can't resolve modules:
# Initialize Terraform first
terraform init
# Then run TFLint
tflint
Rule conflicts
If rules conflict with your team's conventions:
# Disable specific rules in .tflint.hcl
rule "terraform_naming_convention" {
enabled = false
}
Next steps
Pair TFLint with Checkov for comprehensive validation coverage, and review the Makefile reference to see all available validation commands.