Open the first existing file from a list of candidate files

Hi terraform team, I’ve a pretty general question: how to locate/open the first existing file, from a list of candidate files?

Say, I’ve a list of yaml files, which each might exist or not, let say, they are A.yaml, B.yaml, C.yaml.

1, If A.yaml exists, then I’ll open that file, ignore B.yaml and C.yaml.
2, If A.yaml doesn’t exist, B.yaml exists, then I’ll open B.yaml, ignore C.yaml
3, If A.yaml and B.yaml don’t exist, but C.yaml does exist, then I’ll open C.yaml
4, when all files don’t exist, I’ll open a default file (or error out), this case will not be covered here.

How can I express the above logic in terraform codes? Thanks,

This is the code managed to get it work, but it is pretty odd/ugly, is there a friendly/concise alternative? Thanks,

fileexists("/tmp/file_A") ? file("/tmp/file_A") : (fileexists("/tmp/file_B") ? file("/tmp/file_B"): (fileexists("/tmp/file_C") ? file("/tmp/file_C") : "" ))

Hi @dcopperfield888,

Here’s another way to write it, though I’m not sure if you’ll consider this any less odd or ugly. :grinning:

locals {
  file_candidates = tolist([
    "file1.yaml",
    "file2.yaml",
    "file3.yaml",
  ])

  files_available = tolist([
    for fn in local.file_candidates : fn
    if fileexists("${path.module}/${fn}")
  ])

  chosen_file = "${path.module}/${local.files_available[0]}"
}

output "chosen_file" {
  value = local.chosen_file
}

The approach here is to first filter the list of files to contain only those that actually exist, and then to take the first item in that list as the chosen result.

This will fail with an error if none of the files exist, because local.files_available will end up being zero-length in that case. You could add some additional logic to handle that if needed, perhaps causing local.chosen_file to be null if local.files_available ends up having zero elements:

  chosen_file = (
    length(local.files_available) > 0 ?
    "${path.module}/${local.files_available[0]}" :
    null
  )

Even if it’s a lot less concise than the first example you shared, I think (subjectively) it’s easier to read it and understand what it’s doing, and that is what I tend to prioritize when I’m choosing between different designs in Terraform.

Thanks a lot, that’s exactly what I need.