Array variable in gitlab CI/CD yml

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, let me try this.

Thanks @hchouraria, it worked.