Home > other >  iteration and count variable in ansible
iteration and count variable in ansible

Time:01-21

I am trying to simplify the code

    - name: Report status
      ansible.builtin.debug:
        msg:
          - "{{ agents.results.0.services.0.display_name }} is {{ agents.results.0.services.0.state }}"
          - "{{ agents.results.1.services.0.display_name }} is {{ agents.results.1.services.0.state }}"
          - "{{ agents.results.2.services.0.display_name }} is {{ agents.results.2.services.0.state }}"
          - "{{ agents.results.3.services.0.display_name }} is {{ agents.results.3.services.0.state }}"
          - "{{ agents.results.4.services.0.display_name }} is {{ agents.results.4.services.0.state }}"
          - "{{ agents.results.5.services.0.display_name }} is {{ agents.results.5.services.0.state }}"
          - "{{ agents.results.6.services.0.display_name }} is {{ agents.results.6.services.0.state }}"

I need to get the name and service state for each item.

I have tried with_sequence but this leads to an error:

{"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'item'
    - ansible.builtin.debug:
        msg: 
          - "{{ agents.results.item.services.0.display_name }} is {{ agents.results.item.services.0.state }}"
      with_sequence: end=6

A per suggestion I tried

    - ansible.builtin.debug:
        msg:
          - "{{ agents.results[item].services.0.display_name }} is {{ agents.results[item].services.0.state }}"
      with_sequence: end=6

which leads to an error: "msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute '1'

Also, tried:

    - ansible.builtin.debug:
        msg: "{{ item.services.0.display_name }} is {{ item.services.0.state }}"
      loop: "{{ agents.results }}"

which provides more information than required, e.g.

ok: [100.71.76.4] => (item={'changed': False, 'invocation': {'module_args': {'name': 'CSFalconService'}}, 'exists': True, 'services': [{'checkpoint': 0, 'controls_accepted': ['stop', 'pre_shutdown'], 'dependencies': [], 'dependency_of': [], 'description': 'Helps protect the system from malicious activities', 'desktop_interact': False, 'display_name': 'CrowdStrike Falcon Sensor Service', 'error_control': 'normal', 'failure_actions': [{'type': 'restart', 'delay_ms': 60000}, {'type': 'restart', 'delay_ms': 60000}, {'type': 'restart', 'delay_ms': 60000}], 'failure_actions_on_non_crash_failure': False, 'failure_command': None, 'failure_reboot_msg': None, 'failure_reset_period_sec': 86400, 'launch_protection': 'antimalware_light', 'load_order_group': '', 'name': 'CSFalconService', 'path': '"C:\\Program Files\\CrowdStrike\\CSFalconService.exe"', 'pre_shutdown_timeout_ms': 180000, 'preferred_node': None, 'process_id': 7164, 'required_privileges': [], 'service_exit_code': 0, 'service_flags': [], 'service_type': 'win32_own_process', 'sid_info': 'none', 'start_mode': 'auto', 'state': 'started', 'triggers': [], 'username': 'NT AUTHORITY\\SYSTEM', 'wait_hint_ms': 0, 'win32_exit_code': 0}], 'failed': False, 'item': 'CSFalconService', 'ansible_loop_var': 'item'}) => {
    "msg": "CrowdStrike Falcon Sensor Service is started"
}


ok: [100.71.76.4] => (item={'changed': False, 'invocation': {'module_args': {'name': 'Tanium Client'}}, 'exists': True, 'services': [{'checkpoint': 0, 'controls_accepted': ['stop'], 'dependencies': [], 'dependency_of': [], 'description': 'Tanium Client', 'desktop_interact': False, 'display_name': 'Tanium Client', 'error_control': 'normal', 'failure_actions': [{'type': 'restart', 'delay_ms': 60000}, {'type': 'restart', 'delay_ms': 60000}, {'type': 'none', 'delay_ms': 0}], 'failure_actions_on_non_crash_failure': False, 'failure_command': None, 'failure_reboot_msg': None, 'failure_reset_period_sec': 86400, 'launch_protection': 'none', 'load_order_group': '', 'name': 'Tanium Client', 'path': '"C:\\Program Files (x86)\\Tanium\\Tanium Client\\TaniumClient.exe" --service', 'pre_shutdown_timeout_ms': 10000, 'preferred_node': None, 'process_id': 5324, 'required_privileges': [], 'service_exit_code': 0, 'service_flags': [], 'service_type': 'win32_own_process', 'sid_info': 'none', 'start_mode': 'auto', 'state': 'started', 'triggers': [], 'username': 'NT AUTHORITY\\SYSTEM', 'wait_hint_ms': 0, 'win32_exit_code': 0}], 'failed': False, 'item': 'Tanium Client', 'ansible_loop_var': 'item'}) => {
    "msg": "Tanium Client is started"
}

Actually, I need only the msg part.

CodePudding user response:

First, you should read the dedicated article in ansible FAQ. So the direct answer to your above question is:

"{{ agents.results[item | int].services.0.display_name }} is {{ agents.results[item].services.0.state }}"

Note the int filter to cast the variable as with_sequence actually produces strings.


But next, why do you make things so complicated? Just loop on the results:

- ansible.builtin.debug:
    msg: "{{ item.services.0.display_name }} is {{ item.services.0.state }}"
  loop: "{{ agents.results }}"

If each individual item is large and you want to reduce the amount of information which is displayed by Ansible on each loop iteration, see loop control - limiting loop output

CodePudding user response:

Regarding

... which provides more information than required ... actually, I need only the msg part.

you may have a look into Limiting loop output with label

When looping over complex data structures, the console output of your task can be enormous. To limit the displayed output, use the label directive with loop_control.

and use something like

  loop_control:
    label: "{{ item.name }}" # or item.item

for your loop and in order to reduce the header.

  • Related