Terraform Hands‐On Troubleshooting - DevWithNehaCloud/Oracle-Cloud-Infrastructure-wiki GitHub Wiki

Terraform Troubleshooting Guide

Issue #1: Terraform Using Instance Principal Instead of API Key Authentication

Error Encountered

While running the Terraform plan command:

terraform plan

Terraform was attempting to authenticate using Instance Principal instead of the intended API Key Authentication method.

As a result, authentication-related errors were observed, and Terraform was unable to communicate successfully with OCI services.


How I Identified the Issue

I enabled Terraform debug logging and reviewed the environment configuration.

During troubleshooting, I discovered that the environment was configured to use Instance Principal authentication:

OCI_AUTH=InstancePrincipal
OCI_AUTH_TYPE=instance_principal

Because of these settings, Terraform was ignoring the API Key credentials and attempting to authenticate using Instance Principal.


Root Cause

The OCI Provider was not explicitly instructed to use API Key authentication.

Terraform automatically picked up the Instance Principal authentication settings available in the environment.


Resolution

I explicitly configured the OCI Provider to use API Key authentication by adding the following line to the provider block:

provider "oci" {
  auth = "APIKey"

  tenancy_ocid     = var.tenancy_ocid
  user_ocid        = var.user_ocid
  fingerprint      = var.fingerprint
  private_key_path = var.private_key_path
  region           = var.region
}

After updating the provider configuration, Terraform successfully authenticated using the configured API Key credentials.


Verification

terraform plan
terraform apply

Both commands executed successfully, confirming that Terraform was now using API Key authentication instead of Instance Principal authentication.


Key Learning

When multiple OCI authentication methods are available, explicitly defining the authentication type in the provider configuration helps avoid unexpected authentication behavior.


Useful Debug Commands

Generate Terraform debug log:

TF_LOG=DEBUG terraform plan > tf-debug.log

View the log file:

cat tf-debug.log

Search for authentication-related entries:

grep -i auth tf-debug.log

Search for OCI provider-related messages:

grep -i oci tf-debug.log

Issue #2: Invalid Target Error While Destroying a Specific Module Instance

Error Encountered

While attempting to destroy a specific instance created through a module, I executed the following command:

terraform destroy -target="module.dev_instance_creation["dev_instance03"]"

Terraform returned the following error:

Error: Invalid target

Index brackets must contain either a literal number or a literal string.

How I Identified the Issue

I carefully reviewed the target address and noticed that the command contained nested double quotes.

The resource key:

"dev_instance03"

was already enclosed in double quotes inside the square brackets, while the entire target string was also wrapped in double quotes.

This caused Terraform to incorrectly parse the target address.


Root Cause

Terraform could not correctly interpret the nested double quotes used inside the target argument.

Problematic command:

terraform destroy -target="module.dev_instance_creation["dev_instance03"]"

The outer and inner quotation marks conflicted with each other during parsing.


Resolution

I enclosed the entire target address in single quotes while keeping the resource key inside double quotes:

terraform destroy -target='module.dev_instance_creation["dev_instance03"]'

This allowed Terraform to correctly interpret the module path and instance key.


Verification

After executing the corrected command:

terraform destroy -target='module.dev_instance_creation["dev_instance03"]'

Terraform successfully identified the target resource and destroyed only the specified instance.


Key Learning

When a Terraform target address contains a string key inside square brackets, the key must remain in double quotes. To avoid parsing issues, wrap the entire target expression in single quotes.

Correct Format

terraform destroy -target='module.<module_name>["resource_key"]'

Example

terraform destroy -target='module.dev_instance_creation["dev_instance03"]'

This approach prevents quote conflicts and ensures Terraform correctly interprets the target resource address.

Issue #3: Root Module Variable Not Declared in Advanced Modular Approach

Error Encountered

While running the Terraform plan command:

terraform plan

Terraform returned an error similar to:

Error: Reference to undeclared input variable

A variable named "dev_shape" has not been declared.

or

Error: Reference to undeclared input variable

A variable named "dev_boot_volume_size" has not been declared.

Environment Setup

I was using an Advanced Modular Terraform Structure:

compute_service/
│
├── dev/
│   ├── instance.tf
│   └── variables.tf
│
└── instance_module/
    ├── main.tf
    └── variables.tf

In this setup:

  • dev folder acts as the Root Module.
  • instance_module acts as the Child Module.

How I Identified the Issue

In the Root Module (dev/instance.tf), I was passing values to the module as shown below:

module "dev_instance_creation" {

  env_shape            = var.dev_shape
  env_swiggy_finance   = var.dev_swiggy_finance
  env_boot_volume_size = var.dev_boot_volume_size

}

The Child Module (instance_module/variables.tf) already contained:

variable "env_shape" {}
variable "env_swiggy_finance" {}
variable "env_boot_volume_size" {}

However, Terraform was still failing during the plan phase.

After reviewing the configuration, I realized that the Root Module variables were missing.


