Hi @mmauney,
Unfortunately you have left out the most important part of the error message which explains what actually failed when running the function, but I’m guessing it was an error saying that var.app_version
is not suitable for interpolation because it isn’t a string.
The important thing to remember with a configuration like this is that you are using a template to generate a bash script, not to run a bash script. Therefore you need to think about how to tell Terraform which shell commands to generate so that when Bash does eventually run the script it will run the commands you intend; Bash itself won’t have access to the template variables at runtime.
One approach then would be to use Terraform’s template syntax to generate one command for each element of the array:
%{ for v in my_array ~}
echo "${v}"
%{ endfor ~}
With the default variable value you showed, this would generate a bash script like this:
echo "1.5.8"
echo "8.0"
echo "1.0"
echo "1.0"
echo "6.0"
(By the way: the variable you’ve declared is a map rather than a list or array, so it’s a bit confusing to name the variable my_array
but I preserved the name from your question just so you could try it with the rest of your code as you already wrote it.)
Another approach would be to try to get Terraform to generate the syntax that Bash expects for declaring a bash array, which you could then use with the Bash for
command. The Bash array syntax is a bit awkward to generate totally robustly with Terraform, but I think something like this will work as your template:
declare -ra my_bash_array=(${
join(" ", [
for s in my_array : "'${replace(s, "'", "'\\''")}'"
])
})
for s in "$${my_bash_array[@]}"; do
echo "$${s}"
done
This one is more complicated so I’ll try to explain it in smaller parts:
-
replace(s, "'", "'\\''")
is trying to deal with the possibility that a string might contain a literal '
character, which Bash expects us to mark with an escape character. This interpolation sequence is already in ''
quotes, so if s
was "that's"
then that item would be rendered as 'that'\''s'
in the bash script, so that Bash can parse it correctly to recover the original string.
- The
[ for s in my_array : ...]
expression is generating a new list based on your given list, by applying the same transformation (as described in the previous point) to each item.
-
join(" ", ...)
takes an array of strings and transforms it into a single string with all of the items separated by a single space each.
- Everything discussed so far is in a
${ ... }
sequence so that Terraform will include it after the equals sign of a bash array declaration, to generate a list of elements for the Bash array.
- In the bash
for
command that follows, we can refer to my_bash_array
to get elements from the bash version of the array. However, in both $${my_bash_array[@]}
and $${s}
the extra $
on the front is there to tell Terraform to produce a literal ${
sequence for Bash to parse, rather than understanding the following as a Terraform template interpolation.
With all of that said then, the result of rendering this template should be something like the following:
declare -ra my_bash_array=('1.5.8' '8.0' '1.0' '1.0' '6.0')
for s in "${my_bash_array[@]}"; do
echo "${s}"
done
I don’t know if I got that Bash syntax exactly right, since I don’t routinely write complex Bash scripts like this, but hopefully if I didn’t get it right you can see the general idea and adjust it as needed.