Puppet versus Ansible

Voor mijn MusicPlayers heb ik zowel Puppet als Ansible gebruikt, onafhankelijk van elkaar en ik zal proberen hier de pro’s en con’s van beide deployment methodieken uit de doeken te doen. Althans, voor zover ik heb gezien en van toepassing is op mijn projecten.

Agent en agent-less

Het eerste wat een verschil maakt is het feit dat Puppet met een agent werkt en Ansible niet. Om de Puppet-agent op een node te installeren is niet veel nodig maar het registreren op de Puppetmaster geschiedt middels de uitwisseling van ‘certificates’. Op zich niet erg, maar daarvoor moet wel de datum/tijd in orde zijn, dus de ntp-service dient gelijk met de puppet-agent geïnstalleerd te worden. Puppet ‘masterless’ laat ik hierbij buiten beschouwing.

Dedicated port

Het tweede waar je tegen aan loopt is de dedicated TCP/port (8140) van Puppet die gebruikt wordt tijdens de deployment. Deze dient dus opengezet te worden in het netwerk dat gebruikt wordt. Ansible gebruikt voor de deployment standaard de ssh-poort TCP/22. Vaak staat deze al open op het netwerk om in te kunnen loggen.

push versus pull

Eenmaal als het netwerk voor elkaar is en de agent geïnstalleerd, is er voor Puppet een server nodig, de PuppetMaster, van waaruit de scripts opgevraagd worden door de agent(s). Dit is de ‘pull‘-methode van Puppet. Omdat Ansible werkt met een ‘push‘-methode kunnen de Ansible script vanaf elke computer (laptop, server, desktop, macbook, etc…) gerund worden, zolang er maar ssh-toegang tot de node(s) is.

environments

Mede door het feit dat Puppet met een PuppetMaster werkt is het definiëren van ‘environments’ bij Puppet beter geregeld. Zeker als die environments overeenkomen met de branches op de GIT repository is dit prima beheersbaar. Binnen Ansible worden environments vaak bepaald in de structuur van de ‘inventory‘, een directory waar de nodes dan per omgeving ingesteld worden.

variabelen

Een lastig dingetje (voor mij?). In Ansible lijkt het vrij duidelijk, er zijn een aantal directories zoals ‘default’, ‘group_vars’, host_vars’, ‘vars’ om bestanden in te zetten met variabelen die dan weer in de playbooks gebruikt kunnen worden. In Puppet is dat anders en worden constanten gebruikt als variabelen. Wel is het zo dat voor beide ‘Configuration Management Tools‘ (CMT) geldt dat hieradata gebruikt kan worden om de code van de data te scheiden. Uiteraard kunnen zowel binnen ‘manifests‘ als binnen ‘playbooks‘ nieuwe te bepalen variabelen gebruikt worden. Ook de het ophalen/doorgeven van node-facts lijkt hetzelfde te werken.

modules

Voor Puppet is er de puppet-forge, voor Ansible de ansible-galaxy. Zoeken en hoogst waarschijnlijk is er al een module voor het doel dat je zoekt. Zoniet, dan kun je natuurlijk altijd je eigen module maken.

manifests en playbooks

In Puppet worden de classes in manifests bepaald middels een init.pp bestand waarbij meerdere manifests ‘genest’ kunnen worden m.b.v. include-statements. Dit is bij Ansible niet anders, playbooks worden (bij voorkeur) in roles bepaald middels een main.yml bestand en kunnen ‘genest’ worden m.b.v. include-statements.

Puppet heeft een ‘controle’ manifest die per node aangeeft welke manifests voor die bepaalde node gebruikt kan worden. Daarnaast is er ‘default’ om classes voor alle nodes in te zetten.

Ansible werkt ook met een ‘controle’ playbook en daarin staat dan voor welke node(s) de roles uitgevoerd zullen worden.

Het verschil zit ‘m in het feit dat je bij Ansible op de CLI vaak meegeeft voor welke nodes, of groep met nodes, je de playbooks wilt uitvoeren terwijl bij Puppet dit in de ‘control’ manifest is aangegeven omdat er door allerlei nodes een manifest opgevraagd kan worden.

PE / Tower

Voor Puppet is er een Puppet Enterprise versie, gratis tot 10 nodes, waarmee via een web-browser statistieken bekeken kunnen worden over de deployments. Voor Ansible is er net zoiets, Ansible Tower, echter niet gratis. (wel 14 dagen trial) Een ‘open source’ upstream project van Tower is AWX, echter vrij lastig om die te installeren. Een alternatief voor Ansible Tower/AWX is ARA, maar dit is veel beperkter in functies.

Conclusie

Het is lastig te zeggen of het één nou beter is dan het andere. Zowel Puppet als Ansible hebben als doel om een node te voorzien van packages, services, gebruikers, etc… en ze doen dit beiden op hun eigen manier. Ik neig een voorkeur te hebben voor Puppet, louter om het feit dat de agents voor mij de nodes in ‘desired state‘ houden, iets wat ik bij Ansible zelf moet doen of ik zou ‘ansible-pull‘ moeten gaan gebruiken m.b.v. scheduled taken. Ik neig ook een voorkeur te hebben voor Ansible omdat ik op de nodes niet hoef in te stellen, anders dan mijn ssh-toegang. Met Ansible kan ik op een  meer gecontroleerde manier één of meerdere onderdelen uit mijn deployment op één of meerdere nodes uit voeren. Dit kan met server aliases maar ook met tags.

Hoe dan ook, ik hou voorlopig beide tools actief en gebruik ze daar waar het mij het best uit komt: Ansible om een initiëlee setup van de nodes te doen (en om de puppet-agent te installeren) en Puppet om de configuraties te bewaken en indien nodig te herstellen. Happy DevOps!