Horses for courses, it depends on what you're doing, but I've built Multi-£Bn production systems for the last decade on Puppet then Chef then Ansible (and now none of those) and I can't say that Ansible is very buggy these days nor does it fail at complexity. I mean, we found that provisioning with Packer using Ansible as the engine worked perfectly fine, nothing to do with PR material. Newer definitely isn't better, I would always go with reliable, battle-tested tech, but the old ways are largely pointless for most clients and developers who have long left behind artisan infrastructure. If tons of complexity is needed that baffles Ansible/Salt etc, I would be looking at the architects askew TBH...
At my employer, we use a sensible bi-modal approach, where every machine gets a base configuration applied through Puppet, and we consider this The Platform, and any per-machine (or per-use-case) changes should be applied through an Ansible repo.
Puppet lays down those things that the platform "promises"* to provide - syslog, time, auth, DNS, etc, and Ansible does application-specific things.
* - Not a strict promise in the Mark Burgess "Promise Theory" sense, but similar in thought.