Skip to main content

How to write a reusable Terraform module

Package infrastructure into a Terraform module with variables and outputs, then call it from a root configuration to reuse it across environments.

Difficulty
Intermediate
Duration
50 minutes
Steps
6

What and why

A Terraform module is a reusable package of configuration with defined inputs and outputs. Modules turn copy-paste infrastructure into a parameterized component you can apply across dev, staging, and production with different values.

Prerequisites

  • Existing Terraform configuration you want to package.
  • Understanding of resources, variables, and outputs.
  • Terraform installed.

Steps

1. Create the module folder

A module is just a directory of .tf files. Create modules/bucket/ with main.tf, variables.tf, and outputs.tf.

2. Define input variables

In variables.tf:

variable "bucket_name" {
  type        = string
  description = "Globally unique bucket name"
}

variable "versioning" {
  type    = bool
  default = false
}

Variables are the module's public interface.

3. Add resources using variables

In main.tf:

resource "aws_s3_bucket" "this" {
  bucket = var.bucket_name
}

resource "aws_s3_bucket_versioning" "this" {
  bucket = aws_s3_bucket.this.id
  versioning_configuration {
    status = var.versioning ? "Enabled" : "Suspended"
  }
}

Reference inputs with var.<name>.

4. Expose outputs

In outputs.tf:

output "bucket_arn" {
  value = aws_s3_bucket.this.arn
}

Outputs return values to whoever calls the module.

5. Call the module

In your root main.tf:

module "logs" {
  source      = "./modules/bucket"
  bucket_name = "acme-logs-prod"
  versioning  = true
}

The source points to the module path; the other keys set its inputs.

Verification

Run terraform init to register the module, then terraform plan. The plan should show the module's resources prefixed with module.logs. Read the module output with terraform output after applying.

Next Steps

Publish the module to a registry or a shared Git repo and pin it to a version tag. Call the same module twice with different inputs to provision parallel environments. Add input validation blocks to catch bad values early.

Prerequisites

  • Working Terraform configuration
  • Understanding of resources and providers
  • Terraform installed

Steps

  • 1
    Create the module folder
  • 2
    Define input variables
  • 3
    Add resources using variables
  • 4
    Expose outputs
  • 5
    Call the module
  • 6
    Verify reuse across environments