Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plan files not portable when using path.module #7927

Closed
br0ch0n opened this issue Aug 3, 2016 · 18 comments
Closed

plan files not portable when using path.module #7927

br0ch0n opened this issue Aug 3, 2016 · 18 comments

Comments

@br0ch0n
Copy link
Contributor

br0ch0n commented Aug 3, 2016

It would seem that when using modules and/or "path.module" with saved plans, one ends up with hard-coded module paths inside the saved plan. Since in my case, the resources in question were templates, I had hoped that switching from 'filename' to 'template' would help, but it hasn't. Thus I'm unable to apply my saved plan on a different machine from where I generated it. (e.g. a different Jenkins slave)

Hopefully I'm just doing something wrong and/or there's a workaround.

Terraform Version

0.6.16 - 0.7.0

Affected Resource(s)

core

Terraform Configuration Files

#common module
data "template_file" "xenial-generic-user_data" {
  template = "${file("${path.module}/user_data/xenial-generic-config.yml.tpl")}"
  vars {
      }
}

output "xenial-generic-user_data" {
  value = "${data.template_file.xenial-generic-user_data.rendered}"
}
##############################################################
#main tf
module "common" {
  source = "git::ssh://someserver.com/common"
}
resource "aws_instance" "myserver" {
   user_data = "${module.common.xenial-generic-user_data}"
}

Expected Behavior

Terraform should have used local module paths

Actual Behavior

Terraform was looking for module paths that didn't exist so the apply of the saved plan failed

Steps to Reproduce

  • terraform plan -out saved.tfplan
  • copy saved.tfplan to different machine
  • do a terraform get on new machine
  • try to terraform apply saved.tfplan on new machine
${file("${path.module}/user_data/xenial-generic-config.yml.tpl")}
  * file: open /home/path/to/.terraform/modules/4037927f0801c4ca3190166488e205ed/user_data/xenial-generic-config.yml.tpl: no such file or directory in:

References

Likely related to below
#6459
#1439
#7613

@br0ch0n
Copy link
Contributor Author

br0ch0n commented Aug 3, 2016

@ringods
Copy link
Contributor

ringods commented Sep 14, 2016

@br0ch0n did you find a workaround? I just bumped into the same problem.

@br0ch0n
Copy link
Contributor Author

br0ch0n commented Sep 15, 2016

@ringods sadly not really. My current workaround is for my apply (jenkins) job to just ignore the saved plan and blindly apply :(

@c10l
Copy link

c10l commented Oct 21, 2016

On Concourse I had to make sure both plan and apply can find the code in the same absolute path by symlinking. It's easier than in Jenkins because it's all on disposable containers, but still quite smelly...

@dtx
Copy link

dtx commented Nov 16, 2016

This is true also for state files (not only plan files) when, for example, the resource is an archive_file with the source_dir set to something like ${path.module}/....

This renders remote state useless in a way because a resource in it now contains an attribute with an absolute path from another machine.

My current TF version: 0.7.10

@lopopolo
Copy link

This is also the case for ${path.root}

@xsellier
Copy link

xsellier commented Jan 6, 2017

Have you tried this:

#common module
data "template_file" "xenial-generic-user_data" {
  template = "${file("${path.module}/user_data/xenial-generic-config.yml.tpl")}"
  vars {
      }
}

output "xenial-generic-user_data" {
  value = "${data.template_file.xenial-generic-user_data.rendered}"
  depends_on = [ "data.template_file.xenial-generic-user_data" ]
}
##############################################################
#main tf
module "common" {
  source = "git::ssh://someserver.com/common"
}
resource "aws_instance" "myserver" {
   user_data = "${module.common.xenial-generic-user_data}"
}

@vamsee
Copy link

vamsee commented Jan 23, 2017

@xsellier what about files like .zip and other binary data?

@xsellier
Copy link

xsellier commented Feb 13, 2017

@vamsee sorry for the delay.

To archive you can use the archive file provider of terraform

@vamsee
Copy link

vamsee commented Feb 15, 2017

@xsellier thank you!

@discordianfish
Copy link

Is there a reason why nobody fixes this? Has anyone looked into a fix for that already?

@emmekappa
Copy link

Any news on this?

@apparentlymart
Copy link
Contributor

In the next major release we're going to be normalizing all of the configuration paths to be relative to the current working directory when Terraform is run, rather than absolute as they are today. I think that will take care of this issue "for free", but if not then it'll at least lay the groundwork to fix it more easily and we should be able to fix it shortly afterwards.

I've adjusted the labels on this to make sure we'll find it when we're testing the release, and we can see then if the behavior has improved already or if some more work will be required.

@emmekappa
Copy link

Meanwhile as a workaround I switched to archive file provider

@rafaelmagu
Copy link

@apparentlymart when do you expect the next major to land?

@ghost
Copy link

ghost commented Oct 4, 2018 via email

@teamterraform
Copy link
Contributor

Hi all,

From Terraform 0.12 onwards, path.module is now a relative path. We had initially hoped to make it a path relative to the root module (path.root), thus making paths portable between systems as long as the Terraform module filesystem layouts are consistent, but ultimately we were forced to compromise and make it relative to path.cwd to avoid breaking situations where users run Terraform with the current working directory set to something other than the root module.

Another related change in Terraform 0.12 is that Terraform's path variables always use / as the directory separator, even on Windows systems. Since Windows supports both (as long as we're consistent), standardizing on slashes is a convenient, lightweight way to resolve another situation where paths would end up non-portable, and also resolved some other issues relating to the portability of paths within the configuration itself.

While there can still be some rough edges if you are running a mode where path.cwd and path.root are not equal, that is not a usage pattern we recommend (it remains for compatibility until we devise a suitable migration plan for those already using it) and so anyone following the standard model of running Terraform directly within the root module directory should now find that paths in plan files and in state are portable as long as the relative paths of child modules remain constant.

A more substantial rework of how Terraform deals with the distinction between the root module directory and the current working directory is likely to follow later in a separate issue, but that's beyond the scope of what this issue was representing and so we're going to close this one out now. If you are still seeing inconsistencies between different machines on the same configuration and you are following the recommendation to have path.cwd and path.root match, please open a new issue with all of the details requested in the issue template so we can understand your specific situation. Thanks!

@ghost
Copy link

ghost commented Aug 17, 2019

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Aug 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests