When working with Ansible 1.1 playbooks, many users encounter situations where the file module mysteriously skips tasks during execution. In this specific case, the file ownership modification task gets skipped while the preceding file copy operation works fine.
- name: copy files
sudo: True
shell: cp /from/* /to/
- name: change owner
sudo: True
file: path=$item owner=newuser group=newgroup
with_fileglob: /to/*
The skipping occurs because of how with_fileglob
works in earlier Ansible versions. The glob pattern isn't being expanded properly before the file module processes it. Here's what's actually happening behind the scenes:
- The shell module copies files successfully
- The fileglob tries to match patterns before variable substitution
- Ansible sees the literal "$item" instead of expanded paths
Here are three approaches that actually work:
Solution 1: Use find module instead
- name: find copied files
find:
paths: /to/
patterns: "*"
recurse: no
register: found_files
- name: change owner (proper way)
file:
path: "{{ item.path }}"
owner: newuser
group: newgroup
loop: "{{ found_files.files }}"
Solution 2: Fix the original approach
- name: change owner (fixed version)
file:
path: "{{ item }}"
owner: newuser
group: newgroup
with_fileglob:
- "/to/*"
Solution 3: Modern Ansible approach (2.0+)
- name: change owner (modern syntax)
ansible.builtin.file:
path: "/to/{{ item | basename }}"
owner: newuser
group: newgroup
loop: "{{ query('fileglob', '/from/*') }}"
- File module skips when it can't resolve the path properly
- Older Ansible versions handle variable expansion differently
- The find module provides more reliable file discovery
- Modern Ansible versions offer better glob handling
When working with Ansible playbooks, encountering skipped tasks can be particularly frustrating. In this case, the file
module appears to skip ownership changes during file operations. Let's examine the original problematic code:
- name: copy files
sudo: True
shell: cp /from/* /to/
- name: change owner
sudo: True
file: path=$item owner=newuser group=newgroup
with_fileglob: /to/*
Several factors could cause this behavior:
- The
with_fileglob
loop might not be finding matching files - Permission issues preventing Ansible from accessing the files
- Incorrect variable expansion in the path parameter
- Timing issues between the copy operation and subsequent file operations
Here's an improved version of the playbook that addresses these issues:
- name: copy files
become: yes
copy:
src: "/from/"
dest: "/to/"
remote_src: yes
owner: newuser
group: newgroup
mode: '0644'
Alternatively, if you need separate tasks, consider this approach:
- name: ensure target directory exists
file:
path: "/to/"
state: directory
owner: newuser
group: newgroup
- name: copy files with proper permissions
synchronize:
src: "/from/"
dest: "/to/"
owner: yes
group: yes
recursive: yes
To diagnose the issue:
- name: debug file listing
command: ls -la /to/
register: file_list
changed_when: false
- name: display files
debug:
var: file_list.stdout_lines
Add verbosity to your playbook execution:
ansible-playbook playbook.yml -vvv
- Use
copy
orsynchronize
modules instead ofshell
for file transfers - Set ownership and permissions during the initial file operation when possible
- Consider using
register
anddebug
to verify file operations - Test playbooks with
--check
mode first
When dealing with complex file operations, it's often better to use dedicated modules like copy
, template
, or synchronize
rather than chaining shell
commands with subsequent file operations.