Iterate over matching files: `with_fileglob` module in Ansible

The with_fileglob module in Ansible is used to iterate over files in a directory that match a specified pattern on the Ansible controller machine. This is useful when you need to perform tasks on multiple files without explicitly listing each one. The with_fileglob loop allows you to apply actions to all files that match a given globbing pattern, making your playbooks more dynamic and easier to maintain.

with_fileglob module use Python’s “glob” library to find all pathnames.

Use Cases

  1. Deploying Configuration Files: You can use with_fileglob to copy multiple configuration files from a directory to a target host.

  2. Template Rendering: Render multiple template files from a directory.

  3. File Permissions: Change the permissions of multiple files in a directory.

  4. Backup: Back up multiple files from a directory to another location.

Code Examples

  1. Copying Configuration Files:

     - name: Copy all config files
       hosts: webservers
       tasks:
         - name: Copy configuration files
           copy:
             src: "{{ item }}"
             dest: /etc/myapp/config/
           with_fileglob:
             - /path/to/local/configs/*.conf
    
  2. Rendering Templates:

     - name: Render multiple template files
       hosts: appservers
       tasks:
         - name: Template files
           template:
             src: "{{ item }}"
             dest: "/etc/myapp/templates/{{ item | basename }}"
           with_fileglob:
             - /path/to/templates/*.j2
    
  3. Changing File Permissions:

     - name: Change permissions of log files
       hosts: servers
       tasks:
         - name: Set permissions
           file:
             path: "{{ item }}"
             mode: '0644'
           with_fileglob:
             - /var/log/myapp/*.log
    
  4. Backing Up Files:

     - name: Backup important files
       hosts: all
       tasks:
         - name: Copy files to backup directory
           copy:
             src: "{{ item }}"
             dest: /backup/
           with_fileglob:
             - /etc/myapp/important_files/*
    

Explanation

  • with_fileglob: This is the loop directive that tells Ansible to iterate over files matching the given pattern.

  • src: Specifies the source file or directory.

  • dest: Specifies the destination file or directory.

  • item: The current item in the loop, representing each file that matches the pattern.

By using with_fileglob, you can simplify tasks that need to be performed on multiple files without hardcoding each file path, making your Ansible playbooks more efficient and easier to manage.

How with_fileglob works

The with_fileglob module in Ansible is used to match files on the Ansible control machine, not on the remote hosts. This is an important distinction because the file matching is performed locally on the machine where the playbook is being run, and then the actions specified in the tasks are applied to the matched files.

Key Points

  1. Local to Control Machine: The file globbing operation (with_fileglob) is executed on the control machine where Ansible is running.

  2. Remote Tasks: Once the files are matched, the specified tasks (such as copying files, changing permissions, etc.) are executed on the remote hosts.

Example Clarification

Let's clarify with an example:

Control Machine Setup:

  • Assume you have a directory /path/to/local/configs/ on your control machine with several .conf files.

Playbook:

- name: Copy all config files
  hosts: webservers
  tasks:
    - name: Copy configuration files
      copy:
        src: "{{ item }}"
        dest: /etc/myapp/config/
      with_fileglob:
        - /path/to/local/configs/*.conf

Execution Flow

  1. Globbing on Control Machine: Ansible matches all files ending with .conf in the /path/to/local/configs/ directory on the control machine.

  2. Copy Task: The copy module is then used to copy each matched file from the control machine to the specified destination (/etc/myapp/config/) on the remote hosts (e.g., webservers).

Workshop: Copy config files from one local directory to another

This example will demonstrate using with_fileglob to copy multiple configuration files from a local directory to another directory on the same machine.

Step 1: Prepare the Environment

Open a terminal and run the following commands:

mkdir -p ~/ansible_test/configs
mkdir -p ~/ansible_test/target

# Create some sample config files
echo "config1" > ~/ansible_test/configs/sample1.conf
echo "config2" > ~/ansible_test/configs/sample2.conf
echo "config3" > ~/ansible_test/configs/sample3.conf

Step 2: Create the Ansible Playbook

Create a file named copy_configs.yml and add the following content:

---
- name: Copy configuration files using with_fileglob
  hosts: localhost
  connection: local
  tasks:
    - name: Copy configuration files to target directory
      copy:
        src: "{{ item }}"
        dest: ~/ansible_test/target/
      with_fileglob:
        - "~/ansible_test/configs/*.conf"

Step 3: Run the Playbook

Ensure you have Ansible installed. If not, you can install it using:

sudo apt update
sudo apt install ansible -y

Run the playbook with the following command:

ansible-playbook copy_configs.yml

Step 4: Verify the Result

Check the contents of the target directory to ensure the files were copied correctly:

ls ~/ansible_test/target

You should see sample1.conf, sample2.conf, and sample3.conf in the ~/ansible_test/target directory.

Explanation

  • hosts: localhost: Specifies that the playbook will run on the local machine.

  • connection: local: Ensures Ansible runs the tasks locally.

  • with_fileglob: Matches all .conf files in the specified directory.

  • copy module: Copies each matched file from the source directory to the target directory.

References:

  1. Ansible docs: ansible.builtin.fileglob lookup – list files matching a pattern