Terraform

Terraform File Paths – Path Module, Root and CWD

Terraform File Paths - Path Module, Root and Cwd

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.

  1. What are Terraform file paths
  2. Types of path references
  3. Path.module example
  4. Path.root example
  5. Path.cwd example

What are Terraform file paths?

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.

Types of path references

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.

Path.module example

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 in path.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

Path.root example

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

Path.cwd example

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 or path.module over path.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

Key points

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 will be 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 will expand on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6. OpenTofu retained all the features and functionalities that had made Terraform popular among developers while also introducing improvements and enhancements. OpenTofu works with your existing Terraform state file, so you won’t have any issues when you are migrating to it.

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.

Start free trial