File Management

ansible.builtin.copy

- name: Copy file to remote
  ansible.builtin.copy:
    src: app.conf
    dest: /etc/app/app.conf
    owner: root
    group: root
    mode: '0644'
    backup: true

ansible.builtin.template

- name: Deploy config from template
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    mode: '0644'
  notify: restart nginx

ansible.builtin.file

# Create directory
- ansible.builtin.file:
    path: /opt/app/logs
    state: directory
    owner: app
    mode: '0755'

# Create symlink
- ansible.builtin.file:
    src: /opt/app/current
    dest: /opt/app/latest
    state: link

# Delete file
- ansible.builtin.file:
    path: /tmp/old-file.txt
    state: absent

ansible.builtin.lineinfile

- name: Ensure line in file
  ansible.builtin.lineinfile:
    path: /etc/hosts
    line: '192.168.1.10 myserver'
    state: present

- name: Replace line matching regex
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    line: 'PermitRootLogin no'

ansible.builtin.blockinfile

- name: Add block to file
  ansible.builtin.blockinfile:
    path: /etc/nginx/nginx.conf
    block: |
      upstream backend {
          server 10.0.0.1:8080;
          server 10.0.0.2:8080;
      }
    insertbefore: 'server {'

ansible.builtin.fetch

- name: Download file from remote
  ansible.builtin.fetch:
    src: /var/log/app.log
    dest: /tmp/logs/{{ inventory_hostname }}/
    flat: true

ansible.builtin.stat

- name: Check if file exists
  ansible.builtin.stat:
    path: /etc/app/config.yml
  register: config_file

- name: Create default config
  ansible.builtin.copy:
    src: default-config.yml
    dest: /etc/app/config.yml
  when: not config_file.stat.exists

ansible.builtin.find

- name: Find log files older than 7 days
  ansible.builtin.find:
    paths: /var/log/app
    patterns: '*.log'
    age: 7d
  register: old_logs

- name: Delete old logs
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ old_logs.files }}"

ansible.builtin.unarchive

- name: Extract tarball
  ansible.builtin.unarchive:
    src: app-v2.tar.gz
    dest: /opt/app/
    remote_src: false  # src is on controller

ansible.builtin.synchronize

- name: Rsync directory
  ansible.posix.synchronize:
    src: /local/app/
    dest: /remote/app/
    delete: true
    rsync_opts:
      - "--exclude=.git"

Package Management

ansible.builtin.apt (Debian/Ubuntu)

- name: Install packages
  ansible.builtin.apt:
    name:
      - nginx
      - python3-pip
      - git
    state: present
    update_cache: true
    cache_valid_time: 3600

ansible.builtin.yum (RHEL/CentOS)

- name: Install packages
  ansible.builtin.yum:
    name:
      - httpd
      - python3
    state: latest

ansible.builtin.dnf (Fedora/RHEL 8+)

- name: Install packages
  ansible.builtin.dnf:
    name:
      - podman
      - buildah
    state: present

ansible.builtin.pip

- name: Install Python packages
  ansible.builtin.pip:
    name:
      - flask
      - gunicorn
    virtualenv: /opt/app/venv
    virtualenv_python: python3

ansible.builtin.package (OS-agnostic)

- name: Install package (any OS)
  ansible.builtin.package:
    name: git
    state: present

Service Management

ansible.builtin.service

- name: Start and enable nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true

ansible.builtin.systemd

- name: Restart and daemon-reload
  ansible.builtin.systemd:
    name: myapp
    state: restarted
    daemon_reload: true
    enabled: true

User & Group Management

ansible.builtin.user

- name: Create user
  ansible.builtin.user:
    name: deploy
    groups: sudo,docker
    shell: /bin/bash
    create_home: true
    generate_ssh_key: true
    ssh_key_type: ed25519

ansible.builtin.group

- name: Create group
  ansible.builtin.group:
    name: appgroup
    gid: 1500
    state: present

ansible.posix.authorized_key

- name: Add SSH key
  ansible.posix.authorized_key:
    user: deploy
    key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
    state: present

Command Execution

ansible.builtin.command

- name: Run command (no shell features)
  ansible.builtin.command: /opt/app/healthcheck.sh
  register: result
  changed_when: false

ansible.builtin.shell

- name: Run with shell features (pipes, redirects)
  ansible.builtin.shell: |
    cat /var/log/app.log | grep ERROR | wc -l
  register: error_count
  changed_when: false

ansible.builtin.raw

- name: Run on host without Python
  ansible.builtin.raw: apt-get install -y python3
  become: true