Root Cause

I had declared the module variables inside:

instance_module/variables.tf

but forgot to declare the corresponding Root Module variables inside:

dev/variables.tf

Terraform was trying to read:

var.dev_shape
var.dev_swiggy_finance
var.dev_boot_volume_size

but these variables did not exist in the Root Module.

As a result, Terraform could not resolve the variable references and failed during validation.


Resolution

I added the missing variable declarations in the Root Module (dev/variables.tf):

variable "dev_shape" {
  type = string
}

variable "dev_swiggy_finance" {
  type = string
}

variable "dev_boot_volume_size" {
  type = number
}

After declaring the Root Module variables, Terraform successfully passed the values to the Child Module.


Verification

terraform validate
terraform plan

Both commands completed successfully after adding the missing variable declarations.


Key Learning

In an Advanced Modular Terraform Structure, variables must be declared at both levels when required:

Root Module Variable
        ↓
Module Input
        ↓
Child Module Variable
        ↓
Resource Consumption

Declaring a variable only inside the Child Module is not sufficient if the Root Module is referencing its own variable names (for example, var.dev_shape or var.dev_boot_volume_size).

Both the Root Module and Child Module must have the required variable definitions for successful variable mapping.

Issue #4: Incorrect Module Source Path While Creating Child Compartments

Error Encountered

While running the Terraform plan command:

terraform plan

Terraform failed with an error similar to:

Error: Failed to read module directory

or

Error: Unreadable module directory

or

Unable to evaluate directory symlink

Environment Setup

I was creating multiple child compartments using a modular Terraform structure:

identity_service/
│
├── dev/
│   ├── compartment.tf
│   └── variables.tf
│
└── compartment_module/
    ├── main.tf
    └── variables.tf

How I Identified the Issue

One child compartment was being created successfully, but another child compartment failed during the planning phase.

After reviewing the module block, I found that the source path was incorrect.

Example:

module "swiggy_dev_network_compartment" {

  source = "compartment_module"

}

Terraform could not locate the module because the path was not relative to the current working directory.


Root Cause

The module source path was specified incorrectly.

Terraform was unable to find the module directory referenced in the source parameter.

Since Terraform resolves module paths relative to the current directory, an incorrect path causes module initialization to fail.


Resolution

I corrected the module source path by using a relative path:

module "swiggy_dev_network_compartment" {

  source = "../compartment_module"

}

The .. notation instructs Terraform to move one directory level up and then locate the module folder.

After updating the source path, Terraform successfully located the module and loaded its configuration.


Verification

terraform init
terraform validate
terraform plan

Terraform successfully initialized the module and generated the execution plan without any errors.


Key Learning

Always verify the module source path when working with Terraform modules.

Incorrect Path

source = "compartment_module"

Correct Relative Path

source = "../compartment_module"

Path Resolution Example

identity_service/
│
├── dev/
│   └── compartment.tf
│
└── compartment_module/

From the dev folder, Terraform must move one level up before accessing the compartment_module directory:

../compartment_module

Using the correct relative path ensures that Terraform can successfully locate and load the required module.

Issue #5: Forgot to Run Terraform Init After Adding or Modifying a Module

Error Encountered

After adding a new module or modifying the module source path, I directly executed:

terraform plan

Terraform returned an error similar to:

Error: Module not installed

or

Error: Module not initialized

or

Error: Failed to load module

Environment Setup

I was working with a modular Terraform structure:

compute_service/
│
├── dev/
│   ├── instance.tf
│   └── variables.tf
│
└── instance_module/
    ├── main.tf
    └── variables.tf

I had recently added a new module block or modified the module source path.


How I Identified the Issue

The module configuration looked correct, and the source path was also valid.

However, Terraform was unable to locate or load the module.

After reviewing the workflow, I realized that I had updated the module configuration but had not reinitialized Terraform.


Root Cause

Whenever a new module is added or an existing module source is modified, Terraform must download and initialize the module metadata.

Since terraform init was not executed, Terraform was still using the previous initialization data and could not recognize the updated module configuration.


Resolution

I reinitialized the Terraform working directory:

terraform init

Terraform successfully downloaded and initialized the required module components.

After that:

terraform validate
terraform plan

executed successfully.


Verification

terraform init
terraform validate
terraform plan

All commands completed successfully without module-related errors.


Key Learning

Whenever you perform any of the following actions:

  • Add a new module
  • Modify a module source path
  • Add a new provider
  • Upgrade a provider version
  • Clone a Terraform project into a new environment

Always run:

terraform init

before executing:

terraform plan
terraform apply

Best Practice Workflow

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply

Following this sequence helps prevent initialization and module-loading issues.

Terraform fmt and Terraform validate

Terraform fmt

The terraform fmt command is used to automatically format Terraform configuration files according to Terraform's standard coding style.

It helps maintain consistent indentation, spacing, and alignment across all .tf files, making the code easier to read and maintain.

