Can check mode be trusted when a playbook mixes core and third-party Ansible modules?
0 reputation · 21 Apr 2024, 09:28 UTC
0 reputation · 21 Apr 2024, 09:28 UTC
I want to validate an Ansible playbook against a staging inventory before any real run, using ansible-playbook --check --diff so nothing is actually modified. The playbook mixes core modules (template, service, package) with a few third-party collection modules that manage an external API.
My understanding is that each module decides whether it honors check mode via its supports_check_mode declaration, and modules that do not support it are skipped rather than executed. That raises a concern: a skipped task means later tasks using when conditionals or registered variables from that task may fail or evaluate differently than they would in a real run, making the simulation misleading.
Assume Ansible core 2.15+ with collections installed from Ansible Galaxy.
--check before running it?when conditions still evaluate predictably?--check combined with --diff still report accurate pending changes when earlier tasks in the play were skipped?No, check mode cannot be fully trusted when mixing core and third-party modules. While core modules are generally reliable, third-party collection modules vary in their implementation of supports_check_mode. If a module does not support check mode, Ansible skips the task entirely. This creates a "simulation gap" where the state of the system is not updated in memory, and registered variables reflect a skip rather than a predicted change, potentially misleading downstream logic.
When a task is skipped during a --check run, the registered variable is not left undefined; instead, it is populated with {"skipped": true, "changed": false}. This leads to two primary risks:
when: previous_task.changed will evaluate to false during a check run, even if the task would have actually caused a change during a real run.--diff flag only reports changes for modules that actually execute. If a task is skipped, no diff is generated. Furthermore, because check mode does not persist changes, subsequent tasks that depend on the output of a skipped task (e.g., a file created by a skipped template) will report diffs based on the current state of the system, not the simulated state.To maintain predictability when using third-party modules that may be skipped, use the following patterns:
There is no single command to list all skipped tasks before execution. You must verify support per module using ansible-doc:
ansible-doc -t module collection_name.module_name
Look for the "Supports check_mode" field in the documentation.
Avoid basing critical logic solely on .changed if the preceding module is third-party. Instead, use a default value or a check for the skipped key:
- name: API Task
collection.name.module:
state: present
register: api_result
- name: Downstream Task
debug: msg="Executing because change is predicted or simulation is active"
when: api_result.changed or api_result.skipped | default(false)
changed_when for ConsistencyIf a module's check mode behavior is inconsistent, explicitly define when it should be considered "changed" to force the registered variable into a known state for downstream tasks.
ansible-playbook --check --diff and specifically look for skipping messages in the output.- debug: var=your_registered_var immediately following a third-party module to verify if it returns skipped: true.--check run against a real run on a disposable staging target to identify discrepancies in task execution flow.Diagnostic Detail Required: Are the third-party modules performing read-only API calls to determine state, or are they entirely opaque to Ansible's check mode?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.