Ansible: Replacing with_items by loop

Viewed 137

Scenario:

Changing logrotation to daily in all logrotate-config files.

  • /etc/logrotate.d/*
  • /etc/logrotate.conf

Tasks:

  1. Getting list of files in /etc/logrotate.d
- find:
    paths: /etc/logrotate.d/
  register: logrotate_d
  1. Changing log rotation in config files
- replace:
    path: "{{ item.path }}"
    regexp: '^(\s*)(daily|weekly|monthly|yearly)$'
    replace: "\\1daily"
  with_items: 
    - { path: "/etc/logrotate.conf" }
    - "{{ logrotate_d.files }}"
  loop_control:
    label: "{{ item.path }}"

Question:

How can I replace with_items by loop without running in to the following error:

'list object' has no attribute 'path' 
1 Answers

There are some differences between the behaviour of with_items and loop as documented here. Quoting the relevant bit below:

... with_items performed implicit single-level flattening ...

So when you supply 2 lists to with_items they are flattened to 1 list and each item's path attribute is available. Whereas with loop, the second list logrotate_d.files remains a separate list, and that's why item.path attribute cannot be accessed.

For your use with_items seems more suitable. However if you do want to use it with loop you can write it as:

- replace:
    path: "{{ item.path }}"
    regexp: '^(\s*)(daily|weekly|monthly|yearly)$'
    replace: "\\1daily"
  loop: "{{ [ { 'path': '/etc/logrotate.conf' } ] + logrotate_d.files }}"
  loop_control:
    label: "{{ item.path }}"
Related