TFLint

Learn how the starter kit uses TFLint to enforce best practices and catch errors in Terraform configurations.


What is TFLint?

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

  • Local validation: make lint runs TFLint across all environment directories to catch issues before committing.
  • CI enforcement: The deploy workflow calls TFLint via make validate-full before any Terraform deployment. Failing checks block the pipeline.
  • Full validation: Running make validate-full includes TFLint as part of a 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:

Naming conventions

# Bad: Uses camelCase
variable "instanceType" {
  type = string
}

# Good: Uses snake_case
variable "instance_type" {
  type = string
}

Check: terraform_naming_convention

Missing documentation

# 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
}

Check: terraform_documented_variables

Unused declarations

# TFLint warns if this variable is declared but never used
variable "unused_var" {
  type = string
}

Check: terraform_unused_declarations

AWS-specific issues

  • Invalid instance types (e.g., t2.invalid)
  • Deprecated resource patterns
  • Invalid AMI IDs
  • Misconfigured resource properties
  • Region-specific resource availability

Example:

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

TFLint supports plugins for different providers:

# Initialize plugins (downloads configured plugins)
tflint --init

# List installed plugins
tflint --version

Available plugins:

  • tflint-ruleset-aws — AWS provider rules
  • tflint-ruleset-azurerm — Azure provider rules
  • tflint-ruleset-google — GCP provider 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

Compact format (default)

tflint --format=compact

Output:

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)

JSON format

tflint --format=json

Useful for parsing results in CI/CD pipelines or custom tooling.

JUnit format

tflint --format=junit > tflint-results.xml

Useful for test reporting systems.

Checkstyle format

tflint --format=checkstyle

Compatible with many CI/CD tools and IDEs.

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 Workflow 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 lint before 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.hcl to 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 format before 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.