Home > Enterprise >  Add multiple variables to an associative array
Add multiple variables to an associative array

Time:11-08

I am trying to environment variables to map to use elsewhere?

For example.

I have a script to get some variables which are predefined in the environment e.g.

$var1
$var2

aarray='{$var1, $var2}'

I need to use this map to add as a variable in another script. However this array, doesn't pick up the variables, is there a correct way to do this?

CodePudding user response:

First, this shouldn't be a terraform related question. If it indeed is, it is incomplete. What are you trying to do, why aren't you using a foo.tf file to declare all of your intents etc. Please rephrase the question and include more detail.

Second, terraform aside, the thing you want to achieve is called an associative array. Having it in the environment is not an easy task. It is preferred to have each variable in it's own environment variable. Look at this SO question for ideas some more experienced guys have proposed. If you'd, however, want to use this array in a script, you'd have to declare it explicitly (note the braces, quotes and lack of commas):

declare -A TF_VAR_amap=(["buildver"]="$buildversion" ["workingdir"]="$workingdir" ["date"]="$date"

To access them:

echo ${TF_VAR_amap["buildver"]}

Third, you are using single, instead of double quotes. Single quotes will preserve literal values of each character, including $. Use double quotes. From the bash manual:

Single Quotes

Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

Double Quotes

Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘`’, ‘\’, and, when history expansion is enabled, ‘!’. When the shell is in POSIX mode (see Bash POSIX Mode), the ‘!’ has no special meaning within double quotes, even when history expansion is enabled. The characters ‘$’ and ‘`’ retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: ‘$’, ‘`’, ‘"’, ‘\’, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ‘!’ appearing in double quotes is escaped using a backslash. The backslash preceding the ‘!’ is not removed.

CodePudding user response:

I have never tried, but it looks like there's a way to do that. See the complex-type values section in the Terraform docs. Particularly this sentence is promising:

if a root module variable uses a type constraint to require a complex value (list, set, map, object, or tuple), Terraform will instead attempt to parse its value using the same syntax used within variable definitions files, which requires careful attention to the string escaping rules in your shell:

So to take your specific values I'd try something like (not tested):

#!/bin/bash

date=...
workingdir=...
buildver=...

export TF_VAR_amap="{\"buildver\": \"$buildversion\", \"workingdir\": \"$workingdir\", \"date\": \"$date\"}'

terraform apply

As you can see the syntax quickly becomes a mess with regards to escaping. No wonder they advertise the .tfvars approach in the docs. So maybe you would be more successful using that - i.e. generate a .tfvars file in bash.

Also as a side note, be careful with using " vs. ' in bash. What you wrote:

export TF_VAR_amap='{ buildver = $buildversion ...}'

won't work as intended as ' in bash prevent the variables from being evaluated. The other answer explains that in details.

  •  Tags:  
  • bash
  • Related