Score an Ansible playbook's complexity from task count, roles and conditional logic.
This weighted score approximates cognitive and maintenance load: score = tasks×1 + roles×3 + conditionals×2 + loops×2 + handlers×1. Roles are weighted heaviest because each one pulls in its own tasks, defaults, vars and dependency graph; conditionals and loops are weighted above plain tasks because they multiply the number of execution paths a reader must trace mentally.
complexity = tasks × 1 + roles × 3 + conditionals × 2 + handlers × 1.5
A role isn't just one unit of work — it's an entire bundle of tasks, defaults, handlers and dependencies, so each role included in a playbook adds substantially more surface area to understand and maintain than a single task, which the ×3 weight reflects.
Look for opportunities to extract repeated task blocks into roles (paradoxically reducing playbook-level complexity even though it doesn't reduce total logic), replace deeply nested `when:` conditions with clearer role/host-group targeting, and add molecule tests to compensate for the harder-to-reason-about logic.
Not directly measured here, but the components it tracks (conditionals, loops, deep role graphs) are well-established complexity drivers in software generally, and Ansible playbooks are no exception — more branching logic means more paths to test and more ways for edge cases to slip through.
There's no universal target — track the score over time per playbook and treat a sudden jump as a signal to review, rather than chasing an absolute number.