Command

terraform fmt

Example

Before

resource "oci_core_instance" "server" {
display_name="dev-server"
shape="VM.Standard.E4.Flex"
}

After

resource "oci_core_instance" "server" {
  display_name = "dev-server"
  shape        = "VM.Standard.E4.Flex"
}

Benefits

  • Improves code readability
  • Maintains consistent formatting
  • Follows Terraform best practices
  • Makes collaboration easier in team environments

Terraform validate

The terraform validate command checks the Terraform configuration for syntax errors and configuration issues before deployment.

It validates the configuration locally without creating, modifying, or deleting any resources.

Command

terraform validate

What It Checks

  • Syntax errors
  • Missing brackets or quotes
  • Invalid resource definitions
  • Missing variable declarations
  • Invalid references
  • Module configuration issues

Example

display_name = var.instance_name

If the variable is not declared:

variable "instance_name" {
}

Terraform will return a validation error.

Benefits

  • Detects configuration issues early
  • Prevents deployment failures
  • Ensures Terraform files are structurally correct
  • Helps troubleshoot errors before running terraform plan

Recommended Terraform Workflow

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply

Summary

Command Purpose
terraform init Initialize providers and modules
terraform fmt Format Terraform code
terraform validate Validate Terraform configuration
terraform plan Preview infrastructure changes
terraform apply Deploy infrastructure changes

Issue 6

Error: Count Created More Instances Than Expected

While creating instances using the count meta-argument, the expectation was to create only 3 instances:

resource "oci_core_instance" "server" {
  count = 3

  display_name = "terraform-instance-${count.index + 1}"
}

However, Terraform showed a plan to create a total of 4 instances.


Cause

Terraform processes all .tf files present in the same directory as a single configuration.

An existing instance resource was already defined in another .tf file within the same directory. When count = 3 was added to a new resource block, Terraform evaluated both resource definitions together:

  • Existing instance resource = 1
  • New resource with count = 3 = 3

Total instances planned = 4

Terraform was functioning correctly; the issue occurred because multiple instance resources were present in the same Terraform configuration directory.


How to Verify

Review all Terraform files in the current directory:

ls *.tf

Check all instance resources:

grep -R "oci_core_instance" .

Review the execution plan:

terraform plan

Solution

  • Check all .tf files in the working directory.
  • Remove or comment out unwanted instance resources.
  • Ensure only the required resource block exists.
  • Use separate folders/modules for different deployments when appropriate.
  • Run terraform plan before every terraform apply to verify the exact number of resources being created.

Key Learning

Terraform does not execute files individually. It loads and evaluates all .tf files within the same directory as a single configuration.

Therefore, resources defined across multiple files are combined during planning and deployment.

Example:

  • instance.tf contains 1 instance resource
  • server.tf contains another instance resource with count = 3

Terraform will process both resources together and plan to create:

1 + 3 = 4 Instances

Best Practice

✅ Keep only related resources in the same Terraform root module.

✅ Review all .tf files before running terraform apply.

✅ Always run:

terraform plan

before:

terraform apply

to verify the exact resources that will be created, modified, or destroyed.

Issue 7

Error: Terraform Plan Stuck or Not Responding

Terraform configuration was valid and all required files were present. However, the following command was getting stuck for a long time:

terraform plan

or

terraform apply

No meaningful error message was displayed, and Terraform was not progressing further.


Possible Causes

  • Outdated provider plugins
  • Corrupted provider cache
  • Provider version compatibility issues
  • Incomplete provider installation
  • Network connectivity issues while communicating with OCI APIs
  • Terraform dependency initialization issues

Symptoms

  • Terraform remains stuck at provider initialization.
  • Plan takes unusually long to start.
  • No infrastructure changes are displayed.
  • Command appears to hang indefinitely.

Example:

Initializing provider plugins...

or

Planning...

and remains in that state for an extended period.


Solution

Upgrade and refresh the provider plugins:

terraform init -upgrade

After running the command, execute:

terraform plan

again.

In many cases, Terraform downloads updated provider versions and resolves the issue.


Alternative Troubleshooting Steps

Remove the local Terraform cache:

rm -rf .terraform

Remove the lock file:

rm -f .terraform.lock.hcl

Reinitialize Terraform:

terraform init

Advanced Troubleshooting

Enable debug logging:

TF_LOG=DEBUG terraform plan > tf-debug.log

Review the generated log file:

cat tf-debug.log

This can help identify provider communication or initialization issues.


Verification

Check installed providers:

terraform providers

Run:

terraform plan

and confirm that Terraform completes successfully.


Resolution

The issue was resolved by running:

terraform init -upgrade

which refreshed the provider plugins and updated the local Terraform dependency cache.


Key Learning

Even when Terraform code is correct, outdated or corrupted provider plugins can cause Terraform commands to hang or become unresponsive.

A common first troubleshooting step is:

terraform init -upgrade

before investigating more complex causes.