Search code examples
ansiblejinja2ansible-template

ansible Jinja template loop


I'm attempting to loop through a registered variable in a Jinja template via an Ansible playbook. Here is my task:

- name: Check if ports are open | inventory ports
  wait_for:
    host: "{{ item.name }}"
    port: "{{ item.port }}"
    state: started
    delay: 0
    timeout: 5
  ignore_errors: true
  loop: "{{ server_facts.server_port|default (server_port) }}"
  register: server_port_check

Then here is the output:

"server_port_check.results": [
        {
            "state": "started",
            "port": 636,
            "search_regex": null,
            "match_groups": [],
            "match_groupdict": {},
            "path": null,
            "elapsed": 0,
            "invocation": {
                "module_args": {
                    "host": "dc.domain.com",
                    "port": 636,
                    "state": "started",
                    "delay": 0,
                    "timeout": 5,
                    "connect_timeout": 5,
                    "active_connection_states": [
                        "ESTABLISHED",
                        "FIN_WAIT1",
                        "FIN_WAIT2",
                        "SYN_RECV",
                        "SYN_SENT",
                        "TIME_WAIT"
                    ],
                    "sleep": 1,
                    "path": null,
                    "search_regex": null,
                    "exclude_hosts": null,
                    "msg": null
                }
            },
            "failed": false,
            "changed": false,
            "item": {
                "name": "dc.domain.com",
                "port": 636
            },
            "ansible_loop_var": "item"
        },
        {
            "state": "started",
            "port": 4505,
            "search_regex": null,
            "match_groups": [],
            "match_groupdict": {},
            "path": null,
            "elapsed": 0,
            "invocation": {
                "module_args": {
                    "host": "server01",
                    "port": 4505,
                    "state": "started",
                    "delay": 0,
                    "timeout": 5,
                    "connect_timeout": 5,
                    "active_connection_states": [
                        "ESTABLISHED",
                        "FIN_WAIT1",
                        "FIN_WAIT2",
                        "SYN_RECV",
                        "SYN_SENT",
                        "TIME_WAIT"
                    ],
                    "sleep": 1,
                    "path": null,
                    "search_regex": null,
                    "exclude_hosts": null,
                    "msg": null
                }
            },
            "failed": false,
            "changed": false,
            "item": {
                "name": "server01",
                "port": 4505
            },
            "ansible_loop_var": "item"
        }
    ],
    "_ansible_verbose_always": true,
    "_ansible_no_log": false,
    "changed": false
}

When I'm able to grab what I want with the following task:

- name: debugging
  debug:
    msg: 
      - "{{ server_port_check.results.0.item.name }}"
      - "{{ server_port_check.results.0.port }}"
      - "{{ server_port_check.results.0.state }}"

How do I loop over this in a template. I've been doing the following (or different variations):

{% for results in server_port_check.results %}
Host:   {{ item.name }}
Port:   {{ port }}
Status: {{ state }}
{% endfor %}

The playbook fails with

The task includes an option with an undefined variable


Solution

  • The item of your for loop, is the .0 of your debug task.

    So:

    {% for result in server_port_check.results %}
    Host:   {{ result.item.name }}
    Port:   {{ result.port }}
    Status: {{ result.state }}
    {% endfor %}