ansible.builtin.script

- name: Run local script on remote
  ansible.builtin.script: scripts/setup.sh
  args:
    creates: /opt/app/.installed

ansible.builtin.expect

- name: Interactive command
  ansible.builtin.expect:
    command: passwd deploy
    responses:
      "New password:": "SecureP@ss123"
      "Retype new password:": "SecureP@ss123"

System

ansible.builtin.cron

- name: Add cron job
  ansible.builtin.cron:
    name: "daily backup"
    minute: "0"
    hour: "2"
    job: "/opt/backup.sh >> /var/log/backup.log 2>&1"
    user: root

ansible.builtin.hostname

- name: Set hostname
  ansible.builtin.hostname:
    name: web01.example.com

ansible.builtin.reboot

- name: Reboot and wait
  ansible.builtin.reboot:
    reboot_timeout: 600
    msg: "Rebooting for kernel update"

ansible.builtin.sysctl

- name: Set kernel parameter
  ansible.posix.sysctl:
    name: net.ipv4.ip_forward
    value: '1'
    sysctl_set: true
    reload: true

ansible.builtin.mount

- name: Mount NFS share
  ansible.posix.mount:
    path: /mnt/data
    src: nfs-server:/exports/data
    fstype: nfs
    opts: rw,sync
    state: mounted

Networking & Web

ansible.builtin.uri

- name: Call API
  ansible.builtin.uri:
    url: https://api.example.com/deploy
    method: POST
    body_format: json
    body:
      version: "{{ app_version }}"
    headers:
      Authorization: "Bearer {{ api_token }}"
    status_code: [200, 201]
  register: api_response

ansible.builtin.get_url

- name: Download file
  ansible.builtin.get_url:
    url: https://releases.example.com/app-v2.tar.gz
    dest: /tmp/app-v2.tar.gz
    checksum: sha256:abc123...
    mode: '0644'

ansible.builtin.wait_for

- name: Wait for port 8080
  ansible.builtin.wait_for:
    port: 8080
    host: "{{ ansible_host }}"
    delay: 5
    timeout: 300

Variables & Facts

ansible.builtin.set_fact

- name: Create dynamic variable
  ansible.builtin.set_fact:
    app_url: "https://{{ ansible_hostname }}.example.com"
    cacheable: true

ansible.builtin.debug

- ansible.builtin.debug:
    msg: "Deploying {{ app_version }} to {{ inventory_hostname }}"

- ansible.builtin.debug:
    var: ansible_distribution

ansible.builtin.setup

- name: Gather only network facts
  ansible.builtin.setup:
    gather_subset:
      - network

ansible.builtin.include_vars

- name: Load environment-specific vars
  ansible.builtin.include_vars:
    file: "{{ env }}.yml"

ansible.builtin.pause

- name: Wait for confirmation
  ansible.builtin.pause:
    prompt: "Press Enter to continue deployment"

- name: Wait 30 seconds
  ansible.builtin.pause:
    seconds: 30

Task Control

ansible.builtin.assert

- name: Validate configuration
  ansible.builtin.assert:
    that:
      - ansible_memtotal_mb >= 2048
      - ansible_distribution == "Ubuntu"
    fail_msg: "Server doesn't meet requirements"
    success_msg: "All checks passed"

ansible.builtin.fail

- name: Fail if disk is full
  ansible.builtin.fail:
    msg: "Disk usage above 90%!"
  when: disk_usage | int > 90

ansible.builtin.meta

- name: Flush handlers now
  ansible.builtin.meta: flush_handlers

- name: End play for this host
  ansible.builtin.meta: end_host
  when: skip_host | default(false)

- name: Clear facts cache
  ansible.builtin.meta: clear_facts

ansible.builtin.include_tasks

- name: Include OS-specific tasks
  ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml"

ansible.builtin.import_role

- name: Apply role
  ansible.builtin.import_role:
    name: geerlingguy.docker
  vars:
    docker_edition: ce

Cloud & Containers

ansible.builtin.docker_container (community.docker)

- name: Run container
  community.docker.docker_container:
    name: webapp
    image: myapp:latest
    ports:
      - "8080:80"
    env:
      DB_HOST: "{{ db_host }}"
    restart_policy: unless-stopped

ansible.builtin.git

- name: Clone repository
  ansible.builtin.git:
    repo: https://github.com/example/app.git
    dest: /opt/app
    version: main
    force: true

Conclusion

This cheat sheet covers the 50 most used Ansible modules. Bookmark it for quick reference. For full documentation on any module, run ansible-doc module_name.