Essential Ansible Modules Guide: 50+ Modules for Files, Packages, Services, and System Management
Ansible modules are the building blocks of automation, providing pre-built functionality for managing systems, applications, networks, and cloud infrastructure. This comprehensive guide covers 50+ essential Ansible modules across all major categories with practical examples you can use immediately in production environments.
📑 Table of Contents
- What are Ansible Modules?
- Key Characteristics
- Module Syntax
- File and Directory Modules
- file – Manage Files and Directories
- copy – Copy Files to Remote Hosts
- template – Deploy Jinja2 Templates
- lineinfile – Modify Specific Lines
- blockinfile – Manage Text Blocks
- Package Management Modules
- apt – Debian/Ubuntu Package Manager
- yum/dnf – RedHat/CentOS Package Manager
- package – Generic Package Manager
- pip – Python Package Manager
- Service Management Modules
- service – Manage Services
- systemd – Systemd Service Manager
- User and Group Management
- user – Manage User Accounts
- group – Manage Groups
- authorized_key – Manage SSH Keys
- Command Execution Modules
- command – Execute Commands
- shell – Execute Shell Commands
- script – Execute Local Scripts Remotely
- raw – Execute Raw Commands
- Archive and Compression
- archive – Create Archives
- unarchive – Extract Archives
- Web and Network Modules
- get_url – Download Files
- uri – Make HTTP Requests
- Git Module
- git – Manage Git Repositories
- Cron Management
- cron – Manage Cron Jobs
- System Modules
- mount – Manage Filesystems
- sysctl – Manage Kernel Parameters
- hostname – Set System Hostname
- timezone – Set System Timezone
- Utility Modules
- wait_for – Wait for Conditions
- stat – Get File Information
- find – Find Files
- set_fact – Set Variables
- assert – Validate Conditions
- debug – Display Information
- Best Practices
- 1. Use Check Mode for Testing
- 2. Use become Appropriately
- 3. Register and Check Results
- 4. Use Idempotent Modules
- Summary
What are Ansible Modules?
Modules are units of code that Ansible executes on target hosts. Each module performs a specific task like installing packages, managing files, configuring services, or interacting with APIs. Ansible includes thousands of modules, and you can also write custom modules.
Key Characteristics
- Idempotent: Running the same module multiple times produces the same result
- Declarative: Describe desired state, not steps to achieve it
- Cross-Platform: Work across Linux, Windows, network devices, cloud providers
- Extensible: Create custom modules in Python or any language
- Well-Documented: Built-in documentation via
ansible-doc
Module Syntax
- name: Task description
module_name:
parameter1: value1
parameter2: value2
parameter3: value3
become: yes # Optional: run with elevated privileges
register: result # Optional: save output to variable
File and Directory Modules
file – Manage Files and Directories
# Create directory
- name: Create application directory
file:
path: /opt/myapp
state: directory
mode: '0755'
owner: appuser
group: appgroup
# Create multiple directories
- name: Create directory structure
file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- /opt/app/bin
- /opt/app/config
- /opt/app/logs
- /opt/app/data
# Create symbolic link
- name: Create symlink
file:
src: /opt/app/bin/myapp
dest: /usr/local/bin/myapp
state: link
# Remove file or directory
- name: Remove temp directory
file:
path: /tmp/tempdir
state: absent
# Touch file (update timestamp or create if missing)
- name: Touch log file
file:
path: /var/log/myapp.log
state: touch
mode: '0644'
owner: appuser
# Set file permissions and attributes
- name: Secure configuration file
file:
path: /etc/app/secrets.conf
mode: '0600'
owner: root
group: root
attributes: +i # Make immutable
copy – Copy Files to Remote Hosts
# Copy file from control node to remote
- name: Copy configuration file
copy:
src: /local/path/config.ini
dest: /etc/app/config.ini
owner: root
group: root
mode: '0644'
backup: yes # Backup existing file
# Copy with inline content
- name: Create file with content
copy:
content: |
# Application Configuration
debug = false
port = 8080
dest: /etc/app/app.conf
mode: '0644'
# Copy directory recursively
- name: Copy entire directory
copy:
src: /local/configs/
dest: /etc/app/
directory_mode: '0755'
# Copy from remote to remote
- name: Copy file on remote host
copy:
src: /tmp/source.txt
dest: /opt/destination.txt
remote_src: yes
template – Deploy Jinja2 Templates
# Deploy template with variables
- name: Deploy Nginx configuration
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
validate: 'nginx -t -c %s' # Validate before deploying
backup: yes
notify: reload nginx
# Template with variables
- name: Deploy application config
template:
src: app.conf.j2
dest: /etc/app/{{ app_name }}.conf
vars:
app_name: myapp
app_port: 8080
environment: production
lineinfile – Modify Specific Lines
# Add line if missing
- name: Add host entry
lineinfile:
path: /etc/hosts
line: "192.168.1.100 app.example.com"
state: present
# Replace line matching regex
- name: Disable root login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
backup: yes
# Insert after specific pattern
- name: Add user limits
lineinfile:
path: /etc/security/limits.conf
insertafter: '^# End of file'
line: "appuser soft nofile 65536"
# Remove line
- name: Remove old configuration
lineinfile:
path: /etc/app/config.ini
regexp: 'old_setting='
state: absent
blockinfile – Manage Text Blocks
# Insert configuration block
- name: Add custom Nginx configuration
blockinfile:
path: /etc/nginx/nginx.conf
block: |
# Custom settings
client_max_body_size 100M;
keepalive_timeout 65;
gzip on;
marker: "# {mark} ANSIBLE MANAGED BLOCK"
insertbefore: "^http {"
backup: yes
# Remove block
- name: Remove old configuration block
blockinfile:
path: /etc/app/config.conf
state: absent
marker: "# {mark} OLD CONFIG"
Package Management Modules
apt – Debian/Ubuntu Package Manager
# Install single package
- name: Install Nginx
apt:
name: nginx
state: present
update_cache: yes
cache_valid_time: 3600
# Install multiple packages
- name: Install development tools
apt:
name:
- build-essential
- git
- vim
- curl
- python3-pip
state: present
# Install specific version
- name: Install specific Python version
apt:
name: python3.9=3.9.5-1
state: present
# Upgrade all packages
- name: Upgrade all packages
apt:
upgrade: dist
update_cache: yes
# Remove package
- name: Remove Apache
apt:
name: apache2
state: absent
purge: yes # Remove config files too
# Install from .deb file
- name: Install local package
apt:
deb: /tmp/package.deb
yum/dnf – RedHat/CentOS Package Manager
# Install package (yum for RHEL 7, dnf for RHEL 8+)
- name: Install Nginx
yum:
name: nginx
state: present
# Using dnf (RHEL 8+)
- name: Install packages with dnf
dnf:
name:
- nginx
- postgresql
- redis
state: latest
# Install from URL
- name: Install RPM from URL
yum:
name: https://example.com/package.rpm
state: present
# Remove package
- name: Remove httpd
yum:
name: httpd
state: absent
package – Generic Package Manager
# Works across different package managers
- name: Install htop (works on Ubuntu, CentOS, etc.)
package:
name: htop
state: present
pip – Python Package Manager
# Install Python packages
- name: Install Python packages
pip:
name:
- flask
- requests
- ansible
- boto3
state: present
# Install specific version
- name: Install Django 3.2
pip:
name: django
version: 3.2.0
# Install from requirements file
- name: Install from requirements.txt
pip:
requirements: /opt/app/requirements.txt
# Install in virtualenv
- name: Install in virtual environment
pip:
name: flask
virtualenv: /opt/app/venv
virtualenv_python: python3.9
Service Management Modules
service – Manage Services
# Start service
- name: Start Nginx
service:
name: nginx
state: started
enabled: yes # Start on boot
# Stop service
- name: Stop Apache
service:
name: apache2
state: stopped
# Restart service
- name: Restart PostgreSQL
service:
name: postgresql
state: restarted
# Reload service (without restart)
- name: Reload Nginx configuration
service:
name: nginx
state: reloaded
# Disable service from starting on boot
- name: Disable MySQL
service:
name: mysql
enabled: no
systemd – Systemd Service Manager
# Manage systemd services
- name: Start and enable service
systemd:
name: myapp
state: started
enabled: yes
daemon_reload: yes # Reload systemd if unit file changed
# Restart service
- name: Restart application
systemd:
name: myapp
state: restarted
# Reload systemd configuration
- name: Reload systemd daemon
systemd:
daemon_reload: yes
User and Group Management
user – Manage User Accounts
# Create user
- name: Create application user
user:
name: appuser
uid: 2000
group: appgroup
groups: wheel,developers # Additional groups
shell: /bin/bash
home: /opt/appuser
create_home: yes
comment: "Application User"
state: present
# Create system user (no home)
- name: Create system user
user:
name: sysuser
system: yes
shell: /usr/sbin/nologin
create_home: no
# Remove user
- name: Remove user
user:
name: olduser
state: absent
remove: yes # Remove home directory
# Lock user account
- name: Lock user
user:
name: tempuser
password_lock: yes
# Set password
- name: Set user password
user:
name: webadmin
password: "{{ 'MyPassword123' | password_hash('sha512') }}"
update_password: on_create # Only set on creation
group – Manage Groups
# Create group
- name: Create application group
group:
name: appgroup
gid: 2000
state: present
# Create system group
- name: Create system group
group:
name: sysgroup
system: yes
# Remove group
- name: Remove group
group:
name: oldgroup
state: absent
authorized_key – Manage SSH Keys
# Add SSH key to user
- name: Add SSH public key
authorized_key:
user: deploy
key: "{{ lookup('file', '/path/to/public_key.pub') }}"
state: present
# Add multiple keys
- name: Add multiple SSH keys
authorized_key:
user: admin
key: "{{ item }}"
loop:
- "ssh-rsa AAAAB3NzaC1... user1@example.com"
- "ssh-rsa AAAAB3NzaC1... user2@example.com"
# Remove SSH key
- name: Remove old SSH key
authorized_key:
user: olduser
key: "ssh-rsa AAAAB3NzaC1... old@example.com"
state: absent
Command Execution Modules
command – Execute Commands
# Run simple command
- name: Get uptime
command: uptime
register: uptime_output
# Run with arguments
- name: List files
command: ls -la /etc
args:
chdir: /tmp # Change directory first
register: file_list
# Conditional execution
- name: Create file if missing
command: touch /tmp/marker
args:
creates: /tmp/marker # Skip if file exists
- name: Remove file if exists
command: rm /tmp/tempfile
args:
removes: /tmp/tempfile # Skip if file doesn't exist
shell – Execute Shell Commands
# Run shell command with pipes
- name: Count processes
shell: ps aux | grep nginx | wc -l
register: nginx_count
# Run with specific shell
- name: Execute bash script
shell: /path/to/script.sh
args:
executable: /bin/bash
# Multi-line command
- name: Complex shell command
shell: |
cd /opt/app
source venv/bin/activate
python manage.py migrate
register: migration_output
script – Execute Local Scripts Remotely
# Run local script on remote host
- name: Execute setup script
script: /local/path/setup.sh
args:
creates: /opt/app/installed # Skip if marker exists
# Script with arguments
- name: Run script with args
script: /local/scripts/deploy.sh production v2.0
raw – Execute Raw Commands
# Execute command without Python (useful for network devices)
- name: Check OS on device without Python
raw: cat /etc/os-release
register: os_info
Archive and Compression
archive – Create Archives
# Create tar.gz archive
- name: Archive application directory
archive:
path: /opt/app
dest: /backups/app_{{ ansible_date_time.date }}.tar.gz
format: gz
# Archive multiple paths
- name: Archive logs
archive:
path:
- /var/log/app/*.log
- /var/log/nginx/*.log
dest: /backups/logs.tar.gz
remove: yes # Remove source files after archiving
unarchive – Extract Archives
# Extract tar.gz
- name: Extract application archive
unarchive:
src: /tmp/app.tar.gz
dest: /opt/app
remote_src: yes # Source file is on remote host
# Extract from URL
- name: Download and extract
unarchive:
src: https://example.com/app.tar.gz
dest: /opt/app
remote_src: yes
# Extract with specific ownership
- name: Extract and set ownership
unarchive:
src: /tmp/archive.tar.gz
dest: /opt
owner: appuser
group: appgroup
remote_src: yes
Web and Network Modules
get_url – Download Files
# Download file
- name: Download application binary
get_url:
url: https://example.com/app.tar.gz
dest: /tmp/app.tar.gz
mode: '0644'
# Download with checksum verification
- name: Download with checksum
get_url:
url: https://example.com/package.tar.gz
dest: /tmp/package.tar.gz
checksum: sha256:abc123...
# Download with authentication
- name: Download protected file
get_url:
url: https://secure.example.com/file.zip
dest: /tmp/file.zip
url_username: admin
url_password: "{{ vault_password }}"
uri – Make HTTP Requests
# GET request
- name: Check API health
uri:
url: https://api.example.com/health
method: GET
return_content: yes
register: health_check
# POST request with JSON
- name: Create resource via API
uri:
url: https://api.example.com/users
method: POST
body_format: json
body:
name: "John Doe"
email: "john@example.com"
headers:
Authorization: "Bearer {{ api_token }}"
status_code: [200, 201]
register: create_response
# PUT request
- name: Update resource
uri:
url: https://api.example.com/users/123
method: PUT
body_format: json
body:
status: active
status_code: 200
# DELETE request
- name: Delete resource
uri:
url: https://api.example.com/users/123
method: DELETE
status_code: [200, 204]
Git Module
git – Manage Git Repositories
# Clone repository
- name: Clone application repository
git:
repo: https://github.com/example/app.git
dest: /opt/app
version: main
force: yes # Discard local changes
# Clone specific branch
- name: Clone development branch
git:
repo: https://github.com/example/app.git
dest: /opt/app-dev
version: develop
# Clone specific tag
- name: Clone specific version
git:
repo: https://github.com/example/app.git
dest: /opt/app
version: v2.1.0
# Clone with SSH key
- name: Clone private repository
git:
repo: git@github.com:company/private-app.git
dest: /opt/private-app
key_file: /home/deploy/.ssh/id_rsa
accept_hostkey: yes
Cron Management
cron – Manage Cron Jobs
# Create cron job
- name: Backup database daily
cron:
name: "Database backup"
minute: "0"
hour: "2"
job: "/usr/local/bin/backup_db.sh"
user: root
state: present
# Run every 5 minutes
- name: Check service health
cron:
name: "Health check"
minute: "*/5"
job: "/usr/local/bin/health_check.sh"
# Run on reboot
- name: Start application on reboot
cron:
name: "Start app"
special_time: reboot
job: "/usr/local/bin/start_app.sh"
# Disable cron job (keep but don't run)
- name: Disable backup temporarily
cron:
name: "Database backup"
disabled: yes
# Remove cron job
- name: Remove old cron job
cron:
name: "Old job"
state: absent
System Modules
mount – Manage Filesystems
# Mount filesystem
- name: Mount data partition
mount:
path: /mnt/data
src: /dev/sdb1
fstype: ext4
state: mounted
# Mount with options
- name: Mount with specific options
mount:
path: /mnt/nfs
src: nfs.example.com:/exports
fstype: nfs
opts: defaults,rw,noatime
state: mounted
# Unmount
- name: Unmount filesystem
mount:
path: /mnt/temp
state: unmounted
sysctl – Manage Kernel Parameters
# Set kernel parameter
- name: Increase max file descriptors
sysctl:
name: fs.file-max
value: '65536'
state: present
reload: yes
# Multiple parameters
- name: Configure network settings
sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
state: present
reload: yes
loop:
- { key: 'net.ipv4.ip_forward', value: '1' }
- { key: 'net.ipv4.tcp_syncookies', value: '1' }
- { key: 'vm.swappiness', value: '10' }
hostname – Set System Hostname
# Set hostname
- name: Set server hostname
hostname:
name: web01.example.com
timezone – Set System Timezone
# Set timezone
- name: Set timezone to UTC
timezone:
name: UTC
# Set to specific timezone
- name: Set timezone to New York
timezone:
name: America/New_York
Utility Modules
wait_for – Wait for Conditions
# Wait for port to be available
- name: Wait for application to start
wait_for:
host: localhost
port: 8080
delay: 5
timeout: 300
state: started
# Wait for file to exist
- name: Wait for PID file
wait_for:
path: /var/run/app.pid
state: present
timeout: 60
# Wait for port to close
- name: Wait for service to stop
wait_for:
port: 8080
state: stopped
timeout: 120
# Wait for string in file
- name: Wait for application ready
wait_for:
path: /var/log/app.log
search_regex: "Application started"
timeout: 300
stat – Get File Information
# Check if file exists
- name: Check config file
stat:
path: /etc/app/config.ini
register: config_file
- name: Display file info
debug:
msg: |
Exists: {{ config_file.stat.exists }}
Is directory: {{ config_file.stat.isdir | default(false) }}
Size: {{ config_file.stat.size | default(0) }}
Mode: {{ config_file.stat.mode | default('N/A') }}
Owner: {{ config_file.stat.pw_name | default('N/A') }}
find – Find Files
# Find files by pattern
- name: Find old log files
find:
paths: /var/log
patterns: "*.log"
age: 30d
size: 100m
register: old_logs
# Find and delete
- name: Remove old logs
file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
when: old_logs.matched > 0
# Find files recursively
- name: Find all Python files
find:
paths: /opt/app
patterns: "*.py"
recurse: yes
register: python_files
set_fact – Set Variables
# Set runtime variable
- name: Calculate values
set_fact:
deployment_time: "{{ ansible_date_time.iso8601 }}"
total_memory_gb: "{{ (ansible_memtotal_mb / 1024) | round(2) }}"
app_version: "2.1.0"
# Cacheable fact (persists across plays)
- name: Set persistent fact
set_fact:
server_role: "webserver"
cacheable: yes
assert – Validate Conditions
# Validate system requirements
- name: Check system requirements
assert:
that:
- ansible_memtotal_mb >= 4096
- ansible_processor_vcpus >= 2
- ansible_distribution in ['Ubuntu', 'CentOS', 'RedHat']
fail_msg: "System does not meet minimum requirements"
success_msg: "All requirements met"
quiet: no
debug – Display Information
# Display variable
- name: Show variable value
debug:
var: ansible_hostname
# Display message
- name: Show custom message
debug:
msg: "Deploying to {{ inventory_hostname }}"
# Display complex data
- name: Show multiple values
debug:
msg: |
Server: {{ ansible_hostname }}
IP: {{ ansible_default_ipv4.address }}
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
Best Practices
1. Use Check Mode for Testing
# Test playbook without making changes
ansible-playbook playbook.yml --check
# Module that supports check mode
- name: Install package
apt:
name: nginx
state: present
check_mode: yes # Always run in check mode
2. Use become Appropriately
# At task level (recommended)
- name: Install package
apt:
name: nginx
become: yes
# At play level
- hosts: servers
become: yes
tasks: [...]
3. Register and Check Results
- name: Execute command
command: /usr/local/bin/check.sh
register: result
failed_when: result.rc not in [0, 1]
changed_when: "'changed' in result.stdout"
- name: Show result
debug:
var: result
4. Use Idempotent Modules
# Good - idempotent
- name: Ensure line in file
lineinfile:
path: /etc/hosts
line: "192.168.1.100 app.example.com"
# Bad - not idempotent
- name: Add line to file
shell: echo "192.168.1.100 app.example.com" >> /etc/hosts
Summary
Ansible modules provide comprehensive automation capabilities:
- File Modules: file, copy, template, lineinfile, blockinfile
- Package Modules: apt, yum, dnf, package, pip
- Service Modules: service, systemd
- User Modules: user, group, authorized_key
- Command Modules: command, shell, script, raw
- Archive Modules: archive, unarchive
- Web Modules: get_url, uri
- Git Module: Repository management
- Cron Module: Scheduled tasks
- System Modules: mount, sysctl, hostname, timezone
- Utility Modules: wait_for, stat, find, set_fact, assert, debug
Master these modules to build powerful, maintainable automation for any infrastructure.
Was this article helpful?
About Ramesh Sundararamaiah
Red Hat Certified Architect
Expert in Linux system administration, DevOps automation, and cloud infrastructure. Specializing in Red Hat Enterprise Linux, CentOS, Ubuntu, Docker, Ansible, and enterprise IT solutions.