Root Module Example
Suppose your workspace looks like this:Running
tofu init, tofu plan, or tofu apply inside aws-instance treats it as the root module.Calling Child Modules
To avoid duplicating infrastructure code, package a directory as a child module and invoke it:main.tf in development:
module "dev-webserver"assigns a logical name.source = "../aws-instance"points to the child module’s path.
development is the root module, calling the ../aws-instance child module.
Building a Reusable Payroll App Module
FlexIT Consulting needs the same payroll stack in multiple regions. The architecture uses:- One EC2 instance (custom AMI)
- One DynamoDB table
- One S3 bucket

Define the Module
Organize reusable code undermodules/payroll-app:
app_server.tf
s3_bucket.tf
dynamodb_table.tf
variables.tf
- Hardcoded: instance type, DynamoDB table name, and hash key.
- Configurable: AMI, region, bucket via variables.
Deploy in US East (us-east-1)
Create a root module for the US deployment:The S3 bucket name combines the region prefix with the default bucket variable.
Deploy in London (eu-west-2)
Repeat for the UK region:OpenTofu can source community or verified modules from the registry, just like Terraform. For example, to provision a security group:

Always pin the
version to prevent unexpected module changes. Use tofu get or tofu init to fetch registry modules.