Skip to content

Dependency Management

Terraform modules are reusable components that encapsulate infrastructure configurations, but their effectiveness depends on how they are sourced and managed. This section explores how to source modules from local paths, versioned repositories, and the Terraform Registry, along with strategies for managing dependencies between modules to ensure consistency and reliability in infrastructure as code workflows.


Understanding Module Sources

Terraform supports multiple module sources, enabling flexible reuse of configurations. The most common sources include:

1. Local Paths

Modules can be sourced from local file paths, ideal for private or internal modules. Use a relative or absolute path to reference the module directory.

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

2. Versioned Repositories

Modules hosted in version-controlled repositories (e.g., Git) can be sourced using a URL with a version constraint. This ensures compatibility across environments.

module "database" {
  source = "git::https://github.com/myorg/terraform-modules.git//database?ref=v2.1.0"
}

3. Terraform Registry

The Terraform Registry hosts public modules, which can be sourced using their module address. This is ideal for standardized, community-maintained modules.

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
}

Dependency Management

Terraform automatically resolves dependencies between modules, but explicit management is critical for stability. Key practices include:

1. Version Constraints

Use required_version to enforce compatibility between modules. This prevents unintended behavior from version mismatches.

module "app" {
  source = "terraform-aws-modules/ec2-instance/aws"
  required_version = ">= 2.0"
}

2. Lock Files

Terraform generates a .terraform.lock.hcl file to lock module versions. This ensures consistent deployments across environments.

terraform init -lock

3. Explicit Dependencies

Use depends_on to define explicit dependencies between modules when Terraform’s automatic ordering isn’t sufficient.

module "app" {
  source = "./modules/app"
  depends_on = [module.vpc]
}

Best Practices for Module Reusability

  • Version Everything: Always version modules in repositories or registries to avoid drift.
  • Prioritize Registry Modules: Use public registry modules for widely adopted configurations.
  • Test in Isolation: Validate modules independently before integrating them into larger projects.
  • Document Inputs/Outputs: Clearly define module interfaces to simplify integration.
  • Automate Locking: Integrate .terraform.lock.hcl into CI/CD pipelines to enforce version consistency.

Key takeaways

  • Use local paths, Git repositories, or the Terraform Registry to source modules based on your use case.
  • Leverage required_version and .terraform.lock.hcl to lock dependencies and avoid version conflicts.
  • Explicitly define dependencies with depends_on when automatic ordering falls short.
  • Prioritize versioning, testing, and documentation to ensure robust, reusable modules.
  • Automate dependency management to maintain consistency across development and production environments.