0

Terraform give us the ability to a read a local file, which has a secret..

data "local_sensitive_file" "foo" {
  filename = "/tmp/foo"
}

But, what is the right way to handle a file that may not exist? In the above, if /tmp/foo doesn't exist, you get this error on compilation:

Error: Read local file data source error

with data.local_sensitive_file.foo,
on ssh.tf line 12, in data "local_sensitive_file" "foo":
12: data "local_sensitive_file" "foo" {

The file at given path cannot be read.

+Original Error: open /tmp/foo: no such file or directory

Seems as if setting the filename to null also doesn't work.

2 Answers 2

2

In this particular case where the path is well-known I would typically use the file function instead of the local_sensitive_file data source, since the data source is primarily intended for reading files that are generated dynamically while Terraform is running.

locals {
  filename = "${path.module}/whatever.txt"
  example  = fileexists(local.filename) ? sensitive(file(local.filename)) : null
}

However, if in your real configuration this is a file that comes from outside of your Terraform configuration or is generated dynamically by your configuration then you can get a similar effect by telling Terraform that there should be no instances of this data resource if the file doesn't exist:

locals {
  filename = "${path.module}/whatever.txt"
}

data "local_sensitive_file" "example" {
  count = fileexists(local.filename) ? 1 : 0

  filename = local.filename
}

locals {
  file_content = one(data.local_sensitive_file.example[*].content)
}

That last expression using one is a concise way to take either the one value of content or to produce null if there are no instances of this resource. Therefore local.file_content would be either the content of the file or null if there is no file.


Although I suspect this won't be a problem in your case due to this being temporary local files on disk rather than long-lived objects in a remote system, I suggest caution when trying to declare rules like "use this only if it exists". If applying this Terraform configuration could potentially change whether this file exists then you risk declaring something contradictory that will cause Terraform to exhibit unspecified behavior, because it'll make assumptions during the planning phase that won't necessarily hold during the apply phase.

In general I'd recommend instead being explicit about whether you expect the file to exist or not, so that Terraform can tell you immediately if your assumption is incorrect, rather than relying on your assumption and then acting strangely if it turns out not to be true.

For example, you can declare an input variable whose presence explicitly represents that the file ought to exist, but that can be omitted when it need not exist:

variable "filename" {
  type    = string
  default = null
}

data "local_sensitive_file" "example" {
  count = var.filename != null ? 1 : 0

  filename = var.filename
}

locals {
  file_content = one(data.local_sensitive_file.example[*].content)
}

This is essentially the same as my previous example except now the predicate for deciding whether to read the file is whether a filename was specified at all, and so Terraform can therefore give quick feedback if the caller of this module makes a typo when writing the filename, or otherwise assumes a file to exist that doesn't actually exist.

1

In Terraform, you can use the fileexists function to check if a file exists before attempting to use it. This function returns a boolean value indicating whether the specified file exists or not.

https://developer.hashicorp.com/terraform/language/functions/fileexists

in your case since you don't give to much logic behind what you want to do

filename = fileexists("/tmp/foo") ? "/tmp/foo" : "/tmp/whateverfile_you_want_if_foo_doesn't_exist"

filename will have /tmp/foo if file exists and /tmp/whateverfile_you_want_if_foo_doesn't_exis if file doesn't exists

6
  • Yes, but I don't want /tmp/whateverfile_you_want_if_foo_doesn't_exis I just want things to continue if the file doesn't exist. I don't have a fallback or default that I know does exist. Feb 14 at 21:07
  • @EvanCarroll what do you want to happen if the file doesn't exist? Feb 14 at 21:09
  • I'd like something like data.local_sensitive_file.foo.exists to be null or 0 or something. Feb 14 at 21:11
  • @EvanCarroll data.local_sensitive_file.foo.exists = fileexists("/tmp/foo") ? 1 : 0 then you should have something like the above Feb 14 at 21:14
  • 1
    @EvanCarroll I think there should be a couple of extra-steps using another variable, I don't have a Terraform on this machine to try Feb 14 at 21:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.