Skip to main content
RunBook Academy

AnsibleVIII · Modules and the Module ModelThe module model

Check-mode support is a per-module property

Intermediate⏱ ~18 minansible-playbookansible-doc

What you'll learn

  • Look up a module check-mode support level and interpret full, partial, none and N/A
  • Read a check-mode recap and identify which tasks were evaluated and which were skipped
  • Explain why a command task with no creates guard is skipped rather than predicted
  • Assess before a change window whether a check run will prove anything

Prerequisites

Verified against ansible-core 2.21.x · ansible (community package) 14.x · Python (controller) 3.12+ · ansible-lint 26.x · Molecule 26.x · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL / Rocky / AlmaLinux 9.x · 2026-08-11

Not yet marked complete on this device.

--check is the closest thing Ansible has to a dry run, and it is not a property of Ansible. It is a property of each module, declared individually, and the modules that support it worst are the ones doing the work you most want to preview.

The consequence is specific and it is the point of this lesson: a play can produce a completely green check run in which half the tasks were never evaluated. Nothing in the output distinguishes “predicted no change” from “did not look”.

Four tasks, one check run

Here is a play with one task of each support level:

# checkmode.yml
- name: What check mode actually evaluates
  hosts: localhost
  gather_facts: false
  tasks:
    - name: A file task - check_mode support is full
      ansible.builtin.file:
        path: /etc/hostname
        state: file

    - name: A command with no creates - check_mode support is partial
      ansible.builtin.command: /bin/true

    - name: A command with creates - the guard makes check mode meaningful
      ansible.builtin.command: /bin/true
      args:
        creates: /etc/hostname

    - name: A raw task - check_mode support is none
      ansible.builtin.raw: /bin/true
Read-only / Safethe check run
$ ansible-playbook checkmode.yml --check
PLAY [What check mode actually evaluates] **************************************

TASK [A file task - check_mode support is full] ********************************
ok: [localhost]

TASK [A command with no creates - check_mode support is partial] ***************
skipping: [localhost]

TASK [A command with creates - the guard makes check mode meaningful] **********
ok: [localhost]

TASK [A raw task - check_mode support is none] *********************************
skipping: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

ok=2 changed=0 failed=0. On a dashboard, in a change request, or read quickly at the end of a long day, that is a clean run.

It is a clean run in which half the play was not evaluated. The skipped=2 is the entire signal, and it is the column nobody reads.

The support levels, precisely

LevelBehaviour in --checkExamples
fullThe module predicts and reports changed accurately without writing.file, copy, template, lineinfile, user, cron, apt, systemd_service
partialWorks only under a stated condition. Read the details line.command, shell, script, get_url, unarchive
noneThe task is skipped. Nothing is evaluated.raw, uri, expect, tempfile, wait_for
N/AThe module dispatches; ask the module it resolves to.package, service

In ansible-core 2.21 that is 52 modules at full, 8 at partial, 8 at none and 2 at N/A, out of 70 documented.

partial for command and shell means one specific thing

The details line in the attributes table states it exactly:

while the command itself is arbitrary and cannot be subject to the check mode semantics it adds creates/removes options as a workaround

And the module notes are more explicit still:

Check mode is supported when passing creates or removes. If running in check mode and either of these are specified, the module will check for the existence of the file and report the correct changed status. If these are not supplied, the task will be skipped.

So partial here is binary, not partial: with a guard, check mode works; without one, the task is skipped entirely. That is exactly what the two command tasks in the play above demonstrated — same module, same command, one ok and one skipping.

Read-only / Safeask before you run
$ ansible-doc -j ansible.builtin.raw | jq -r '.[].doc.attributes.check_mode.support'
none

raw has no check mode at all

raw bypasses the module subsystem entirely — it pushes a command down the connection with no Python and no JSON contract. There is nothing that could implement a prediction, so --check skips it silently.

This matters most in the one place raw is legitimately used: bootstrapping. A first play that installs Python with raw produces no check-mode information whatsoever, which is fine as long as you know it rather than discovering it.

Assessing a play before the change window

The question is not “does Ansible support check mode”. It is “for this play, on this fleet, what fraction of the tasks will --check actually evaluate?”

Read-only / Safeextract the modules a play uses
$ ansible-playbook --list-tasks site.yml
Read-only / Safereport support for each
$ for m in package template service command copy; do printf '%-10s %s\n' "$m" "$(ansible-doc -j ansible.builtin.$m | jq -r '.[].doc.attributes.check_mode.support')"; done
package    N/A
template   full
service    N/A
command    partial

Illustrative output

Then read the check run against that list. If the play has four command tasks and the recap says skipped=4, the check told you nothing about the four tasks that actually do the work.

Knowledge check

Knowledge check · 4 questions

  1. Q1. A --check run of a four-task play reports ok=2 changed=0 failed=0 skipped=2. What is the correct reading?

  2. Q2. Which of these will cause a task to be skipped during a --check run? Select all that apply.

  3. Q3. A module declaring check_mode: full is guaranteed by the Ansible toolchain not to modify the target during a check run.

  4. Q4. A read-only probe registers a version string that a later when: depends on. During a check run the whole play fails after the probe. What is the appropriate fix?

Passing score: 75%. Answers are checked in this browser.