So Ansible has the disadvantage of unclear, implicit dependencies.
The undeterministic declarative system (Puppet) has the disadvantage of unclear, missing dependencies.
I would prefer a deterministic system, so that I can validate the output by automated acceptance tests. Preferably, these tests also take into account the various upgrade paths (new->head and head^->head)
I've seen this a lot of times when working with chef already. Someone moves a very trivial thing to a different place, or adds/moves a notification - current system works, clean deployment works, ... but current system will fail on the next reboot or package update that cascades in an unpredictable series of events. Unless you explicitly list all existing dependencies, the system is very fragile and sensitive to modifications. I agree that most people deploying a single-server webapp will never run into this, notice the problem, or even care about it. When deploying a multi-host, minimal-downtime infrastructure it becomes a problem though.
I can appreciate the simple chef/ansible way of provisioning things, but starting with some size I think that explicit dependencies are the only way to go. Puppet/salt allow me to do things that are quite hard to do in chef.