ArgumentSpec, Check Mode, Idempotency, and Diff¶
Section status: outline
This page is scoped but not yet written in full prose. The sections below define what it will cover. Build a Custom Module already demonstrates each of these in a working module — this page goes one level deeper on each piece.
What It Will Cover¶
argument_specfeatures beyondtype/required:choices,default,no_log=Truefor sensitive parameters,mutually_exclusive,required_together,required_if, sub-argument specs for nested dict parameters- Check mode internals:
module.check_mode, and why a module must explicitly branch on it rather than getting it "for free" - Idempotency patterns beyond a simple equality check: comparing computed hashes for large content, handling partial-match update-in-place logic, race conditions between the check and the act
- Diff mode: the
before/afterdict shapemodule.exit_json(diff=...)expects, and how it surfaces in--diffoutput module_utils: sharing logic across a family of related modules instead of duplicating it (the mechanism a real collection uses for its own custom modules — see Build a Collection From Zero)- Return value documentation: the
RETURNdocstring contract in full, including nested return structures
Common Mistakes¶
- Using
no_logonly on the task level and forgetting it belongs on theargument_specparameter itself for a custom module handling secrets. - A "check-then-act" idempotency check that's actually a race — state can change between the check and the write on a genuinely concurrent system, which is worth calling out even though most Ansible use cases (config management, not high-frequency systems) rarely hit it in practice.
Interview Questions¶
- What does
no_log=Trueon anargument_specparameter actually redact, and where? - How would you share validation logic across five related custom modules without duplicating it in each one?
Next¶
Continue to Build a Collection From Zero.