Terraform Debug Mode: How to Enable TF_LOG and Read Debug Output
Enable Terraform debug mode with TF_LOG=DEBUG, save logs to file with TF_LOG_PATH, and troubleshoot terraform plan/apply errors.
DevOps
Install and configure TFLint to catch Terraform errors before terraform apply. Covers AWS/Azure/GCP plugins, .tflint.hcl config, CI/CD integration
TFLint is a linter for Terraform that catches errors terraform validate misses. It checks for:
t2.gigantic doesn't exist)terraform validate only checks syntax. TFLint checks whether your configuration makes sense.
brew install tflintcurl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bashchoco install tflintdocker run --rm -v $(pwd):/data -t ghcr.io/terraform-linters/tflintVerify installation:
$ tflint --version
TFLint version 0.53.0cd my-terraform-project/
tflint --init # Download plugins
tflint # Run linterThat's it. TFLint scans all .tf files in the current directory.
Create .tflint.hcl in your project root:
# .tflint.hcl
# Enable the AWS plugin
plugin "aws" {
enabled = true
version = "0.32.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
# Enforce naming conventions
rule "terraform_naming_convention" {
enabled = true
}
# Require descriptions on variables
rule "terraform_documented_variables" {
enabled = true
}
# Require descriptions on outputs
rule "terraform_documented_outputs" {
enabled = true
}
# Disallow deprecated syntax
rule "terraform_deprecated_interpolation" {
enabled = true
}
# Enforce standard module structure
rule "terraform_standard_module_structure" {
enabled = true
}Then initialize:
$ tflint --init
Installing `aws` plugin...
Installed `aws` (source: github.com/terraform-linters/tflint-ruleset-aws, version: 0.32.0)resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.superduper" # Doesn't exist!
}$ tflint
1 issue(s) found:
Error: "t2.superduper" is an invalid value as instance_type (aws_instance_invalid_type)
on main.tf line 3:
3: instance_type = "t2.superduper"terraform validate would pass this. terraform apply would fail after waiting for the API call.
resource "aws_instance" "web" {
ami = "not-an-ami"
}TFLint catches the invalid AMI format before you waste time on a failed plan.
# Old interpolation-only syntax
resource "aws_instance" "web" {
instance_type = "${var.instance_type}" # Deprecated since Terraform 0.12
}Warning: Interpolation-only expressions are deprecated (terraform_deprecated_interpolation)With the AWS plugin, you can enforce required tags:
# In .tflint.hcl
rule "aws_resource_missing_tags" {
enabled = true
tags = ["Environment", "Team", "ManagedBy"]
}Now every AWS resource must have these tags or TFLint reports an error.
plugin "aws" {
enabled = true
version = "0.32.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}Checks: invalid instance types, invalid AMIs, invalid IAM policy actions, security group rules, and more.
plugin "azurerm" {
enabled = true
version = "0.27.0"
source = "github.com/terraform-linters/tflint-ruleset-azurerm"
}plugin "google" {
enabled = true
version = "0.30.0"
source = "github.com/terraform-linters/tflint-ruleset-google"
}These rules work without any provider plugin:
| Rule | What It Checks |
|---|---|
terraform_naming_convention | Resource/variable/output naming patterns |
terraform_documented_variables | Variables have descriptions |
terraform_documented_outputs | Outputs have descriptions |
terraform_deprecated_interpolation | "${var.x}" → var.x |
terraform_unused_declarations | Unused variables, data sources, locals |
terraform_standard_module_structure | main.tf, variables.tf, outputs.tf exist |
terraform_workspace_remote | Warns about terraform.workspace with remote backends |
terraform_required_version | required_version is declared |
terraform_required_providers | required_providers block exists |
Enable them all for strict projects:
rule "terraform_naming_convention" { enabled = true }
rule "terraform_documented_variables" { enabled = true }
rule "terraform_documented_outputs" { enabled = true }
rule "terraform_deprecated_interpolation" { enabled = true }
rule "terraform_unused_declarations" { enabled = true }
rule "terraform_standard_module_structure" { enabled = true }
rule "terraform_required_version" { enabled = true }
rule "terraform_required_providers" { enabled = true }name: Terraform Lint
on: [pull_request]
jobs:
tflint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: terraform-linters/setup-tflint@v4
with:
tflint_version: v0.53.0
- run: tflint --init
- run: tflint --format compacttflint:
image: ghcr.io/terraform-linters/tflint:latest
script:
- tflint --init
- tflint --format compact
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"# .pre-commit-config.yaml
repos:
- repo: https://github.com/terraform-linters/tflint
rev: v0.53.0
hooks:
- id: tflinttflint # Default (human-readable)
tflint --format compact # One line per issue
tflint --format json # Machine-readable JSON
tflint --format junit # JUnit XML for CI
tflint --format sarif # SARIF for GitHub Code Scanning| Tool | What It Does | When to Use |
|---|---|---|
terraform validate | Syntax check only | Always (fast, built-in) |
| TFLint | Syntax + provider-specific + best practices | Always (catches real errors) |
terraform plan | Full API check against real infrastructure | Before apply |
tfsec / trivy | Security scanning | Security audits |
checkov | Policy compliance | Compliance requirements |
terraform-docs | Generate documentation | Module documentation |
Recommended pipeline order: terraform fmt → tflint → terraform validate → terraform plan
rule "terraform_naming_convention" {
enabled = true
format = "snake_case"
}tflint --ignore-rule=terraform_documented_variablestflint --chdir=modules/vpc/tflint --recursiveLearn by doing with interactive courses on CopyPasteLearn:
TFLint catches real errors that terraform validate misses — invalid instance types, missing tags, deprecated syntax, naming violations. Install it, add a .tflint.hcl with the AWS/Azure/GCP plugin, and integrate it into your CI pipeline. Run tflint before terraform plan to catch mistakes before they reach infrastructure.
Enable Terraform debug mode with TF_LOG=DEBUG, save logs to file with TF_LOG_PATH, and troubleshoot terraform plan/apply errors.
Encountering the Inconsistent Dependency Lock File error in Terraform? This guide explains the causes and provides step-by-step solutions to resolve the.
Complete guide to Terraform logging. Set TF_LOG to TRACE, DEBUG, INFO, WARN, or ERROR. Save verbose output to a file with TF_LOG_PATH. Works on Linux, macOS.
Install and run Terraform on Ubuntu 26.04 LTS Resolute Raccoon. Covers sudo-rs as default, APT 3.2 rollback, Kernel 7.0, Wayland-only, ROCm, and building...