terraform

Map in tfvars in a module


I'm writing a terraform module that will select a value from a map, based on a key passed to it. Nothing unusual.

The values in that map are secret however, and do not change based on who is calling the module. A simple way I thought to keep those secrets secret would be to define the variable as a map in variables.tf in the module, put the keys/values in terraform.tfvars in the module, .gitignore terraform.tfvars, and encrypt it to terraform.tfvars.gpg or something.

But that doesn't work, because I have no default for the variable in the module terraform is expecting the variable to be set by the caller. I can define the variable in the caller without a value, add it to the call, and either specify manually --var-file or include a terraform.tfvars in the caller. But that means the user having to remember a magic --var-file invocation or the duplication of terraform.tfvars everywhere my new module is used. Remembering magic strings and duplication are both not good options.

Is it possible for a module to use its own tfvars to fill in variables not passed to it?


Solution

  • There is no way to use an automatic .tfvars file with a non-root module. Child modules always get all of their values from the calling module block (with default values inserted where appropriate); .tfvars is only for assigning values to root module variables.

    Another option with similar characteristics to what you're describing is to use a data file in either JSON or YAML format inside the module directory, and load it in using the file function and one of the decoding functions. For example:

    locals {
      # This file must be created before using this module by
      # decrypting secrets.yaml.gpg in this directory.
      secrets = yamldecode(file("${path.module}/secrets.yaml"))
    }
    

    If the caller neglects to decrypt into the .gitignored file before using the module then the file call will fail with a "file not found" error message.