How To Debug Terraform
Multiple options and techniques for debugging Terraform and OpenTofu Infrastructure plans #
Access Infrastructure Data from the State #
Terraform issues while using official providers and common resources are mostly configuration-related. Using terraform state the details of the resources can be examined.
Listing Resources #
Use this process to list Terraform-managed infrastructure resources:
$ terraform state list
data.aws_iam_policy_document.access_assume_role
data.aws_iam_policy_document.project_defaults
data.aws_iam_policy_document.project_ec2
aws_iam_access_key.project_1_admin
aws_iam_group.project_1_admins
aws_iam_group.project_1_devs
aws_iam_group.super_admins
aws_iam_policy.access_assume_role
aws_iam_policy.project_defaults
aws_iam_policy.project_ec2
aws_iam_user.project_1_admin
aws_iam_user.project_1_dev
aws_iam_user_policy_attachment.user_policy_access_assume_role
aws_iam_user_policy_attachment.user_policy_project_defaults
aws_subnet.ditwl-sn-za-pro-pri-02
aws_subnet.ditwl-sn-za-pro-pub-00
aws_vpc.ditlw-vpc
Accessing resources #
Access Terraform resource details with terraform state show aws_vpc.name-of-resource:
$ terraform state show aws_vpc.ditlw-vpc
# aws_vpc.ditlw-vpc:
resource "aws_vpc" "ditlw-vpc" {
arn = "arn:aws:ec2:us-east-1:831....2212234:vpc/vpc-0cb3cad6544bd2691"
assign_generated_ipv6_cidr_block = false
cidr_block = "172.21.0.0/19"
default_network_acl_id = "acl-0d88e6275c2111bc4"
default_route_table_id = "rtb-0d1b9b2cb61c820f0"
default_security_group_id = "sg-0254ed1ab3ab43fa5"
dhcp_options_id = "dopt-5800d822"
enable_dns_hostnames = false
enable_dns_support = true
enable_network_address_usage_metrics = false
id = "vpc-0cb3cad6544bd2691"
instance_tenancy = "default"
ipv6_netmask_length = 0
main_route_table_id = "rtb-0d1b9b2cb61c820f0"
owner_id = "831....2212234"
tags = {
"Name" = "ditlw-vpc"
}
tags_all = {
"Name" = "ditlw-vpc"
}
}
Debug API / Provider Communication #
Useful when the problem is not in the configuration but in the communication between Terraform (or OpenTofu) and the cloud API, for example permission errors or unexpected API responses.
Enable Terraform debug #
Terraform and OpenTofu use the value of the environment variable TF_LOG to define the log level. Available values are TRACE, DEBUG, INFO, WARN or ERROR. Additionally, you can specify a destination file for the log by setting the environment variable TF_LOG_PATH to the full path of the desired destination.
Set the debug variables and execute the Terraform plan to see the output:
$ export TF_LOG=DEBUG
$ # Optional: export TF_LOG_PATH=~/debug.txt
$ terraform plan # or: tofu plan
2020/07/31 20:19:01 [WARN] Log levels other than TRACE are currently unreliable, and are supported only for backward compatibility.
Use TF_LOG=TRACE to see Terraform's internal logs.
----
2020/07/31 20:19:01 [INFO] Terraform version: 0.12.26
2020/07/31 20:19:01 [INFO] Go runtime version: go1.12.13
2020/07/31 20:19:01 [INFO] CLI args: []string{"/usr/bin/terraform", "plan"}
2020/07/31 20:19:01 [DEBUG] Attempting to open CLI config file: /home/jruiz/.terraformrc
2020/07/31 20:19:01 [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2020/07/31 20:19:01 [INFO] CLI command args: []string{"plan"}
2020/07/31 20:19:01 [WARN] Log levels other than TRACE are currently unreliable, and are supported only for backward compatibility.
Use TF_LOG=TRACE to see Terraform's internal logs.
----
2020/07/31 20:19:01 [DEBUG] New state was assigned lineage "cc420085-6d12-cb64-c041-a0ed135c58ed"
2020/07/31 20:19:01 [DEBUG] checking for provider in "."
2020/07/31 20:19:01 [DEBUG] checking for provider in "/usr/bin"
2020/07/31 20:19:01 [DEBUG] checking for provider in ".terraform/plugins/linux_amd64"
2020/07/31 20:19:01 [DEBUG] found provider "terraform-provider-aws_v2.67.0_x4"
2020/07/31 20:19:01 [DEBUG] found provider "terraform-provider-external_v1.2.0_x4"
2020/07/31 20:19:01 [DEBUG] found valid plugin: "aws", "2.67.0", "/home/jruiz/git/github/terraform-aws-ec2-rds-basic-free/.terraform/plugins/linux_amd64/terraform-provider-aws_v2.67.0_x4"
2020/07/31 20:19:01 [DEBUG] found valid plugin: "external", "1.2.0", "/home/jruiz/git/github/terraform-aws-ec2-rds-basic-free/.terraform/plugins/linux_amd64/terraform-provider-external_v1.2.0_x4"
2020/07/31 20:19:01 [DEBUG] checking for provisioner in "."
2020/07/31 20:19:01 [DEBUG] checking for provisioner in "/usr/bin"
2020/07/31 20:19:01 [DEBUG] checking for provisioner in ".terraform/plugins/linux_amd64"
2020/07/31 20:19:01 [INFO] backend/local: starting Plan operation
...
2020/07/31 20:19:30 [DEBUG] ProviderTransformer: "module.aws_sg_rds_mariadb_pro_pub_01.aws_security_group.default" (*terraform.NodeValidatableResource) needs provider.aws
6.aws_subnet.default - *terraform.NodeValidatableResource
provider.aws - *terraform.NodeApplyableProvider
module.aws_sn_zb_pro_pub_36.output.id - *terraform.NodeApplyableOutput
module.aws_sn_zb_pro_pub_36.var.az - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.cidr - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.description - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.name - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.public - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.vpc_id - *terraform.NodeApplyableModuleVariable
module.aws_sr_ec2_default_internet_to_ssh.aws_security_group_rule.default - *terraform.NodeValidatableResource
....
2020/07/31 20:19:30 [DEBUG] ProviderTransformer: "module.aws_sg_rds_mariadb_pro_pub_01.aws_security_group.default" (*terraform.NodeValidatableResource) needs provider.aws
6.aws_subnet.default - *terraform.NodeValidatableResource
provider.aws - *terraform.NodeApplyableProvider
module.aws_sn_zb_pro_pub_36.output.id - *terraform.NodeApplyableOutput
module.aws_sn_zb_pro_pub_36.var.az - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.cidr - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.description - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.name - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.public - *terraform.NodeApplyableModuleVariable
module.aws_sn_zb_pro_pub_36.var.vpc_id - *terraform.NodeApplyableModuleVariable
module.aws_sr_ec2_default_internet_to_ssh.aws_security_group_rule.default - *terraform.NodeValidatableResource
...
Use Terraform Console #
The terraform console command allows you to interactively evaluate expressions and query data from your Terraform configuration and state. Access the console and evaluate expressions or inspect resources.
terraform console
module.aws_sn_zb_pro_pub_36.var.vpc_id
Generate Terraform Infrastructure Graphs #
The graph command generates a visual representation of a configuration or an execution plan (it needs Graphviz).
terraform graph | dot -Tsvg > graph.svg
See also the checks and tools of Terraform Tools: validate, TFLint and the security scanners.