Ansible has done a great job by including out of the box modules for most commonly used resources like PostgreSQL, ec2, NTP etc. It provides users standard code base which can be evolved/forked by community members. Of course, one can create a completely independent module code base, but it's nice to have a standard/curated code base.
Puppet: It's really difficult to find quality modules on the Puppet forge. Sometimes modules can give a false configuration impression. For example, when I had tested PostgreSQL module, the database owner wasn't being set properly [1]. I agree this can happen with Ansible modules as well. Also, badly written community modules can cause dependency issues (e.g. user1-http module uses user1-iptables module, but you are already using user2-firewall module etc..). It can be difficult to find good Puppet modules.
Chef: I haven't explored it much, but found it too complicated compared with Puppet and Ansible.
Good to see tools that work as a system configuration framework and also allow command execution.
[ControlTier](http://www.controltier.org/) had (don't think it's actively developed now) options to execute general system commands, configure systems and application deployment. But it was fairly complex and required [ant](http://ant.apache.org/) skills.
Both Salt and Ansible look interesting. It's much easier to define system state using Ansible or Salt than Puppet.
However, I am not sure how would one use Ansible where VMs get launched dynamically (private cloud/virtualization fabric where devs can instantiate systems) and then receive their configuration without any manual steps.
For example, one can create kickstart/VM-images which get a hostname based on certain regex pattern, register with a Puppet master, the Puppet master auto-signs certs matching this specific hostname pattern and then client nodes receive their catalog. This is really useful pattern wherein systems pull their configuration state almost immediately after boot. It requires manual setup only while writing kickstart/VM-iamge profile and Puppet master configuration.
Ansible's SSH keys setup requires manual intervention, however, I think it can be automated using pre-defined keys in kickstart/VM-images. Haven't tried it yet though...