Problem with stat module and multiple files in the register

Hello

I’m struggling with file check when there’s more than one file in the stat module.

For example, this works:

- name: Check if conf file exist.
  ansible.builtin.stat:
    path: /etc/file.conf
  register: confcheck

- name: Create the file.conf file.
  ansible.builtin.lineinfile:
    create: true
    group: root
    line: root
    mode: '0600'
    owner: root
    path: /etc/file.conf
    state: present
  when: not confcheck.stat.exists

When I would add a list of files, I’m no longer able to use when: because I don’t understand how it works.
Using debug to display the register result, I see the structure, but whatever I put in the when: block, I get this item is not in the list error every time. Ansible docs didn’t help.

What I’m trying to do here is to copy the file to /etc/app.d/ folder if it exists in /etc, if it doesn’t exist in /etc/ and /etc/app.d/, create the file in /etc/app.d/ and I should be able to determine the exists value for each file from ther registered variable.

- name: Check if conf files exist.
  ansible.builtin.stat:
    path: "{{ item }}"
  loop:
    - /etc/app1.conf
    - /etc/app.d/app1.conf
    - /etc/app2.conf
    - /etc/app.d/app2.conf
  register: confcheck

- name: Copy app1.conf to app.d directory.
  ansible.builtin.copy:
    dest: /etc/app.d/app1.conf
    group: root
    mode: '0600'
    owner: root
    remote_src: true
    src: "/etc/app1.conf"
  loop:
    - "{{ confcheck }}"
  when: item.stat.exists # This should be: exists /etc/app1.conf and not exists /etc/app.d/app1.conf. This would fail as there is no stat item, although there is when I check with the debug module.

- name: Create the file.conf file.
  ansible.builtin.lineinfile:
    create: true
    group: root
    line: root
    mode: '0600'
    owner: root
    path: /etc/file.conf
    state: present
  loop:
    - "{{ confcheck }}"
  when: not items.stat.exists # This should be: not exists /etc/app1.conf and not exists /etc/app.d/app1.conf.

I need someone to tell me how to iterate registered list vars.
Right now, I have separate registers per file, and I don’t like it.

This is nicely explained in the documentation:

Update: sorry I didn’t read you question carefully. You already mentioned docs were of no help.

I think you are missing only one thing. You should loop over confcheck['results'] like this:

- name: Copy app1.conf to app.d directory.
  ansible.builtin.copy:
    dest: /etc/app.d/app1.conf
    group: root
    mode: '0600'
    owner: root
    remote_src: true
    src: "/etc/app1.conf"
  loop:
    - "{{ confcheck['results'] }}"
  when: item.stat.exists

It’s a little bit hard to understand what are you trying to accomplish, but in the previous code either dest or src or both should also be variables dependent on {{ item['item'] }}. Possibly something like this:

- name: Copy app1.conf to app.d directory.
  ansible.builtin.copy:
    dest: "/etc/app.d/{{ item['item'] }}"
    group: root
    mode: '0600'
    owner: root
    remote_src: true
    src: "/etc/{{ item['item'] }}"
  loop:
    - "{{ confcheck['results'] }}"
  when: item.stat.exists

And another note, {{ item['item'] }} is the notation I preferably used but {{ item.item }} can also be used and is the equivalent.

1 Like