Search code examples
ansiblegitlabjinja2gitlab-ciansible-template

Passing arrays or dictionary as extra parameter from gitlab to ansible


I am trying to pass a list or list of dictionary from gitlab to ansible. I am using gitlab anchors because in different jobs the list will have different values. This is the anchor I am using

  .generic_deploy: &generic_deploy 
    "sudo ansible-playbook -b my-ansible.yml --user $SSH_USR 
          -e deploymentEnvironment=${deploymentEnvironment} 
          -e domains=${domains}"

In my-ansible.yml there is a task for creating a template as below:

- name: Creating Gson from Template
  template:
    src: mytemplate.json.j2
    dest: /opt/mypath/my.json

and then in the mytemplate.json.j2 there is a structure like this:

    {
      "id": "/{{ deploymentEnvironment }}/myapp",
      "apps": [
      {% for domain in domains %}
        {
          "id": "{{ loop.index }}",
           "constraints": [
            [
              "zone",
              "CLUSTER",
              "GATEWAY_{{ loop.index }}_{{ loop.index }}"
            ]
          ]
       }
      {%- if not loop.last %},{% endif %}
      {% endfor %}
}

I have tested different ways to pass a list to Ansible, here is an example

deploy-featurebranch:
  variables:
    deploymentEnvironment: "devtest"
    domains: "['A1','A2','D1','D3','D5']"
  stage: deploy
  script:
    - *generic_deploy
  when: manual

I noticed that I am not allowed to have space inside the list like this "['A1', 'A2', 'D1', 'D3','D5']". If I am using space after comma then Ansible will give me bad argument error. If I am pssing this without space then I am getting an string as variable so the number of loop.index will be as many as string length. Any idea how this can be done?


Solution

  • I could resolve this by little working, putting the solution that worked for me here: gitlab-ci.yml file:

    .generic_deploy: &generic_deploy 
        "sudo ansible-playbook -b my-ansible.yml --user $SSH_USR 
              -e deploymentEnvironment=${deploymentEnvironment} 
              -e \"${domains}\"
    
    deploy-featurebranch:
      variables:
        deploymentEnvironment: "devtest"
        domains: "{'domains': [{'name':'A1','zone':'A'},{'name':'A2','zone':'A'},{'name':'D1','zone':'D'},{'name':'D3','zone':'D'},{'name':'D5','zone':'D'}]}"
      stage: deploy
      script:
        - *generic_deploy
      when: manual
    

    mytemplate.json.j2 file

    {
          "id": "/{{ deploymentEnvironment }}/myapp",
          "apps": [
          {% for domain in domains %}
            {
              "id": "{{ domain.name|lower }}",
               "constraints": [
                [
                  "zone",
                  "CLUSTER",
                  "{{ domain.zone }}"
                ]
              ]
           }
          {%- if not loop.last %},{% endif %}
          {% endfor %}
    }
    

    In my case json files were used for deployment to Marathon and the app id should be lowercase.