Ansible Array Variables

48 Views Asked by At

I have a problem using an array in ansible

My hosts_vars:

ivr:
  - id: 1
    name: "General"
    announcement: "General-ES"
    dests:
      - option: "t"
        id_dest: 10000
        type: "Queue"

      - option: "i"
        id_dest: 10000
        type: "Queue"

and my task:

- name: Creamos el ivr si no existe
  uri:
    url: "http://{{ ansible_host }}:{{ api_port }}/ivr/create"
    method: POST
    headers:
      Content-Type: "application/json"
      Authorization: "Bearer {{ result_post_token.json.token }}"
    return_content: yes
    body_format: json
    body: '{
      "name": "{{ item.name }}",
      "announcement" : "{{ item.announcement }}",
      "dests" : {
        "{{ item.dests.option }}":{
            "type": "{{ item.dests.type }}",
            "id": "{{ item.dests.id }}"
        },
      },
    }'
    status_code: 201
    timeout: 30

When I run the playbook it returns an error saying that item.dests.option does not exist.

This is a test example, finally the amount of dests can vary, that's why I need to use something that assembles the body with all the dests

Can someone help me correctly define my variables and be able to assemble the body using loop or something similar.

probe defines the variables like this:

ivr:
  - id: 1
    name: "General"
    advertisement: "General-ES"
    Destinations:
      option: "t"
      dest_id: 10000
      type: "queue"
      option: "i"
      dest_id: 10000
      type: "queue"

but it only showed me the last option

1

There are 1 best solutions below

2
Alexander Pletnev On

When I run the playbook it returns an error saying that item.dests.option does not exist.

This is expected (if only your task is not running in a loop already) - your current example does not contain a definition of item variable.

At the same time, item is the default name of the loop variable. To iterate over your ivr list, you need to add the loop keyword to your task.

But this also won't work because item.dests is a list and you're trying to access item.dests.option as if item.dests was a hash.

To make it work, you need to loop this task first setting a different loop variable, and then iterate over the dests list inside that task:

# playbook.yaml
---
- hosts: localhost
  connection: local
  gather_facts: false
  vars:
    ivr:
      - id: 1
        name: "General"
        announcement: "General-ES"
        dests:
          - option: "t"
            id_dest: 10000
            type: "Queue"

          - option: "i"
            id_dest: 10000
            type: "Queue"
  tasks:
    - name: Iterate over the `ivr` variable
      include_tasks: tasks/task.yaml
      loop: "{{ ivr }}"
      loop_control:
        loop_var: ivr_item
# tasks/task.yaml
---
- name: Creamos el ivr si no existe
  uri:
    url: "http://{{ ansible_host }}:{{ api_port }}/ivr/create"
    method: POST
    headers:
      Content-Type: "application/json"
      Authorization: "Bearer {{ result_post_token.json.token }}"
    return_content: yes
    body_format: json
    body: '{
      "name": "{{ ivr_item.name }}",
      "announcement": "{{ ivr_item.announcement }}",
      "dests": {
        "{{ item.dests.option }}": {
          "type": "{{ item.dests.type }}",
          "id": "{{ item.dests.id }}"
        },
      },
    }'
    status_code: 201
    timeout: 30
  loop: "{{ ivr_item.dests }}"

Note the different item and ivr_item variables. I would also recommend to always set a specific loop variable name so that your tasks will behave the same after a possible refactoring and adding to other nested loops.

probe defines the variables like this:

This example is invalid as the Destinations hash contains duplicate keys.