Commands & Modules¶
- In this section, we will cover the Modules.
- Modules are important elements and act as the “heart” of
Ansible. 
What will we learn?¶
- What Ansible modules are and how they work
- How to use ad-hoc commands with modules
- How to use the
ping,shell,copy,file, andaptmodules - How to find and read module documentation
Prerequisites¶
- Complete the previous lab in order to have a working
Ansiblecontroller and inventory configuration.
01. What is a module?¶
- A module is a unit of code in
Ansiblethat performs common operations in infrastructure management (such as configuring systems, installing software and managing resources). Ansiblehas a huge number of modules (over 3,000+ built-in modules).- You can browse and search
Ansiblebuiltin modules in the Builtin Ansible modules. - Modules are used for task automation and can be executed directly via ad-hoc commands or within playbooks.
- Each module is idempotent by design - running it multiple times produces the same result without unwanted side effects.
Common Module Categories:¶
| Category | Examples | Use Cases |
|---|---|---|
| System | user, group, service, systemd | Managing users, groups, and services |
| Files | copy, file, template, lineinfile | File operations and modifications |
| Packaging | apt, yum, dnf, pip, npm | Package management |
| Commands | command, shell, script | Running commands |
| Network | uri, get_url, nmcli | Network operations |
| Database | mysql_db, postgresql_db, mongodb_user | Database management |
| Cloud | ec2, azure_rm_virtualmachine, gcp_compute_instance | Cloud resource management |
| Monitoring | nagios, datadog_monitor | Monitoring and alerting |
02. A sample module¶
- In this lab we will explore the builtin
pingmodule. - You can read about this module in the Ansible documentation.
- You can find the source code for this module in Builtin ping module repo.
03. The ping module¶
From the docs:
- ansible.builtin.ping module - Try to connect to host, verify a usable python and return pong on success
- This module is part of ansible-core and included in all Ansible installations.
- In most cases, you can use the short module name
ping
- Now, as we break down the code, feel free to browse and look at the full code.
04. The ping source code¶
- At the time of writing this tutorial, the “implementation” of the
pingmodule is as follows:
RETURN = '''
ping:
description: Value provided with the O(data) parameter.
returned: success
type: str
sample: pong
'''
from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec=dict(
data=dict(type='str', default='pong'),
),
supports_check_mode=True
)
if module.params['data'] == 'crash':
raise Exception("boom")
result = dict(
ping=module.params['data'],
)
module.exit_json(**result)
if __name__ == '__main__':
main()
05. List of modules¶
- Modules are managed in the form of
collections, as eachcollectioncontains multiple related modules. - See here for a List of Collections.
!!! warning “Note” Up to version 2.9, Ansible included all modules by default, but as the number of modules increased tremendously, it has been changed to the current format (ver. 2.10 and later).
06. Using modules¶
- By default
Ansibleis installed withansible.builtinas the only collection. - Click here for a list of modules that are available in the
ansible.builtin.
07. Find modules for your OS¶
- To see which modules are available for your OS, use the following command:
ansible-doc -l
### Output (only first few lines)
add_host Add a host (and alternatively a group) to the ansible-playbook in-memory inventor...
apt Manages apt-packages
apt_key Add or remove an apt key
apt_repository Add and remove APT repositories
assemble Assemble configuration files from fragments
assert Asserts given expressions are true
async_status Obtain status of asynchronous task
blockinfile Insert/update/remove a text block surrounded by marker lines
08. Documentation¶
- To view documentation for a specific module, use the following command:
# Display the ping documentation
$ ansible-doc ping
### Output (only first few lines)
> ANSIBLE.BUILTIN.PING (/opt/homebrew/Cellar/ansible/9.4.0_1/libexec/lib/python3.12/site-packages/ansible/modules/ping>
A trivial test module, this module always returns `pong' on successful contact. It does
not make sense in playbooks, but it is useful from `/usr/bin/ansible' to verify the
ability to login and that a usable Python is configured. This is NOT ICMP ping, this is
just a trivial test module that requires Python on the remote-node. For Windows targets,
use the [ansible.windows.win_ping] module instead. For Network targets, use the
[ansible.netcommon.net_ping] module instead.
ADDED IN: historical
OPTIONS (= is mandatory):
- data
Data to return for the `ping' return value.
09. Common ad-hoc commands¶
- Invoking a module is referred to as an
ad-hoc command. - The syntax of an
ad-hoc commandis as follows:
| CLI option | Description |
|---|---|
<servers> | Any server (single, group or all) as defined in the inventory file |
-m <module_name> | Specifies the module name |
-a <parameters> | Specifies the parameters to be passed to the module. Optional in most cases |
10. Ping usage¶
- We are already familiarized with the ping module.
!!! warning “Tips” - The ping module is a module that determines whether Ansible can “communicate as Ansible” with the node it is working on (which is different from ICMP used in the network). - The ping module parameters are optional.
- Usage:
# Ping all server in the inventory
ansible all -m ping
# In our demo lab we will execute it, as follows:
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m ping"
### Output
linux-server-1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
linux-server-3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
linux-server-2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
11. The shell module¶
- This is a module that executes shell commands on targets’ nodes.
- See
Ansibledocumentation about theshellmodule.
TIP
Be cautious when using the shell module, as it can introduce security risks if not used properly. Always validate and sanitize any user input that may be passed to shell commands.
# Let's get the hostname of the server
ansible all -m shell -a 'hostname'
# In our demo lab we will execute it like this:
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m shell -a 'hostname'"
# Output
# ansible all -m shell -a 'hostname'
linux-server-3 | CHANGED | rc=0 >>
linux-server-3
linux-server-2 | CHANGED | rc=0 >>
linux-server-2
linux-server-1 | CHANGED | rc=0 >>
linux-server-1
12. The copy module¶
- The
copymodule copies files from the local or remote machine to a location on remote hosts. - See documentation about the
copymodule.
# Copy a file to remote hosts
ansible all -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt mode=0644"
# Create a file with content
ansible all -m copy -a "content='Hello World' dest=/tmp/hello.txt"
13. The file module¶
- The
filemodule manages files, directories, and their properties. - See documentation about the
filemodule.
# Create a directory
ansible all -m file -a "path=/tmp/mydir state=directory mode=0755"
# Create a symlink
ansible all -m file -a "src=/tmp/test.txt dest=/tmp/link.txt state=link"
# Remove a file
ansible all -m file -a "path=/tmp/test.txt state=absent"
# Change file permissions
ansible all -m file -a "path=/tmp/test.txt mode=0600 owner=root group=root"
14. The apt module (Debian/Ubuntu)¶
- The
aptmodule manages packages on Debian-based systems. - See documentation about the
aptmodule.
# Install a package
ansible all -m apt -a "name=nginx state=present" --become
# Install multiple packages
ansible all -m apt -a "name=nginx,git,curl state=present" --become
# Remove a package
ansible all -m apt -a "name=nginx state=absent" --become
# Update cache and upgrade all packages
ansible all -m apt -a "upgrade=dist update_cache=yes" --become
15. The service module¶
- The
servicemodule manages services on remote hosts. - See documentation about the
servicemodule.
# Start a service
ansible all -m service -a "name=nginx state=started" --become
# Stop a service
ansible all -m service -a "name=nginx state=stopped" --become
# Restart a service
ansible all -m service -a "name=nginx state=restarted" --become
# Enable service on boot
ansible all -m service -a "name=nginx enabled=yes" --become
16. The user module¶
- The
usermodule manages user accounts on remote hosts. - See documentation about the
usermodule.
# Create a user
ansible all -m user -a "name=john state=present" --become
# Create user with specific UID and shell
ansible all -m user -a "name=john uid=1500 shell=/bin/bash" --become
# Add user to groups
ansible all -m user -a "name=john groups=sudo,docker append=yes" --become
# Remove a user
ansible all -m user -a "name=john state=absent remove=yes" --become
17. The lineinfile module¶
- The
lineinfilemodule manages single lines in text files. - See documentation about the
lineinfilemodule.
# Add a line to a file
ansible all -m lineinfile -a "path=/etc/hosts line='192.168.1.100 myserver.local'" --become
# Replace a line matching a pattern
ansible all -m lineinfile -a "path=/etc/ssh/sshd_config regexp='^PermitRootLogin' line='PermitRootLogin no'" --become
# Remove a line
ansible all -m lineinfile -a "path=/etc/hosts line='192.168.1.100 myserver.local' state=absent" --become
18. The get_url module¶
- The
get_urlmodule downloads files from HTTP, HTTPS, or FTP. - See documentation about the
get_urlmodule.
# Download a file
ansible all -m get_url -a "url=https://example.com/file.zip dest=/tmp/file.zip"
# Download with checksum verification
ansible all -m get_url -a "url=https://example.com/file.zip dest=/tmp/file.zip checksum=sha256:abc123..."
19. Module vs Command vs Shell¶
Key Differences:
| Aspect | Module | Command | Shell |
|---|---|---|---|
| Idempotent | Yes | No | No |
| Safe | Yes | Yes | Potentially risky |
| Shell features | N/A | No | Yes (pipes, redirects) |
| Preferred | ✅ Always preferred | Use when no module | Last resort |
Examples:
# ❌ BAD: Using shell to copy file
ansible all -m shell -a "cp /source /dest"
# ✅ GOOD: Using copy module
ansible all -m copy -a "src=/source dest=/dest"
# ❌ BAD: Using shell to create user
ansible all -m shell -a "useradd john"
# ✅ GOOD: Using user module
ansible all -m user -a "name=john state=present"

20. Hands-on¶
-
Figure out a way to run the following (shell) command with
Ansible, on any of the servers:Solution
````sh # Using the shell module docker exec ansible-controller sh -c “cd /labs-scripts && ansible linux-server-1 -m shell -a ‘uname -a’” docker exec ansible-controller sh -c “cd /labs-scripts && ansible linux-server-1 -m shell -a ‘date’”
# Using the ansible command module docker exec ansible-controller sh -c "cd /labs-scripts && ansible linux-server-1 -m command -a 'uname -a'" docker exec ansible-controller sh -c "cd /labs-scripts && ansible linux-server-1 -m command -a 'date'" ```````
-
Use the Ansible
commandmodule to print out the previous shell commands.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m command -a 'uname -a'" docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m command -a 'date'" -
Try to run the following command:
What is the result of this command?
Solution
````sh # The command docker exec ansible-controller sh -c “cd /labs-scripts && ansible all -m shell -a ‘git config -l’”
### Output # If git is not installed, you'll get an error # If git is installed but not configured, you'll see minimal output # If git is configured, you'll see: user.name=Your Name user.email=your.email@example.com core.repositoryformatversion=0 core.filemode=true core.bare=false ```````
-
Create a directory called
/tmp/ansible-teston all servers using thefilemodule.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'path=/tmp/ansible-test state=directory mode=0755'" -
Create a file
/tmp/info.txtwith the content “Ansible Lab 003” using thecopymodule.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m copy -a \"content='Ansible Lab 003' dest=/tmp/info.txt\"" -
Use the
lineinfilemodule to add your name to/tmp/info.txt.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m lineinfile -a \"path=/tmp/info.txt line='Name: Your Name'\"" -
Check if the
gitpackage is installed on your servers using theshellmodule.Solution
````sh # Using shell module docker exec ansible-controller sh -c “cd /labs-scripts && ansible all -m shell -a ‘which git’”
# Or check version docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m shell -a 'git --version'" ```````
-
Use the
filemodule to change the permissions of/tmp/info.txtto0600.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'path=/tmp/info.txt mode=0600'" -
Create a symbolic link from
/tmp/info.txtto/tmp/info-link.txt.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'src=/tmp/info.txt dest=/tmp/info-link.txt state=link'" -
Use the
get_urlmodule to download a file from the internet to/tmp/.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m get_url -a 'url=https://raw.githubusercontent.com/ansible/ansible/devel/README.md dest=/tmp/ansible-readme.md'" -
List all files in
/tmpdirectory that start with “ansible” or “info”.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m shell -a 'ls -la /tmp/ | grep -E \"(ansible|info)\"'" -
Remove the directory
/tmp/ansible-testand all its contents.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m file -a 'path=/tmp/ansible-test state=absent'" -
Use the
setupmodule to gather facts about one of your servers and filter for memory information.Solution
-
Create a user named
ansibleuserwith home directory/home/ansibleuser.Solution
sh docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m user -a 'name=ansibleuser home=/home/ansibleuser state=present' --become" -
Use modules to check disk usage on all servers.
Solution
````sh # Using shell module docker exec ansible-controller sh -c “cd /labs-scripts && ansible all -m shell -a ‘df -h’”
# Or specific path docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m shell -a 'du -sh /tmp'" ```````
22. Summary¶
- Modules are the core building blocks of Ansible automation
- Over 3,000+ built-in modules covering system, files, packages, cloud, and more
- Modules are idempotent - safe to run multiple times
- Use
ansible-docto view module documentation - Ad-hoc commands:
ansible <hosts> -m <module> -a '<args>' - Always prefer modules over
shellorcommandwhen available - Common modules:
ping,copy,file,apt,service,user,lineinfile - Use
--becomefor operations requiring elevated privileges - Modules provide structured output and proper error handling
- Each module has specific parameters - check docs before using