I have worked with nightmarishly complicated Ansible playbooks and roles designed to provide declarative infrastructure when it didn't exist in a module. If all you had to change was a group_vars setting, you could be confident in your change. But if you had to edit a role, playbook or task, nobody was sure if it would break something in the future or not. It was much less robust than a real module because it was just the DSL.
With a Python DSL you could write code that was declarative, but because the language is complex, lexing is more difficult, and simple changes to configuration become more error-prone.
By moving to images and containers, the majority of configuration management is now largely unnecessary. We will always need a CM tool, but they should give users less rope to hang themselves with, not more.