I am writing a CI/CD pipeline for terraform to deploy GCP resources. In terraform code, I got many functionality and Network is one of them. The folder structure of the Network is
Network
VPC
LoadBalancer
DNS
VPN
So, I want to loop terraform init, plan and apply commands for all the sub-folder of Network folder. The yml file looks like
image:
name: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
variables:
TF_ROOT: ${CI_PROJECT_DIR}
env: 'prod'
network_services: ""
stages:
- init
init:
stage: init
script:
- |
network_services = ['vpc' 'vpn']
for service in $network_services[@]
do
echo The path is var/$env/terraform.tfvars
done
The above gives me the error:
$ network_services = ['vpc' 'vpn'] # collapsed multi-line command
/bin/sh: eval: line 103: network_services: not found
Please suggest a way to declare array variable in gitlab CI/CD yml.
Arrays are a feature of the Bash shell, but the image you’re using (registry.gitlab.com/gitlab-org/terraform-images/stable:latest
) does not carry it installed. It (/bin/sh
) is using a much older standard shell, likely ash
to execute the passed script.
You can use a custom, derived image with bash installed to make use of Bash specific syntax, or you can use an alternative way of iterating over values.
Since you mention a directory structure and if that exists within the container, you can perhaps use the following script syntax to list (ls
) the directory and iterate on the list results:
for SERVICE in $(ls -d var/${env}/*)
do
echo "The path is ${SERVICE}/terraform.tfvars"
done
Or use a more portable/simpler way of iterating over words in a whitespace separated string in the shell:
SERVICES="VPN VPC LB DNS"
for SERVICE in ${SERVICES}
do
echo "The path is var/$env/${SERVICE}/terraform.tfvars"
done
If you decide and implement a way to use Bash instead, follow the guide on Arrays in Bash to use the right declaration and substitution syntax. In particular, the declaration syntax must not carry any whitespace around =
, as Bash is sensitive to whitespaces, and the arrays must be declared within ()
parentheses, not []
:
network_services=('vpc' 'vpn')
1 Like
Thanks @hchouraria, it worked.