Cloud ComputingTerraform Debug: Enable TF_LOG and Troubleshoot
Enable Terraform debug mode with TF_LOG. Save logs to file, interpret output, and fix terraform plan and apply errors fast.
DevOps
Install TFLint on macOS, Linux, Windows, or Docker and lint your Terraform code. Covers .tflint.hcl config, AWS/Azure/GCP plugins, and 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 | bashThis script downloads the prebuilt tflint binary for your architecture and places it on your PATH — no package manager required.
choco 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 ScanningFor machine-readable output that scripts and CI tools can parse directly, use --format json (generic JSON) or --format sarif (structured findings for code-scanning integrations) instead of the default human-readable text.
| 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 --recursiveOn macOS run brew install tflint. On Linux, run the official install script: curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash. On Windows use choco install tflint. Verify with tflint --version.
Use the official Linux install script (curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash), which works on Ubuntu and other Debian-based distributions. It places the tflint binary on your PATH.
terraform validate only checks syntax and internal consistency. TFLint goes further: it catches provider-specific mistakes like invalid instance types, non-existent AMIs, deprecated syntax, and missing required tags — issues that only surface at apply time otherwise.
Install TFLint in your pipeline (the terraform-linters/setup-tflint GitHub Action is the simplest), run tflint --init to load plugins, then tflint --format compact. A non-zero exit code fails the build when lint issues are found.
Learn 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.
Cloud ComputingEnable Terraform debug mode with TF_LOG. Save logs to file, interpret output, and fix terraform plan and apply errors fast.
TerraformEncountering the Inconsistent Dependency Lock File error in Terraform? This guide explains the causes and provides step-by-step solutions to resolve the.
TerraformComplete 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...