How to Use Modules in Terraform: Syntax and Example
In Terraform, use
module blocks to include reusable code from local paths or remote sources. Define a module with its own configuration, then call it in your root configuration using module "name" { source = "path_or_url" }.Syntax
A module block calls reusable Terraform code. It has a source attribute to specify where the module lives. You can pass variables to the module and get outputs back.
- module "name": Names the module instance.
- source: Path or URL to the module code.
- variables: Inputs to customize the module.
- outputs: Values returned from the module.
terraform
module "example" { source = "./modules/example_module" variable1 = "value1" variable2 = "value2" }
Example
This example shows a root Terraform configuration calling a module that creates an AWS S3 bucket. The module is stored locally in ./modules/s3_bucket. The root passes the bucket name as a variable and gets the bucket ARN as output.
terraform
/* Root configuration: main.tf */ module "my_bucket" { source = "./modules/s3_bucket" bucket_name = "my-unique-bucket-12345" } output "bucket_arn" { value = module.my_bucket.bucket_arn } /* Module code: ./modules/s3_bucket/main.tf */ resource "aws_s3_bucket" "this" { bucket = var.bucket_name acl = "private" } output "bucket_arn" { value = aws_s3_bucket.this.arn } /* Module variables: ./modules/s3_bucket/variables.tf */ variable "bucket_name" { type = string }
Output
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
bucket_arn = arn:aws:s3:::my-unique-bucket-12345
Common Pitfalls
Common mistakes when using modules include:
- Not specifying the
sourceattribute correctly, causing Terraform to fail finding the module. - Forgetting to define variables in the module or not passing required variables from the root.
- Trying to use outputs before applying the module.
- Using relative paths incorrectly, especially when running Terraform from different directories.
terraform
/* Wrong: missing source attribute */ module "bad_module" { bucket_name = "test" } /* Right: include source */ module "good_module" { source = "./modules/s3_bucket" bucket_name = "test" }
Quick Reference
| Term | Description |
|---|---|
| module "name" | Defines a module block with a unique name |
| source | Location of the module code (local path, Git URL, registry) |
| variables | Input values passed to the module |
| outputs | Values returned from the module for use in root config |
| terraform init | Command to download modules before applying |
Key Takeaways
Use the module block with a source attribute to include reusable Terraform code.
Pass variables to customize the module and use outputs to get information back.
Always run terraform init to download modules before applying changes.
Check that module paths and variable names match exactly to avoid errors.
Modules help organize and reuse infrastructure code efficiently.