What's Actually Happening

Terraform cannot find or download the modules referenced in your configuration. Modules are reusable packages of Terraform configuration that you call from other configurations. When module resolution fails, terraform init cannot complete, blocking all subsequent operations.

The Error You'll See

For registry modules:

``` Error: Failed to download module

Could not download module "vpc" (main.tf:15) source "terraform-aws-modules/vpc/aws": error looking up module: failed to retrieve available versions for "terraform-aws-modules/vpc/aws" from registry.terraform.io

Error: Module not found Module "vpc" (main.tf:15) is not available for download. ```

For local modules:

``` Error: Unreadable module directory

Unable to evaluate directory: lstat ../modules/networking: no such file or directory

Error: Module not found A local path must begin with either ./ or ../ to indicate a local module. ```

For Git modules:

``` Error: Failed to download module

Could not download module "vpc" (main.tf:15) source "github.com/terraform-aws-modules/terraform-aws-vpc": 'git clone --depth=1 https://github.com/terraform-aws-modules/terraform-aws-vpc' exited with error: fatal: repository not found ```

For version mismatches:

``` Error: No compatible versions

Module "vpc" (main.tf:15) has no versions that match ">= 5.0.0" Available versions: 4.0.0, 4.1.0, 4.2.0 ```

Why This Happens

Module resolution failures occur due to:

  1. 1.Typos in module source - Incorrect module name or path
  2. 2.Network connectivity - Cannot reach registry.terraform.io or Git hosting
  3. 3.Authentication required - Private registry or Git repository needs credentials
  4. 4.Version mismatch - Requested version doesn't exist
  5. 5.Module deleted - Publisher removed the module from registry
  6. 6.Path syntax errors - Local module path missing ./ or ../ prefix
  7. 7.Git ref not found - Specified branch or tag doesn't exist
  8. 8.Proxy blocking - Corporate firewall blocking registry access

Step 1: Verify Module Source Syntax

Check your module source is correctly formatted:

```hcl # Registry module - correct syntax module "vpc" { source = "terraform-aws-modules/vpc/aws" # namespace/name/provider version = "~> 5.0" }

# Registry module with version constraint module "eks" { source = "terraform-aws-modules/eks/aws" version = ">= 18.0.0, < 19.0.0" }

# Local module - MUST start with ./ or ../ module "networking" { source = "./modules/networking" # Relative path }

module "shared" { source = "../shared-modules/vpc" # Parent directory }

# Git module - various formats module "vpc" { source = "github.com/terraform-aws-modules/terraform-aws-vpc" }

# Git module with specific tag module "vpc" { source = "github.com/terraform-aws-modules/terraform-aws-vpc?ref=v5.0.0" }

# Git module with specific branch module "vpc" { source = "github.com/terraform-aws-modules/terraform-aws-vpc?ref=main" }

# Private Git repository module "internal" { source = "git::https://github.com/myorg/private-module.git?ref=v1.0.0" }

# Terraform Cloud private registry module "internal" { source = "app.terraform.io/myorg/vpc/aws" version = "1.0.0" } ```

Step 2: Test Network Connectivity

Verify you can reach the module source:

```bash # Test Terraform Registry connectivity curl -I https://registry.terraform.io

# Check specific module availability curl https://registry.terraform.io/v1/modules/terraform-aws-modules/vpc/aws

# Test Git connectivity git ls-remote https://github.com/terraform-aws-modules/terraform-aws-vpc

# Check proxy configuration echo $HTTP_PROXY echo $HTTPS_PROXY echo $NO_PROXY ```

Configure proxy if needed:

```bash export HTTP_PROXY="http://proxy.company.com:8080" export HTTPS_PROXY="http://proxy.company.com:8080" export NO_PROXY="localhost,127.0.0.1,.internal.company.com"

terraform init ```

Step 3: Fix Local Module Path Issues

Resolve local filesystem module errors:

```bash # Check directory structure find . -name "*.tf" -type f

# Verify module directory exists ls -la modules/networking/

# Check from current directory pwd ls -la ./modules/ ```

Fix the path based on your structure:

```hcl # If structure is: # . # ├── main.tf # └── modules/ # └── networking/

module "networking" { source = "./modules/networking" }

# If structure is: # ├── environments/ # │ └── prod/ # │ └── main.tf # └── modules/ # └── networking/

module "networking" { source = "../../modules/networking" } ```

Step 4: Handle Private Module Authentication

For private Terraform Cloud registry:

