In this article, we will explain what module, root and CWD Terraform file paths are, and how you can reference the different types of file paths, along with some reference examples.
File paths in Terraform allow you to reference paths that include various files and modules within your configuration. These configuration files typically have a .tf
extension and contain the Terraform code necessary to describe and provision infrastructure resources.
The following types of path references (path.<TYPE>
) are available in Terraform:
path.root()
path.cwd()
path.module()
Root Module Path
The root module is the main directory where your Terraform configuration files (.tf
files) are located. The root module path is the absolute or relative path to the directory containing your main Terraform configuration. In most cases, the root module path is set to the directory where you run the terraform
command.
Current Working Directory (CWD)
The current working directory is the directory from which the Terraform command is executed. Note that it can be different from the root module path if you run Terraform commands from a subdirectory.
Module Paths
Modules are self-contained packages of Terraform configurations. The path to a module is the directory where the module’s Terraform files are located. Module paths can be specified as relative or absolute paths.
Path Module
Terraform provides a path
module that you can use to work with file paths within your Terraform code. The path
module includes functions path.cwd()
, path.root()
and path.module()
to retrieve the current working directory, root module path, and filesystem path of the module where the expression is placed respectively.
What is the difference between path root and path module?
path.root()
and path.module()
are functions provided by the path
module to retrieve information about file paths within your Terraform configuration. The key difference is that path.root()
always refers to the root module’s directory, while path.module()
dynamically reflects the directory containing the module’s configuration files. Using these functions can be helpful when you need to generate file paths dynamically or when dealing with modularized Terraform projects.
Adding the below output block to your configuration, if run within a module, it will output the path to that module’s directory when you execute terraform apply
.
output "module_path" {
value = path.module()
}
It is not recommend to use
path.module
in write operations because it can produce different behavior depending on whether you use remote or local module sources. Multiple invocations of local modules use the same source directory, overwriting the data inpath.module
during each call. This can lead to race conditions and unexpected results.
To further explain the value the path.module()
function will produce, consider the following file and directory structure:
my_terraform_project/
|-- main.tf
|-- variables.tf
|-- outputs.tf
|-- modules/
| |-- web_server/
| |-- main.tf
| |-- variables.tf
| |-- outputs.tf
The contents of the my_terraform_project/modules/web_server/outputs.tf file looks like this:
output "module_path" {
value = path.module()
}
When terraform apply
is run in the root directory, you’ll see output similar to the following:
Outputs:
module_path = /path/to/my_terraform_project/modules/web_server
If you run this in a file within a subdirectory of your Terraform project, it will output the path to the root directory when you execute terraform apply
.
output "root_path" {
value = path.root()
}
Consider the same file structure shown in the previous example. The output.tf file in the root directory (my_terraform_project/outputs.tf) includes the above code. The output would be similar to the below when terraform apply
is run.
Outputs:
root_module_path = /path/to/my_terraform_project
If you run this in a file within a subdirectory of your Terraform project, it will output the path to the current working directory before applying any -chdir
arguments when you execute terraform apply
.
It should be used with caution, e.g., if used to directly populate a path into a resource argument, then later applying the same configuration from a different directory or on a different computer with a different directory structure will cause the provider to consider the change of path to be a change to be applied, even if the path still refers to the same file.
output "cwd" {
value = path.cwd()
}
This path is an absolute path that includes details about the filesystem structure. It is also useful in some advanced cases where Terraform is run from a directory other than the root module directory. It is recommend to use
path.root
orpath.module
overpath.cwd
where possible.
Again, using the example file structure from the previous examples, consider the output.tf file in the root directory (my_terraform_project/outputs.tf) includes the above code. The output would be similar to the below when terraform apply
is run.
Outputs:
current_working_directory = /path/to/my_terraform_project
Terraform provides a path
module that you can use to work with file paths within your Terraform code. Choosing which function you use to reference paths should be understood carefully to avoid any unintended consequences when running your code on different systems with different directory structures.
We encourage you also to explore how Spacelift makes it easy to work with Terraform. If you need any help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box. You can check it for free, by creating a trial account or booking a demo.
Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.
Manage Terraform Better with Spacelift
Build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization, and many more.