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.

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?

R

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.