Debugging Terraform
1. Enabling Debug Logging
| Option | Values | Notes |
|---|---|---|
| TF_LOG | DEBUG, INFO, WARN, ERROR |
Set to DEBUG to enable detailed logging |
| TF_LOG_PATH | path/to/logfile.log |
Optional: specify a file path to write logs to |
Example: Setting Debug Logging
export TF_LOG=DEBUG
export TF_LOG_PATH=/tmp/terraform.log
terraform plan
Note: Debug logs can contain sensitive information. Ensure logs are handled securely and not committed to version control.
2. Setting Log Levels
| Level | Description | Use Case |
|---|---|---|
| TRACE | Most verbose logging, includes all internal operations and data flow | Debugging complex provider issues or internal Terraform behavior |
| DEBUG | Includes debug information about operations and state changes | Developing or troubleshooting custom providers or modules |
| INFO | Standard operational messages, such as resource creation/destruction | General monitoring of Terraform operations in production |
| WARN | Non-fatal warnings about unexpected conditions | Identifying potential issues without stopping execution |
| ERROR | Fatal errors that stop execution or cause failures | Investigating failures in Terraform runs |
Note: Log levels can also be set using the
TF_LOG environment variable or the -log-level CLI flag. Setting TF_LOG=DEBUG or higher will output detailed logs to stderr.
3. Logging to File
| Option | Values | Notes |
|---|---|---|
| TF_LOG | TRACE, DEBUG, INFO, WARN, ERROR |
Set log level for Terraform operations |
| TF_LOG_PATH | ./terraform.log |
File path to write logs to |
Example: Enable detailed logging to file
export TF_LOG=DEBUG
export TF_LOG_PATH=./terraform-debug.log
terraform plan
Note: Logs include sensitive data. Ensure logs are stored securely and reviewed for sensitive information before sharing.
4. Using Terraform Console
| Command | Description | Usage |
|---|---|---|
| terraform console | Interactively evaluate Terraform expressions | terraform console |
Example: Evaluating Variables
terraform console
> var.instance_type
t3.micro
> var.vpc_id
vpc-12345678
Example: Evaluating Expressions
terraform console
> format("Instance %s is in VPC %s", var.instance_type, var.vpc_id)
Instance t3.micro is in VPC vpc-12345678
Note: The
terraform console command is useful for debugging and testing expressions before using them in your configuration files.
5. Testing Expressions
Example: Testing Expression Evaluation
output "test_result" {
value = "Hello, ${var.name}!"
}
| Expression Type | Description | Example | Notes |
|---|---|---|---|
| string interpolation | Embeds values within strings | "Hello, ${var.name}!" |
Uses ${} syntax |
| function calls | Invokes built-in functions | upper(var.name) |
Available in HCL v2+ |
| conditional expressions | Conditionally evaluates to a value | var.enabled ? "on" : "off" |
Uses ? : syntax |
| for expressions | Creates lists or maps from collections | [for i in var.items : i.value] |
Supports filtering and transformation |
Note: Use
terraform console to test expressions in isolation.
Warning: Complex expressions can be hard to debug; simplify where possible.
6. Validating Configuration
Use the terraform validate command to check your Terraform configuration files for syntax errors and other issues without actually applying changes.
| Option | Values | Description |
|---|---|---|
| -no-color | false |
Disable color output in the validation results |
| -check-variables | true |
Check that all variables required by the configuration are set |
Note: Validation does not require a backend or credentials to be configured, but it will check for issues in the configuration files themselves.
7. Checking Formatting
| Option | Values | Description |
|---|---|---|
| -check | true |
Check if the files are formatted, without modifying them |
| -diff | false |
Show a diff of the changes that would be made |
| -write | true |
Write the formatted files back to disk (default behavior) |
Note: The
terraform fmt command uses the official HCL formatter and ensures consistent formatting across all Terraform files.
Warning: Running
terraform fmt without flags will modify files in place. Use -check to verify formatting before applying changes.
8. Reviewing Plan Output
| Field | Description | Example |
|---|---|---|
| Changes | Summarizes the actions Terraform will take (create, update, destroy) | 1 to add, 1 to change, 0 to destroy |
| Resources | List of resources affected by the plan | aws_instance.web |
| Action | Operation to be performed (create, update, delete) | create, update, destroy |
Example: Plan Output Summary
terraform plan
Refreshing Terraform state in-memory prior to plan...
The Terraform run will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {
+ ami = "ami-0c55018923d741336"
+ instance_type = "t2.micro"
}
# aws_security_group.web will be updated in-place
~ resource "aws_security_group" "web" {
~ description = "Old description" -> "New description"
}
# aws_elb.web will be destroyed
- resource "aws_elb" "web" {
- name = "old-elb"
}
Plan: 1 to add, 1 to change, 1 to destroy.
Note: The plan output includes a color-coded summary indicating what actions will be taken. Red indicates destruction, yellow indicates updates, and green indicates creation.
Key Elements to Review
- Resource Changes: Ensure all resource changes align with intended modifications.
- Dependencies: Verify that dependencies between resources are correctly identified.
- Destroy Actions: Confirm any destruction actions are intentional and backed up.
9. Using Terraform Show
| Command | Description | Flags |
|---|---|---|
| terraform show | Displays the current state of your Terraform-managed infrastructure | -no-color, -json |
Note: The
terraform show command reads the current state file (terraform.tfstate) and displays it in a human-readable format. It does not interact with remote state or refresh the state from a remote backend.
10. Debugging Provider Issues
| Issue Type | Description | Solution/Command |
|---|---|---|
| Provider Not Found | Provider not found when running terraform init |
Ensure provider is declared in required_providers block with correct source and version |
| Version Mismatch | Provider version does not match what is expected by Terraform | Run terraform init -upgrade to update to latest compatible version |
| Authentication Failure | Provider fails to authenticate with cloud service (e.g., AWS, GCP) | Check credentials in ~/.aws/credentials, GOOGLE_APPLICATION_CREDENTIALS, or environment variables |
| Network Issues | Provider cannot reach remote API due to network or firewall rules | Verify connectivity and ensure required ports are open (e.g., 443 for HTTPS) |
Example: Provider Configuration with Debugging
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-west-2"
access_key = "<your-access-key>"
secret_key = "<your-secret-key>"
}
Note: Use
TF_LOG=DEBUG environment variable to enable detailed logs during terraform apply.
Warning: Avoid including sensitive credentials in logs or version-controlled files.
11. Handling Rate Limits
| Rate Limit | Description | Recommended Action |
|---|---|---|
| API Requests Per Second | 10 requests/second |
Implement exponential backoff with jitter |
| Concurrent Requests | 50 concurrent requests |
Use max_concurrent_requests in provider config |
| Daily Request Limit | 50,000 requests/day |
Monitor usage via logs or dashboard |
Example: Configuring Retry Logic in Terraform
provider "aws" {
region = "us-west-2"
retry {
max_attempts = 5
backoff = "exponential"
jitter = true
}
}
Note: AWS API rate limits can vary by service and region. Always consult the official AWS documentation for the most accurate limits.
Warning: Exceeding rate limits may result in temporary blocking or throttling, causing Terraform operations to fail.