```bash # Login to Terraform Cloud terraform login

# This creates ~/.terraform.d/credentials.tfrc.json ```

For private Git repositories:

```bash # SSH authentication - ensure SSH key is configured ssh-add -l ssh -T git@github.com

# Use SSH-based source module "private" { source = "git::ssh://git@github.com/myorg/private-module.git" }

# HTTPS with token module "private" { source = "git::https://oauth2:${var.github_token}@github.com/myorg/private-module.git" }

# Or configure Git credential helper git config --global credential.helper store ```

For GitLab private modules:

bash
module "private" {
  source = "git::https://oauth2:${var.gitlab_token}@gitlab.com/myorg/terraform-module.git"
}

Step 5: Fix Version Constraint Issues

Check available versions:

```bash # Query registry for versions curl -s https://registry.terraform.io/v1/modules/terraform-aws-modules/vpc/aws/versions | jq '.modules[].versions[].version'

# Check GitHub tags git ls-remote --tags https://github.com/terraform-aws-modules/terraform-aws-vpc ```

Update your version constraint:

```hcl # Use specific available version module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "4.3.0" # If 5.0 doesn't exist }

# Use flexible constraint module "vpc" { source = "terraform-aws-modules/vpc/aws" version = ">= 4.0.0, < 6.0.0" }

# Allow any version (not recommended for production) module "vpc" { source = "terraform-aws-modules/vpc/aws" # Omit version } ```

Step 6: Clear Module Cache

Corrupted cache causes resolution failures:

```bash # Remove .terraform directory rm -rf .terraform/

# Remove lock file rm -f .terraform.lock.hcl

# Clear module cache rm -rf ~/.terraform.d/plugin-cache/

# Reinitialize fresh terraform init -upgrade ```

Step 7: Handle Git Reference Issues

For Git modules with specific refs:

```bash # Verify the ref exists git ls-remote https://github.com/myorg/module | grep v1.0.0

# Check available branches git ls-remote --heads https://github.com/myorg/module

# Check available tags git ls-remote --tags https://github.com/myorg/module ```

Fix the reference:

```hcl # Use existing tag module "vpc" { source = "github.com/myorg/module?ref=v1.0.0" }

# Use existing branch module "vpc" { source = "github.com/myorg/module?ref=main" }

# Use specific commit module "vpc" { source = "github.com/myorg/module?ref=a1b2c3d4" } ```

Step 8: Pre-download Modules for Offline Use

For air-gapped or restricted networks:

```bash # Download all modules to cache terraform init -get -get-plugins -upgrade

# Package for offline transfer tar -czf terraform-cache.tar.gz .terraform/

# On target system, extract tar -xzf terraform-cache.tar.gz

# Run init without downloading terraform init -get=false ```

Use filesystem mirror:

```hcl # In ~/.terraformrc provider_installation { filesystem_mirror { path = "/usr/local/share/terraform/modules" include = ["*/*/*"] } }

module_installation { filesystem_mirror { path = "/usr/local/share/terraform/modules" } } ```

Step 9: Verify Submodule References

For registry modules with submodules:

```hcl # Check module structure on registry page # terraform-aws-modules/vpc/aws might have submodules

# Submodule syntax - double slash module "subnet_addons" { source = "terraform-aws-modules/vpc/aws//modules/subnet-addons" }

# But many modules now have separate packages # Check if submodule is now a separate module module "vpc_endpoint" { source = "terraform-aws-modules/vpc-endpoint/aws" # Separate module } ```

Verify the Fix

After resolving module issues:

```bash # Initialize successfully terraform init

# You should see: # Initializing modules... # - vpc in .terraform/modules/vpc # Terraform has been successfully initialized!

# Verify modules downloaded ls -la .terraform/modules/

# Check module structure cat .terraform/modules/modules.json | jq .

# Test module usage terraform plan ```

Verify module configuration:

bash
# Check module inputs/outputs
ls .terraform/modules/vpc/
cat .terraform/modules/vpc/variables.tf
cat .terraform/modules/vpc/outputs.tf

Prevention Best Practices

Always pin module versions:

```hcl module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.0.0" # Pin exact version

name = "my-vpc" cidr = "10.0.0.0/16" } ```

Use lock files:

```bash # Commit lock file git add .terraform.lock.hcl

# Team uses consistent versions terraform init ```

Document module sources:

markdown
## Module Sources
- VPC: terraform-aws-modules/vpc/aws v5.0.0
- EKS: terraform-aws-modules/eks/aws v18.0.0
- Internal: ./modules/networking (local)