🐶
Terraform

Terraform Modules and required_providers: Explained

By Filip on 10/07/2024

Learn whether Terraform modules need their own required_providers blocks or inherit them from the root module and best practices for managing provider dependencies.

Terraform Modules and required_providers: Explained

Table of Contents

Introduction

In Terraform, modules are designed to be self-contained units of infrastructure code. To achieve this, each module must explicitly declare its provider dependencies using the required_providers block within a terraform block. This declaration specifies the source and version constraints for each provider the module relies on. This practice is crucial for several reasons.

Step-by-Step Guide

In Terraform, every module needs to explicitly declare its provider dependencies using required_providers within a terraform block. This declaration specifies the source of the provider (e.g., "hashicorp/aws") and the acceptable version constraints.

This requirement exists because modules are meant to be self-contained units of infrastructure code. By declaring providers directly within the module, you ensure that:

  1. Version Compatibility: The module will always use the intended provider version, preventing unexpected behavior from version mismatches.
  2. Reproducibility: Anyone using your module will automatically download and utilize the correct provider versions, ensuring consistent deployments across environments.
  3. Portability: Modules can be easily shared and reused across different Terraform configurations without relying on provider configurations defined elsewhere.

It's important to note that required_providers in a child module doesn't inherit declarations from the parent module. Each module must explicitly declare its own provider requirements. This ensures that modules remain independent and portable, even if they are used in different projects with potentially different provider configurations.

If you're transitioning from Terraform 0.12 to 0.13 or later, you'll need to add required_providers blocks to your modules. This change, while requiring a bit of upfront work, ultimately leads to more robust and maintainable Terraform code.

Code Example

This code demonstrates how to define required providers within a Terraform module for deploying an AWS EC2 instance. The module specifies the AWS provider source and version constraint, ensuring version compatibility and reproducibility. When using the module, it automatically downloads and uses the correct AWS provider version, regardless of the root module's provider configuration. This approach promotes module independence, portability, and consistent deployments.

Let's say you have a module for deploying an AWS EC2 instance:

modules/ec2-instance/main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

resource "aws_instance" "example" {
  ami           = "ami-0c94855a"
  instance_type = "t2.micro"
}

Explanation:

  • terraform block: This block is mandatory for declaring provider requirements.
  • required_providers block: This block specifies the providers needed by the module.
    • aws: The name of the provider as used within the module.
    • source: The source address of the provider. This tells Terraform where to download the provider plugin from.
    • version: The version constraint for the provider. This ensures compatibility and reproducibility. Here, ~> 4.0 means any version within the 4.x.x range.

Using the module:

Now, you can use this module in your root module or another module:

main.tf

module "ec2_instance" {
  source = "./modules/ec2-instance"
}

Benefits:

  • Version Compatibility: The ec2-instance module will always use a compatible version of the AWS provider, preventing issues from version mismatches.
  • Reproducibility: Anyone using this module will automatically download and use the correct AWS provider version, ensuring consistent deployments.
  • Portability: The ec2-instance module can be easily shared and reused in different Terraform configurations without relying on provider configurations defined elsewhere.

Important Note:

Even if your root module already defines the hashicorp/aws provider, the ec2-instance module still needs its own required_providers declaration. This ensures the module remains independent and portable.

Additional Notes

  • Terraform 0.13+ Feature: The required_providers block was introduced in Terraform 0.13. If you're using an older version, you'll need to upgrade to take advantage of this feature.
  • Version Constraints: Using version constraints like ~> 4.0 is crucial for maintaining compatibility. It ensures that future provider updates won't break your module unless they introduce major, backward-incompatible changes.
  • Provider Namespacing: If a module uses multiple providers from the same source (e.g., two different versions of the AWS provider), you can use aliases to distinguish them within the module.
  • Centralized Provider Management: While each module declares its own providers, you can still manage provider versions centrally using a version constraints file. This helps ensure consistency across your project.
  • Troubleshooting: If you encounter issues with required_providers, carefully review the error messages. They often provide clues about missing or incompatible provider versions.
  • Best Practices: Always explicitly declare required_providers in every module, even if it seems redundant. This promotes clarity, maintainability, and avoids potential conflicts in the future.

Summary

Terraform modules must explicitly declare their provider dependencies using the required_providers block within a terraform block. This declaration specifies the provider's source and acceptable version constraints.

Here's why:

| Benefit | Description

Conclusion

By explicitly declaring provider dependencies within each module using required_providers, Terraform ensures version compatibility, reproducibility, and portability. This practice guarantees that modules function as intended, regardless of where they are used, making your infrastructure code more robust and maintainable.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait