Terraform -chdir folder isolation

Hello,

I have 2 folders with terraform sources firstfolder=/one and secondfolder=/two

I am wondering when i run the command terraform plan -chdir=<firstfolder> terraform is able to get files from the second folder ? (the second folder is not a subfolder of firstfolder)

The local_file datasource is relative to the current dir ? or it’s the full filesystem ?

Thanks

Hi @sylvainmouquet,

The best way to think about the -chdir option is that terraform plan -chdir=one is roughly the same as cd one && terraform plan (using Unix-style shell syntax), with only two special exceptions:

  • Terraform does its general CLI setup actions, like parsing the CLI configuration and deciding which directories to search for plugins, before switching directory. In a sense, you could say that the directory change applies only to the plan subcommand, not to the top-level terraform behavior, although that distinction isn’t important in most cases.
  • For historical reasons Terraform sets the symbol path.cwd to represent the original working directory where you ran Terraform rather than the directory you specified in -chdir, because some existing workflows relied on that and the -chdir directory is already available as path.root.

With that said, there isn’t really any isolation happening here, and so in principle you can write configurations that traverse out of their root module directory or access absolute paths on the host system, although of course you should do so with care to avoid your configuration becoming too coupled to the filesystem of the computer where you happen to be running Terraform today. But Terraform won’t block you from doing this, so it’s up to you to make the design tradeoffs for how your different configurations will interact with each other and with the execution environment you apply them in.

Since the local_file data source runs as part of terraform plan or terraform apply, it will indeed be subject to -chdir and so paths in it will be relative to that directory. However, it’s often helpful to be explicit about that intent to future readers of your module by writing a path that includes path.root, like this:

  filename = "${path.root}/example"

On modern Terraform path.root literally just expands to . to select the current working directory, but it’s helpful to be explicit because it’s also common to use path.module to select a path relative to the current module (if your configuration has multiple modules) and so a future reader might assume that’s what you meant without seeing this explicit path.root prompt that you intended something different.