100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
DevOps

Tasks and Modules

Understand how Ansible tasks invoke modules to perform idempotent actions, and how to choose the right module for the job.

Playbooks & TasksBeginner9 min readJul 10, 2026
Analogies

Anatomy of a Task

A task is the smallest unit of work in a playbook: it has a human-readable 'name' and calls exactly one module with a set of parameters. The module — such as ansible.builtin.apt, ansible.builtin.copy, or ansible.builtin.service — does the actual work on the target host, and Ansible reports back whether that task resulted in a change ('changed'), no change needed ('ok'), or a failure ('failed').

🏏

Cricket analogy: A task is like a single ball bowled in an over: the module is the specific delivery type (yorker, googly), the parameters are line and length, and the umpire's call afterward mirrors Ansible reporting changed, ok, or failed.

Idempotency and Common Modules

Well-written Ansible modules are idempotent: running the same task repeatedly produces the same end state without side effects, and Ansible only reports 'changed' the first time the desired state is actually applied. This is why modules like ansible.builtin.apt (state: present) or ansible.builtin.file (state: directory) are preferred over the ansible.builtin.command or ansible.builtin.shell modules, which execute raw commands and have no built-in awareness of whether the system already matches the desired state.

🏏

Cricket analogy: Idempotency is like DRS reviewing the same delivery twice — the outcome (out or not out) doesn't change no matter how many times you re-check it, unlike a raw shell command that just re-bowls blindly.

yaml
tasks:
  - name: Install required packages (idempotent)
    ansible.builtin.apt:
      name:
        - git
        - curl
        - python3-pip
      state: present

  - name: Ensure application directory exists
    ansible.builtin.file:
      path: /opt/myapp
      state: directory
      owner: appuser
      group: appuser
      mode: '0755'

  - name: Run a one-off migration script (not naturally idempotent)
    ansible.builtin.command: /opt/myapp/bin/migrate.sh
    args:
      creates: /opt/myapp/.migrated

command vs. shell, and Finding the Right Module

ansible.builtin.command runs a program directly without invoking a shell, so it cannot use pipes, redirects, or environment variable expansion, but it is safer against shell injection. ansible.builtin.shell runs the command through /bin/sh, enabling pipes and redirection at the cost of that safety. In almost every case, checking 'ansible-doc -l' for a purpose-built module (git, mysql_db, systemd, user, cron, etc.) is better than reaching for command or shell, because purpose-built modules handle idempotency, error checking, and check-mode support for you.

🏏

Cricket analogy: Choosing command over shell is like a batter using a defensive block against a tricky delivery instead of trying a risky reverse-sweep — command avoids the 'shell injection' equivalent of getting caught off a mistimed shot.

Avoid ansible.builtin.shell and ansible.builtin.command for anything that has a dedicated module (package installs, service management, file operations, user management). Raw shell tasks are not idempotent by default, can fail silently on repeated runs, and don't support check-mode diffs the way real modules do — use 'creates' or 'changed_when' if you must use them.

  • A task pairs a name with exactly one module call and its parameters.
  • Modules report changed, ok, or failed after execution.
  • Idempotent modules produce the same end state regardless of how many times they run.
  • command runs without a shell (no pipes/redirects); shell runs via /bin/sh (supports them but less safe).
  • Prefer purpose-built modules (apt, file, service, user, git, etc.) over command/shell whenever one exists.
  • Use 'ansible-doc -l' and 'ansible-doc <module>' to discover and inspect available modules.
  • Use 'creates' or 'changed_when' to give command/shell tasks idempotent-like behavior when unavoidable.

Practice what you learned

Was this page helpful?

Topics covered

#DevOps#AnsibleStudyNotes#TasksAndModules#Tasks#Modules#Anatomy#Task#StudyNotes#SkillVeris#ExamPrep