Four states that do not replace each other
A long action raises at least four different questions: was it launched, did it finish, did it finish with the expected result, and did it leave the application ready? With async and poll: 0, the controller can proceed after launch without answering the remaining questions. Retain ansible_job_id and execution context to monitor that operation. A changed launch result does not measure final success. For a command whose contract requires rc=0, inspect the terminal result and exit status. Then check the relevant application function. Put these criteria in the change before the operational window rather than improvising acceptance during an outage.
Choose waiting and protect dependencies
With positive poll, execution monitors the task until it obtains a result or reaches the async limit. The poll interval is not a guaranteed work duration; async sets the allowed limit for that action. With zero poll, work can be launched and explicitly monitored later, but dependencies must be designed. Two steps using a package manager with an exclusive lock should not overlap merely because the controller received an identifier. Increasing forks or changing labels does not release the lock. Place a completion barrier before the dependent step and define what happens if monitoring fails.
Loss of observation and cleanup
If connectivity is lost or the cache cannot be found, do not conclude that the operation never ran. The process may have produced effects that outlive the controller. Collect the original identifier, correct user, and execution context, then reconcile persistent state before relaunching. Async_status mode: cleanup removes tracking cache; it is neither a cancellation request nor reversal of effects. In the inspected ansible-core 2.21.4 implementation, cleanup removes the file without waiting for the process. After validated completion, cleanup scoped to that identifier may be appropriate. First retain the evidence required for diagnosis and audit.
Accepted HTTP and the readiness contract
A check using ansible.builtin.uri must distinguish accepted HTTP status from the meaning of the returned document. If the endpoint documents ready, a 200 response with ready=false still does not confirm readiness. With Content-Type application/json, the json result is exposed independently of return_content; that parameter controls another aspect of body return. Define conditions for the expected structure and a waiting limit consistent with the window. Also verify application identity and generation when those belong to the local contract. Do not turn fictional examples into universal requirements: each application defines the signals that establish its ability to serve requests.
Isolated workshop and simulation limits
The lab launches only a local Python process that waits one second and writes fixture-complete. It queries the same identifier until completion, checks rc=0 and output, and cleans completed cache. A second part starts a temporary HTTP server on 127.0.0.1 returning JSON with ready=false. The assertion confirms HTTP 200 and lack of readiness without contacting external services. These four facts are laboratory observations, not production guarantees. URI has no check-mode support in the inspected documentation; a skipped rehearsal task did not test the endpoint. Actual checks require explicit scope and understood effects.
Summary for the change window
Write the decision flow before execution: launch, monitor, validate the command, observe function, and only then accept or proceed. For each transition, specify evidence, deadline, and owner. If partial failure occurs, retain known state and uncertainty rather than automatically repeating an action with persistent effects. Define cancellation and reversal through mechanisms appropriate to the operation; do not substitute cache cleanup. At handover, pass on the original identifier and outstanding criteria. Connect this lesson with serial execution, recovery, and observability, because technically completed execution can still require functional investigation.
# Conceptual sequence; the runnable fixture is in content/labs/ansible-execution.
# launch: async: 20, poll: 0, register: launched
# observe: async_status jid=launched.ansible_job_id
# wait until finished, then inspect failure and rc
# validate application readiness separately
# retain evidence, then clean this completed job's cacheA job can return an identifier immediately and remain active. An endpoint can return 200 with ready=false. Neither response alone accepts the change.
Common pitfalls
Confusing poll zero with completion; repeating a migration without reconciling effects; treating cache cleanup as cancellation; treating HTTP 200 as readiness.
Related topics: Inventory and execution context · Batch orchestration · Failures and recovery
An identifier starts monitoring. Acceptance requires the correct terminal result and a functional observation suited to the service.
Reference: Asynchronous actions and polling · Ansible community 14 / ansible-core 2.21 documentation consulted 2026-09-30; executor, collection and plugin compatibility requires confirmation