Puppet works so well, Ansible seems like a typical "not invented here" tragedy that frequently occurs in open source. Rather than coalesce around something that works and has years of experience and knowledge and bug fixing sunk into it, people create something from scratch.
To be specific, this is Ansible:
- name: Memcached
template:
src=$repository_basedir/memcached/templates/memcached.conf.j2
dest=/etc/memcached.conf
owner=root group=root mode=0644
notify:
- memcached-restart
The same in Puppet: file {
'/etc/memcached.conf':
content => template('memcached/memcached.conf'),
owner => root,
group => root,
mode => '0644',
notify => Service['memcached'];
}
It's literally the same data expressed here.Puppet has very little abstraction. But what you do get, which Ansible has not really understood, I think, is a data model. The above results in the graph getting an object File['/etc/memcached.conf'] which can be referred to. I can do this:
service {
'memcached':
require => File['/etc/memcached.conf'];
}
This in turn creates the graph node Service['memcached']. It takes part in a larger graph that looks like this: Stage[main]/Node[myserver]/Service['memcached']
In fact, manifests are all compiled into a large graph like this, with interdependencies between the nodes. The logic-based, Prolog-type language in the OP's link is precisely what Puppet builds underneath.Likewise, the graph model is extensible. I can invent a new object like so:
define public_key() {
file {
"/home/$name/.ssh/authorized_keys":
content => "$key";
}
}
public_key {
'someuser':
key => 'some public key';
}
account {
'someuser':
require => PublicKey['someuser'];
}
Here, the define public_key() actually defines a new type of object that can be instantiated in scripts. When one is instantiated, other objects can be depend on it. This allows me to encapsulate stuff in my scripts; rather than having other declarations depend on the internal details of how a public key is stored (ie., in a home directory), they depend on my definition.Ansible may look simpler on the surface, but I think it's all surface. When you have learned to use Puppet, it becomes simple. Ansible looks to me like the product of a person who looked at Puppet, said something like "ugh Ruby, ew syntax" and made his own thing, without looking deeper. Simialrly, Ansible appeals to people who look at Puppet with the same reaction, again without looking deeper. The irony is that they are buying into something that is arguably poorer.
That said, I would argue that part of the problem is Puppet's documentation, which surely must drive people to "poor man's Puppet" solutions. (The cynic in me wonders if Puppet's poor documentation is a deliberate ploy on part of Puppet Labs to boost their consulting business.)