Register Variables in Loop in an Ansible Playbook

Register Variables in Loop in an Ansible Playbook

Is this what you're looking for:

- hosts: localhost
tags: s21
gather_facts: no
vars:
images:
- foo
- bar
tasks:
- shell: "echo result-{{item}}"
register: "r"
with_items: "{{images}}"

- debug: var=r

- debug: msg="item.item={{item.item}}, item.stdout={{item.stdout}}, item.changed={{item.changed}}"
with_items: "{{r.results}}"

- debug: msg="Gets printed only if this item changed - {{item}}"
when: "{{item.changed == true}}"
with_items: "{{r.results}}"

Source: Register variables in with_items loop in Ansible playbook

Register variables in with_items loop in Ansible playbook

So how can I properly save the results of the operations in variable names based on the list I iterate over?

You don't need to. Variables registered for a task that has with_items have different format, they contain results for all items.

- hosts: localhost
gather_facts: no
vars:
images:
- foo
- bar
tasks:
- shell: "echo result-{{item}}"
register: "r"
with_items: "{{ images }}"

- debug: var=r

- debug: msg="item.item={{item.item}}, item.stdout={{item.stdout}}, item.changed={{item.changed}}"
with_items: "{{r.results}}"

- debug: msg="Gets printed only if this item changed - {{item}}"
when: item.changed == true
with_items: "{{r.results}}"

Ansible loop with multiple register value

I understand your use case that you like to append one list to an other or to merge two lists.

To do so you could use an approach like

---
- hosts: localhost
become: false
gather_facts: false

vars:

LIST_1:
- 1
- 2
- 3

LIST_2:
- A
- B
- C

tasks:

- name: Info
debug:
msg: "{{ item }}"
loop: "{{ LIST_1 + LIST_2 }}"
loop_control:
extended: true
label: "{{ansible_loop.index0 }}"

resulting into an output of

TASK [Info] ******************
ok: [localhost] => (item=0) =>
msg: 1
ok: [localhost] => (item=1) =>
msg: 2
ok: [localhost] => (item=2) =>
msg: 3
ok: [localhost] => (item=3) =>
msg: A
ok: [localhost] => (item=4) =>
msg: B
ok: [localhost] => (item=5) =>
msg: C

Credits to

  • Append list variable to another list in Ansible

Further Q&A

  • Combine two lists in Ansible when one list could be empty
  • Ansible: Merge two lists based on an attribute

Ansible : Loop over two register variables using with_items

Do this:

- name: Get cksum some of files copied locally
stat:
path : "{{ item.src }}/{{ item.file }}"
delegate_to: localhost
with_items: "{{ files }}"
register: local_files

- name: Get cksum of remote files
stat:
path : "{{ item.dest }}/{{ item.file }}"
with_items: "{{ files }}"
register: remote_files

- name: Compare local and remote cksums. Fail if not matched
fail:
msg: "Checksum don't match"
when: item[0].stat.checksum != item[1].stat.checksum
with_together:
- "{{ local_files.results }}"
- "{{ remote_files.results }}"

Ansible until: and register variables

create a custom filter named customfilter1 here,:

#!/usr/bin/python
import os
import json

class FilterModule(object):
def filters(self):
return {
'customfilter1': self.customfilter1
}

def customfilter1(self, obj, file):
if obj["attempts"] == 1:
result = [obj]
json_file = json.dumps(result, sort_keys = False, indent= 4)
with open(file, 'w') as f:
f.write(json_file)
else:
with open(file) as f:
result = json.load(f)
result.append(obj)
json_file = json.dumps(result, sort_keys = False, indent= 4)
with open(file, 'w') as f:
f.write(json_file)

return False

the plugin returns always the value false...

and you use it:

- win_updates:
ignore_errors: yes
category_names: '*'
reboot: yes
state: installed
register: win_updates
until: win_updates | customfilter1(file) or win_updates.installed_update_count == 0
vars:
file: /yourfolder/file.json

the file json contains all history, so you could modify the plugin to just keep what you want...

[
{
"attempts": 1,
"changed": false,
"failed": false,
"failed_update_count": 0,
"filtered_updates": {},
"found_update_count": 0,
"installed_update_count": 2,
"reboot_required": false,
"updates": {something...}
},
{
"attempts": 2,
"changed": false,
"failed": false,
"failed_update_count": 0,
"filtered_updates": {},
"found_update_count": 0,
"installed_update_count": 1,
"reboot_required": false,
"updates": {something...}
}, and so on

]

after that you could do a task to trap all names of package..(the file is json format, list of dictionaries)

so i have no window so i dont know your ouput..

a sample with random number:

- name: simulate
command: shuf -i 0-5 -n 1
register: out
until: out | customfilter1(file) or out.stdout | int == 2
retries: 100
vars:
file: /yourfolder/file.json

- name: group results
set_fact:
result: "{{ result | d([]) + [item.stdout] }}"
loop: "{{ lookup('file',file) | from_json }}"
vars:
file: /yourfolder/file.json

- name: group results
debug:
var: result

display result (stop when random number is 2) you have the list of all random numbers:

ok: [localhost] => {
"result": [
"5",
"3",
"3",
"1",
"3",
"0",
"4",
"0",
"5",
"2"
]
}


Related Topics



Leave a reply



Submit