liveBook · Manning

Root module

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

A root module is the Terraform module defined by the configuration files in the current working directory and serving as the entry point for a Terraform operation.

Suppose a Terraform configuration must deploy an application using separate modules for its network-facing components, container service, database, and cache. The root module is the entry point that assembles those pieces. It can pass one module’s outputs into another module’s inputs and expose settings that vary by environment. section 8.4

A module is a collection of related resources, data sources, and supporting assets. The root module is the module Terraform starts from, not a particular location in a repository. When you run terraform init or terraform apply, the .tf files in the current working directory make up that root module. It may contain resources directly, call other modules, or do both. section 3.1 section 3.1.3

Keep the responsibilities of the entry point distinct from those of a reusable module:

  • Configure providers in the root module. A reusable module can declare required providers, but its provider configuration blocks must be removed when refactoring it for reuse. section 3.1.3 section 3.8.1
  • Accept values supplied by the person running a plan or apply at the root, then pass the needed values to child modules. section 8.4
  • Choose the root by how the configuration is called, not by its repository path. A reusable application module can itself serve as a root, or another root can call it. section 3.8.1 section 8.4

One root per environment

Create staging/main.tf and production/main.tf as separate entry points. Each can be a thin wrapper that calls the same application module while selecting its own module version and environment settings. This keeps deployments independent without requiring one shared root to handle every environment. section 8.4.2

Listing 8.10 Environment main.tf example
variable "logging_api_key" {                     #1
  sensitive = true                               #2
}
 
module "application" {                           #3
  source  = "registry.example.com/example/aws/application"
  version = "1.1.1"                              #4
 
  network_name = "dev_network"                   #5
  db_size      = 20                              #5
  num_tasks    = 5                               #5
 
  logging_api_key = var.logging_api_key          #6
}
 
output "application_url" {                       #7
  value = module.application.url
}

This environment root pins an application module version, supplies network and capacity settings, passes a sensitive logging key through a variable, and exposes the application URL as an output. Keep sensitive values out of settings committed to source control. section 8.4.2

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Defines the working-directory boundary and provider rule, then develops environment-specific wrappers; does not detail Terraform’s internal execution.
Examples
Uses a three-tier application assembled from component modules and an environment root calling a versioned application module.
What it assumes
Defines modules before distinguishing root, shared, and submodules, while using terraform init and terraform apply as the operative commands.
What you can do after
Operate/configure it by choosing a working-directory entry point, placing provider configuration there, and optionally creating independent environment roots.
How it connects
Connects provider configuration, input variables, outputs, reusable modules, Terraform workspaces, and deployment environments.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.