Setting object/rich type parameter in automation frameworks

Hello,
we use jenkins with terraform and so far passed parameters to terraform using TF_VAR env vars. I would like to use object parameter if possible but I haven’t found a reasonable way to this other than moving from env vars to parameter files.

I am wondering what other people. Would be nice to see an example

thanks and happy holidays

I often use map type variables in my autovars files, especially for environment-specific parameters like vpc cidrs, and then have a simple variable for selecting the environment ie “test” or “dev”. Maybe that can be used here.

Having said that, the documentation for input variables have examples of injecting maps and lists on the commandline. So that should work. I guess the usage of single-quotes is important to avoid the bash interpreter messing with the construct.

1 Like

Hi @pmoosh,

If you have a variable whose type is set to a complex type constraint, such as an object(...) constraint, then Terraform will expect a TF_VAR_... environment value for that one to use Terraform expression syntax to provide the value.

For example, consider the following variable declaration:

variable "example" {
  type = object({
    env_name = string
  })
}

If we were setting that environment variable using bash, for example, we might set it like this:

export TF_VAR_example='{"env_name":"production"}'

Terraform decides how to process the environment variable value based on the type constraint, so it’s important to set appropriate type constraints when you’ll be assigning values using environment variables like this. There’s more detail on how this works in the Input Variables documentation.

In particular, note the warning there about shell escaping. In the example above I used ' quotes to make sure the " quotes inside the string were interpreted literally by bash.

Since you are using Jenkins I expect it’s Jenkins escaping you’ll need to contend with, rather than shell escaping, but my Jenkins knowledge is very outdated (I last used it before Jenkinsfile); from some quick skimming of the syntax documentation I guess the equivalent might be to use ''' quoting:

  environment {
    TF_VAR_example = '''{"env_name":"production"}'''
  }
1 Like

I realized that one of the issues I am facing is the merge behavior of objects and maps with terraform. Simple parameter behave differently, as in if they are not set the default if defined will be used. For objects I have to set all the values otherwise terraform will fail. Maps only the set values are relevant.

On a side note I was hoping for something that I am able to do in helm:

helm --set ingress.hosts[0]=…

For now I am thinking of doing something like:

export TF_VAR_tags=’{“tmpdir”:"’${TMP}’"}’
where TMP is set by the jenkins job and TF_VAR_tags by the wrapper script

thanks

Peter