Deciding which tasks run on which host, looping a task over a list, recovering when a step fails, overriding what counts as failure or change, and carving a playbook into selectable phases. Conditionals, loops, blocks, failure control, tags, and the static-versus-dynamic split between import and include.
6 topics
A playbook with no control flow runs every task on every host, in order, no matter what — which is fine until reality intrudes. Real fleets are heterogeneous, real changes can fail partway, and a real playbook grows to sixty tasks you do not always want to run end to end. This chapter is the machinery that turns a flat task list into something that decides, repeats, recovers, and selects.
Six topics, building on the Larkspur web stack. Conditionals gate a task per host with when; loops run one task over a list; blocks give you try/except/finally; failure control rewrites what Ansible calls a failure or a change; tags let you run just the deploy or just the config; and the import-versus-include split — the most confused pair in Ansible — decides whether content is inlined at parse time or pulled in at run time, which changes how tags, loops, and when behave.