Introduction
Ansible is a widely-used IT automation tool that simplifies infrastructure management and deployment. In this lab, we will explore how to list files and directories in long format using Ansible. You will learn how to set up Ansible, create playbooks, and use the built-in modules to list file information from remote systems. By the end of this lab, you will have practical experience with Ansible commands and techniques that can enhance your automation workflows.
Installing and Setting Up Ansible
In this step, we will install Ansible on our system and create a basic inventory file to manage our local environment.
Installing Ansible
First, let's install Ansible using the package manager:
sudo apt update
sudo apt install -y ansible
After the installation completes, verify that Ansible is installed correctly by checking its version:
ansible --version
You should see output similar to this:
ansible [core 2.12.0]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.x (default, Ubuntu 22.04)
jinja version = 3.0.3
libyaml = True
Creating an Ansible Inventory
An inventory file is a list of managed nodes that Ansible can work with. For this lab, we'll create a simple inventory file that includes our local machine.
Create a directory for our Ansible project:
mkdir -p ~/project/ansible-lab
cd ~/project/ansible-lab
Now, create an inventory file using the VS Code editor:
- Click on the "Explorer" icon in the left sidebar
- Navigate to the
~/project/ansible-labdirectory - Right-click and select "New File"
- Name the file
inventory.ini - Add the following content to the file:
[local]
localhost ansible_connection=local
This inventory file defines a group called local that includes only our localhost, and specifies that Ansible should connect locally rather than using SSH.
Creating the Ansible Configuration File
Let's create a basic Ansible configuration file to specify default settings:
- In the Explorer panel, right-click on the
ansible-labdirectory and select "New File" - Name the file
ansible.cfg - Add the following content:
[defaults]
inventory = inventory.ini
host_key_checking = False
This configuration file tells Ansible to use our inventory.ini file by default and disables SSH host key checking, which is useful for lab environments.
Testing the Setup
Let's test our Ansible setup by running a simple command:
cd ~/project/ansible-lab
ansible local -m ping
You should see output similar to this:
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
This confirms that Ansible is properly configured and can communicate with our local machine.
Creating a Basic Ansible Playbook for Listing Files
In this step, we will create a basic Ansible playbook to list files and directories. Playbooks are YAML files that define a set of tasks to be executed on managed nodes.
Understanding Ansible Playbooks
Before we start creating our playbook, let's understand what a playbook is:
- A playbook is a YAML file that contains a list of plays
- Each play defines a set of tasks to run on a specific group of hosts
- Tasks are individual actions that call Ansible modules
- Modules are reusable units of code that perform specific operations
Creating Our First Playbook
Let's create a simple playbook to list the contents of the /etc directory:
- In the Explorer panel, navigate to the
~/project/ansible-labdirectory - Right-click and select "New File"
- Name the file
list_files.yml - Add the following content:
---
- name: List files and directories
hosts: local
tasks:
- name: Get directory listing
command: ls -l /etc
register: directory_contents
- name: Display directory contents
debug:
var: directory_contents.stdout_lines
Let's understand what this playbook does:
- The first line (
---) indicates the start of a YAML document name: List files and directoriesis a descriptive name for the playhosts: localspecifies that this play will run on hosts in thelocalgroup (defined in our inventory)tasks:begins the list of tasks to execute- The first task runs the command
ls -l /etcand stores the result in a variable calleddirectory_contents - The second task displays the contents of the
directory_contents.stdout_linesvariable
Running the Playbook
Now let's run our playbook:
cd ~/project/ansible-lab
ansible-playbook list_files.yml
You should see output similar to this:
PLAY [List files and directories] *****************************************************
TASK [Gathering Facts] ****************************************************************
ok: [localhost]
TASK [Get directory listing] **********************************************************
changed: [localhost]
TASK [Display directory contents] *****************************************************
ok: [localhost] => {
"directory_contents.stdout_lines": [
"total 1088",
"drwxr-xr-x 2 root root 4096 Apr 15 12:34 acpi",
"drwxr-xr-x 3 root root 4096 Apr 15 12:34 alternatives",
"-rw-r--r-- 1 root root 3028 Aug 1 2017 bash.bashrc",
"drwxr-xr-x 2 root root 4096 Apr 15 12:34 bash_completion.d",
"... [more files and directories] ..."
]
}
PLAY RECAP ***************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The output shows the contents of the /etc directory in the long format, which includes permissions, owner, group, size, and modification date.
Using a Different Directory
Now let's modify our playbook to list the contents of the /home/labex directory:
- Open the
list_files.ymlfile in the editor - Change the path in the command from
/etcto/home/labex - Save the file with the following content:
---
- name: List files and directories
hosts: local
tasks:
- name: Get directory listing
command: ls -l /home/labex
register: directory_contents
- name: Display directory contents
debug:
var: directory_contents.stdout_lines
Run the playbook again:
ansible-playbook list_files.yml
The output will now show the contents of the /home/labex directory instead of /etc.
Using Ansible's File Module for Long Format Listing
In the previous step, we used the command module to run the ls -l command. While this works, Ansible provides a more dedicated module for working with files and directories: the ansible.builtin.file module. In this step, we'll learn how to use this module along with the ansible.builtin.find module to list files in a more Ansible-native way.
Using the find Module
The ansible.builtin.find module is designed to locate files matching specific criteria. It provides a more powerful and flexible way to list files compared to the command module.
Let's create a new playbook that uses the find module:
- In the Explorer panel, navigate to the
~/project/ansible-labdirectory - Right-click and select "New File"
- Name the file
find_files.yml - Add the following content:
---
- name: Find files with Ansible
hosts: local
tasks:
- name: Find all files in /etc
ansible.builtin.find:
paths: /etc
file_type: any
register: found_files
- name: Display the first 10 files
debug:
var: found_files.files[:10]
This playbook uses the find module to locate all files and directories in the /etc directory and then displays the first 10 items.
Let's run the playbook:
cd ~/project/ansible-lab
ansible-playbook find_files.yml
You should see output that contains detailed information about each file, including:
- Path
- Mode (permissions)
- Owner and group
- Size
- Modified time
Creating a Playbook with Long Format Details
Now, let's create a more comprehensive playbook that displays files in a long format with all the details:
- In the Explorer panel, right-click and select "New File"
- Name the file
long_format.yml - Add the following content:
---
- name: List files in long format
hosts: local
tasks:
- name: Find files in /etc
ansible.builtin.find:
paths: /etc
file_type: any
recurse: no
register: found_files
- name: Create a formatted list of files
set_fact:
formatted_files: "{{ formatted_files | default([]) + [item] }}"
loop: "{{ found_files.files }}"
loop_control:
label: "{{ item.path }}"
vars:
item_info: >-
{{ item.mode }} {{ item.uid | string | ljust(5) }}
{{ item.gid | string | ljust(5) }} {{ item.size | string | ljust(10) }}
{{ item.mtime | string | ljust(11) }} {{ item.path }}
- name: Display files in long format
debug:
msg: "{{ formatted_files[:10] }}"
This playbook:
- Uses the
findmodule to locate files in the/etcdirectory - Creates a formatted list that resembles the output of the
ls -lcommand - Displays the first 10 files in the list
Let's run the playbook:
ansible-playbook long_format.yml
The output will show file details in a format similar to the ls -l command.
Filtering Files Based on Criteria
One advantage of using Ansible's modules is the ability to filter files based on various criteria. Let's create a playbook that lists only the configuration files (files ending with .conf):
- In the Explorer panel, right-click and select "New File"
- Name the file
filter_files.yml - Add the following content:
---
- name: List filtered files in long format
hosts: local
tasks:
- name: Find configuration files in /etc
ansible.builtin.find:
paths: /etc
patterns: "*.conf"
file_type: file
register: conf_files
- name: Display configuration files
debug:
msg: "{{ item.mode }} {{ item.uid }} {{ item.gid }} {{ item.size }} {{ item.mtime }} {{ item.path }}"
loop: "{{ conf_files.files }}"
loop_control:
label: "{{ item.path }}"
This playbook:
- Uses the
findmodule to locate files in the/etcdirectory that end with.conf - Displays each file with its details
Let's run the playbook:
ansible-playbook filter_files.yml
The output will show details only for .conf files in the /etc directory.
Comparing with Command Module
Let's create one more playbook to compare the output of the find module with the traditional ls -l command:
- In the Explorer panel, right-click and select "New File"
- Name the file
compare_methods.yml - Add the following content:
---
- name: Compare listing methods
hosts: local
tasks:
- name: Get directory listing with ls command
command: ls -l /etc/passwd
register: ls_output
- name: Get file info with find module
ansible.builtin.find:
paths: /etc
patterns: "passwd"
file_type: file
register: find_output
- name: Display ls command output
debug:
var: ls_output.stdout_lines
- name: Display find module output
debug:
var: find_output.files[0]
This playbook:
- Uses the
commandmodule to runls -lon the/etc/passwdfile - Uses the
findmodule to locate the same file - Displays both outputs for comparison
Let's run the playbook:
ansible-playbook compare_methods.yml
You can now see the difference between the two methods:
- The
ls -lcommand gives you a single line of text in the traditional Unix format - The
findmodule gives you a structured data object that you can manipulate in Ansible
Creating a Reusable Role for File Listing
In this step, we'll learn how to create an Ansible role for file listing. Roles are a way to organize playbooks and make them more reusable. This is especially useful when you need to perform the same task across multiple playbooks or projects.
Understanding Ansible Roles
An Ansible role is a set of tasks, variables, files, templates, and other resources that are grouped together in a standard directory structure. Roles make it easier to reuse code and share it with others.
The standard directory structure for a role looks like this:
roles/
rolename/
tasks/ ## Main tasks for the role
handlers/ ## Handlers triggered by tasks
defaults/ ## Default variables
vars/ ## Role variables
files/ ## Static files
templates/ ## Templates
meta/ ## Metadata for the role
Creating a File Listing Role
Let's create a role for listing files in long format:
- First, create the directory structure for our role:
cd ~/project/ansible-lab
mkdir -p roles/file_lister/tasks
- Create the main task file for our role:
cd ~/project/ansible-lab
- In the Explorer panel, navigate to
~/project/ansible-lab/roles/file_lister/tasks - Right-click and select "New File"
- Name the file
main.yml - Add the following content:
---
## Tasks for file_lister role
- name: Find files in the specified directory
ansible.builtin.find:
paths: "{{ path | default('/etc') }}"
patterns: "{{ patterns | default('*') }}"
file_type: "{{ file_type | default('any') }}"
recurse: "{{ recurse | default(false) }}"
register: found_files
- name: Display files in long format
debug:
msg: "{{ item.mode }} {{ item.uid }} {{ item.gid }} {{ item.size }} {{ item.mtime }} {{ item.path }}"
loop: "{{ found_files.files | sort(attribute='path') }}"
loop_control:
label: "{{ item.path }}"
when: show_details | default(true)
- name: Display only file paths
debug:
msg: "{{ item.path }}"
loop: "{{ found_files.files | sort(attribute='path') }}"
loop_control:
label: "{{ item.path }}"
when: not (show_details | default(true))
This role:
- Finds files in a specified directory based on parameters
- Displays the files in either long format or just the paths
- Uses default values for parameters if they're not specified
Using Our Role in a Playbook
Now, let's create a playbook that uses our new role:
- In the Explorer panel, navigate to the
~/project/ansible-labdirectory - Right-click and select "New File"
- Name the file
use_role.yml - Add the following content:
---
- name: Use file listing role
hosts: local
roles:
- role: file_lister
vars:
path: "/etc"
patterns: "*.conf"
file_type: "file"
show_details: true
This playbook:
- Runs on the local host
- Uses our
file_listerrole - Sets variables for the role to customize its behavior
Let's run the playbook:
cd ~/project/ansible-lab
ansible-playbook use_role.yml
You should see output showing the details of all .conf files in the /etc directory.
Customizing Role Variables
One of the advantages of roles is that we can easily customize their behavior by changing the variables. Let's create another playbook that uses our role with different parameters:
- In the Explorer panel, right-click and select "New File"
- Name the file
custom_listing.yml - Add the following content:
---
- name: Custom file listing
hosts: local
roles:
- role: file_lister
vars:
path: "/home/labex"
patterns: "*.yml"
file_type: "file"
show_details: false
This playbook:
- Uses our
file_listerrole - Sets it to look in the
/home/labexdirectory - Filters for YAML files (*.yml)
- Shows only file paths (not full details)
Let's run the playbook:
ansible-playbook custom_listing.yml
You should see a list of all YAML files in the /home/labex directory, without the detailed information.
Advanced Usage: Creating a Report
Finally, let's create a more advanced playbook that uses our role to generate a report of files:
- In the Explorer panel, right-click and select "New File"
- Name the file
generate_report.yml - Add the following content:
---
- name: Generate file listing report
hosts: local
vars:
report_path: "~/project/ansible-lab/file_report.txt"
tasks:
- name: Find files in the specified directory
ansible.builtin.find:
paths: "/etc"
patterns: "*.conf"
file_type: "file"
register: found_files
- name: Create report header
copy:
dest: "{{ report_path }}"
content: |
File Listing Report
Generated on: {{ ansible_date_time.date }} at {{ ansible_date_time.time }}
-----------------------------------------------------------
Mode Owner Group Size Modified Path
-----------------------------------------------------------
force: yes
- name: Append file information to report
lineinfile:
path: "{{ report_path }}"
line: "{{ item.mode }} {{ item.uid }} {{ item.gid }} {{ item.size | string | ljust(10) }} {{ item.mtime }} {{ item.path }}"
loop: "{{ found_files.files | sort(attribute='path') }}"
loop_control:
label: "{{ item.path }}"
- name: Display report location
debug:
msg: "Report generated at {{ report_path }}"
This playbook:
- Finds
.conffiles in the/etcdirectory - Creates a text file with a header
- Appends information about each file to the report
- Displays the location of the report
Let's run the playbook:
ansible-playbook generate_report.yml
After running the playbook, you can view the report:
cat ~/project/ansible-lab/file_report.txt
You should see a formatted report listing all the .conf files in the /etc directory.
Summary
In this lab, you have learned how to use Ansible to list files and directories in long format. You have gained practical experience with:
- Setting up Ansible by installing the software and creating an inventory file
- Creating basic playbooks that use the command module to run the
ls -lcommand - Using Ansible's built-in file and find modules to get detailed information about files
- Creating a reusable Ansible role for listing files with various options
- Generating formatted reports based on file information
These skills will help you automate file management tasks across your infrastructure and integrate file listings into larger automation workflows. As you continue working with Ansible, you can build on these concepts to create more complex automations that manage files, directories, and their permissions across your entire environment.


