Terraform: file function does not work for future generated files

Created on 8 Nov 2016  ยท  3Comments  ยท  Source: hashicorp/terraform

I am trying to use file function in "aws_key_pair" for public key.
I am creating public key file using null resource with local-exec and added dependency of null resource in aws_key_pair.
But terraform apply is failing because file is not present at that time.

Regards,
Ganesh

Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

Run terraform -v to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed.

Affected Resource(s)

Please list the resources as a list, for example:

  • aws_instance
  • dnsimple_record

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key.

Debug Output

Please provider a link to a GitHub Gist containing the complete debug output: https://www.terraform.io/docs/internals/debugging.html. Please do NOT paste the debug output in the issue; just paste a link to the Gist.

Panic Output

If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the crash.log.

Expected Behavior

What should have happened?

Actual Behavior

What actually happened?

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

Important Factoids

Are there anything atypical about your accounts that we should know? For example: Running in EC2 Classic? Custom version of OpenStack? Tight ACLs?

References

Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example:

  • GH-1234
question

Most helpful comment

Hi @gkhakare,

As you've noticed, The file function in the interpolation language gets dealt with very early on in the Terraform lifecycle, during configuration parsing. This is intended to give Terraform the best opportunity to validate the configuration, since Terraform's goal is to find as many errors as possible before running the apply step.

There are no plans right now to support "lazy" evaluation of the file function, because the interpolation language is not currently capable of representing such a thing. However, there is an alternative approach that would work today, with some caveats:

The tls_private_key resource can generate a private key directly within Terraform itself. In spite of the name, it's also capable of generating RSA and ECDSA SSH keys:

resource "tls_private_key" "example" {
    algorithm = "RSA"
    rsa_bits = 4096
}

This resource exposes the following two attributes that are interesting for your use-case here:

  • private_key_pem - The private key data in PEM format. If you copy this data into a file then you can use it as an identity document (-i argument) to OpenSSH.
  • public_key_openssh - The public key data in OpenSSH authorized_keys format. You can interpolate this into the public_key attribute on the aws_key_pair resource to produce a keypair object that you can use for your EC2 instances.

The caveat here is that the generated private key will end up in your Terraform state file, so you need to make sure that this state file is stored securely.

I've also been working on #8768, which is intended to be a more robust replacement of the pattern of using a remote-exec provisioner to write a local file to disk and read it back elsewhere in the configuration. Were this to be merged, in your case you could write an external wrapper script that runs ssh-keygen, writing the private and public key files to disk, and then reads back in the public key file to use elsewhere in the Terraform configuration. It's not in yet, but hopefully it will be soon.

All 3 comments

Hi @gkhakare,

As you've noticed, The file function in the interpolation language gets dealt with very early on in the Terraform lifecycle, during configuration parsing. This is intended to give Terraform the best opportunity to validate the configuration, since Terraform's goal is to find as many errors as possible before running the apply step.

There are no plans right now to support "lazy" evaluation of the file function, because the interpolation language is not currently capable of representing such a thing. However, there is an alternative approach that would work today, with some caveats:

The tls_private_key resource can generate a private key directly within Terraform itself. In spite of the name, it's also capable of generating RSA and ECDSA SSH keys:

resource "tls_private_key" "example" {
    algorithm = "RSA"
    rsa_bits = 4096
}

This resource exposes the following two attributes that are interesting for your use-case here:

  • private_key_pem - The private key data in PEM format. If you copy this data into a file then you can use it as an identity document (-i argument) to OpenSSH.
  • public_key_openssh - The public key data in OpenSSH authorized_keys format. You can interpolate this into the public_key attribute on the aws_key_pair resource to produce a keypair object that you can use for your EC2 instances.

The caveat here is that the generated private key will end up in your Terraform state file, so you need to make sure that this state file is stored securely.

I've also been working on #8768, which is intended to be a more robust replacement of the pattern of using a remote-exec provisioner to write a local file to disk and read it back elsewhere in the configuration. Were this to be merged, in your case you could write an external wrapper script that runs ssh-keygen, writing the private and public key files to disk, and then reads back in the public key file to use elsewhere in the Terraform configuration. It's not in yet, but hopefully it will be soon.

Thank you @apparentlymart for the detailed explanation.
It worked very well for me.

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.

Was this page helpful?
0 / 5 - 0 ratings