How to Use terraform path.root to Determine the Root Module Directory
The path.root pseudo-variable returns the absolute filesystem path to the directory containing your Terraform root module, regardless of where the terraform command was invoked.
Terraform exposes filesystem information through the path object, making the terraform path.root pseudo-variable available within HCL expressions. This variable identifies the absolute directory containing your root module's configuration files, ensuring consistent file references even when users invoke Terraform from different working directories or use the -chdir flag. The value is computed during the evaluation phase by the Terraform core engine and injected into the HCL evaluation context.
What is terraform path.root?
path.root is a pseudo-variable—not a resource or data source—that belongs to the path object available in all Terraform configurations. It returns the absolute filesystem path to the directory containing the root module, which is the top-level directory where Terraform begins evaluating your configuration.
Unlike relative paths or hard-coded strings, terraform path.root remains stable across different execution contexts. Whether a user runs terraform apply from the project root, a subdirectory, or uses the -chdir command-line flag, path.root consistently points to the directory containing the root *.tf files.
How terraform path.root Works Internally
The implementation of path.root resides in the Terraform core evaluation engine. In internal/terraform/evaluate_data.go, the GetPathAttr method handles attribute access for the path pseudo-variable. When the evaluation encounters the "root" case, it retrieves the source directory from the evaluator's configuration and converts it to a slash-separated absolute path:
case "root":
sourceDir := d.Evaluator.Config.Module.SourceDir
return cty.StringVal(filepath.ToSlash(sourceDir)), diags
This value is then injected into the HCL evaluation context in internal/lang/eval.go (lines 147-151), where it becomes available as path.root within your configuration expressions:
vals["path"] = cty.ObjectVal(pathAttrs)
The internal/addrs/path_attr.go file defines the PathAttr address type used to identify these pseudo-variable attributes, while tests in internal/lang/eval_test.go and internal/command/e2etest/primary_test.go validate that path.root behaves correctly across different working directories and CLI invocation patterns.
terraform path.root vs. path.cwd and path.module
Terraform provides three distinct path attributes within the path object. Understanding their differences ensures you select the correct variable for your use case:
-
path.root– Returns the absolute path to the root module directory. This value remains constant regardless of the process working directory or-chdirusage. Use this when you need to reference files relative to the project root. -
path.cwd– Returns the current working directory of the Terraform process (obtained viaos.Getwd()). This changes when users invoke Terraform from different directories or use the-chdirflag. Avoid this for file references within your configuration. -
path.module– Returns the directory of the current module where the expression is evaluated. In the root module, this equalspath.root, but in child modules, it points to the child module's directory. Use this when referencing files within a specific module's package.
Practical Examples for Using terraform path.root
Referencing Files Relative to the Project Root
Use path.root to construct absolute paths to files that reside in your repository, ensuring they resolve correctly regardless of execution context:
resource "local_file" "readme" {
filename = "${path.root}/outputs/README.md"
content = "# Deployment Information\n\nGenerated at ${timestamp()}"
}
Debugging Path Resolution
Output both path.root and path.cwd to verify how Terraform resolves paths in your environment:
output "path_debug" {
value = {
root_directory = path.root
cwd_directory = path.cwd
}
description = "Compare root module location vs. execution directory"
}
Conditional Logic Based on Root Directory
Implement repository-wide feature flags by checking for files in the root directory:
locals {
use_legacy_config = fileexists("${path.root}/.legacy-mode")
config_path = local.use_legacy_config ? "${path.root}/legacy" : "${path.root}/modern"
}
Accessing Root Module Files from Child Modules
When designing reusable child modules, accept the root path as a variable rather than hard-coding relative paths:
# In child module
variable "root_dir" {
type = string
}
locals {
policy_file = "${var.root_dir}/policies/default.json"
}
Then invoke with root_dir = path.root from the root module.
Summary
terraform path.rootprovides the absolute filesystem path to the directory containing your root module configuration files.- The value is computed in
internal/terraform/evaluate_data.goby theGetPathAttrmethod, which retrievesEvaluator.Config.Module.SourceDirand normalizes it to slash-separated paths. - Unlike
path.cwd,path.rootremains stable across different working directories and-chdirCLI usage, making it the reliable choice for file path construction. - Use
path.rootwhen referencing files relative to your project root, implementing repository-wide configuration flags, or passing root directory information to child modules.
Frequently Asked Questions
What is the difference between terraform path.root and path.cwd?
path.root returns the absolute path to the directory containing your root module (where the top-level *.tf files reside), while path.cwd returns the current working directory of the Terraform process. When you use the -chdir flag or run Terraform from a subdirectory, path.cwd changes but path.root remains constant, pointing to the actual configuration root.
Can I use path.root inside a child module?
Yes, path.root is available in all contexts including child modules, but it always refers to the root module's directory, not the child module's location. If you need the child module's directory, use path.module instead. When designing reusable modules, consider passing path.root as an input variable if the module needs to access files from the project root.
Does path.root return a relative or absolute path?
path.root always returns an absolute path with forward slashes as directory separators, regardless of the host operating system. The Terraform source code explicitly converts the source directory using filepath.ToSlash() before returning it as a string value, ensuring consistent path formatting across Windows, Linux, and macOS environments.
Is path.root available in all Terraform versions?
The path pseudo-variable object, including path.root, has been available since early Terraform versions (0.9+). The specific implementation details in internal/terraform/evaluate_data.go and internal/lang/eval.go represent the modern architecture, but the user-facing behavior of path.root has remained consistent across recent major versions, making it safe to use in production configurations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →