Infrastructure as code met Vagrant

 
22 april 2014

DevOps en ‘infrastructure as code’

Er is een nog steeds groeiende aandacht voor de DevOps werkwijze. De essentie van DevOps ligt in hoe je een organisatie qua processen en cultuur inricht om de development en operations activiteiten goed met elkaar te laten samenwerken. Dit met als hoger doel om op een flexibele en robuuste manier je IT op je business te laten aansluiten (of beter nog, de IT als business driver te laten fungeren). Eén van de technisch component binnen het DevOps verhaal is ‘infrastructure as code’ waarbij infrastructuurconfiguratie in code wordt vastgelegd zodat deze configuratie beheerbaar en herhaalbaar wordt. Vagrant is een tool die daarmee kan helpen.

Als software ontwikkelaars zijn we al bedreven in het automatiseren van dingen. Repeterende taken die we moeten uitvoeren zijn vaak al geautomatiseerd. Bijvoorbeeld het builden van software (make, ant, msbuild, Fake), het testen van de software (Junit, Selenium, Cucumber) en het deployen van software (Jenkins, GO).

Wat veelal nog handmatig gebeurt is het inrichten van de servers waarop de software die we bouwen draait en het inrichten van je ontwikkelmachine om aan de software te werken. Zoals de meeste handmatige processen is dit vaak een slecht herhaalbaar proces waardoor er verschillen kunnen optreden tussen de inrichting van verschillende servers binnen een omgeving over over omgevingen heen (denk aan een OTAP inrichting). Een ander symptoom is dat nieuwe developers op een project een dag kwijt zijn om ‘het project draaiend te krijgen’ op hun werkstation. Vanuit de ‘infrastructure as code’ gedachte wordt de serverinrichting geautomatiseerd zodat ook dit herhaalbaar proces wordt.

Vagrant is een tool die hier, met name tijdens het ontwikkelproces, een rol in kan spelen. Met Vagrant kun je een complete (multi server) infrastructuuropzet definieren in een configuratiefile zodat elke ontwikkelaar een gelijke gescripte omgeving krijgt om de ontwikkelde software in te draaien.

Verschillende lagen in infrastructuur

Bij infrastructuur hebben we het over alles wat niet direct de software is die we ontwikkelen. Een voorbeeld: Stel je ontwikkelt een ASP.Net website (genaamd MySite) die gebruik maakt van een MySQL database (genaamd MyDB). Als ik een nieuwe versie oplever bestaat dit uit de files en dll’s van de website en een opzet/migratie script voor de database. Om dit te laten draaien hebben we het volgende nodig

Een webserver en een database (Software). Deze draaien op een OS wat geinstalleerd is op een server en die draait binnen een bepaalde server container (bijv. vmware, AWS of virtualbox). Zie Figuur 1.

figuur1

Figuur 1: Infrastructuur lagen

Voor elk van deze componenten geld dat er verschillende dingen geconfigureerd moeten worden, versie van een OS, bepaalde features die aan moeten staan, user en service accounts, MSMQ, databaseusers, configuratie van de webserver, rechten op van alles en nog wat, dimensionering van je servers (CPU, geheugen). Pas als al deze dingen ingericht zijn ben je er aan toe je software te installeren en te draaien.

Vagrant

Met Vagrant kun je een complete virtuele infrastructuur op je werkstation geautomatiseerd opzetten. Kort door de bocht gaat dit als volgt:

  • Je installeert een virtualisatieplatform zoals hyper-v of virtualbox
  • Je installeert Vagrant
  • Je creeert een Vagrant configuratiefile waarin je de servers en de inrichting definieert
  • Je start Vagrant op (Vagrant up) en die zorgt ervoor dat op basis van de configuratiefile de servers worden opgestart en ingericht.

Het belangrijkste aspect hierin is de Vagrant configuratiefile. Doordat je complete server opzet gedefinieerd is in een configuratiefile kun je deze eenvoudig delen met anderen en zelf onder versiebeheer hangen.

Deze opzet heeft een aantal voordelen.

1. De footprint die je nodig hebt om te starten is zeer beperkt en onafhankelijk van wat je ontwikkeld. Je installeert virtualbox en Vagrant en haalt de Vagrant configuratiefile uit versiebeheer en je kunt starten. Ongeacht hoe complex de uiteindelijke serveromgeving ook is.

2. Herhaalbaarheid. Omdat de complete opzet gescript is krijg je altijd exact dezelfde omgeving.

3. De code is de documentatie en klopt altijd. Bij handmatige installaties heb je (als het goed is) een handleiding die beschrijft hoe de installatie te doen. Maar het gebeurd niet zelden dat handleidingen niet actueel gehouden worden of dat er details missen. Als alles in configuratie/code is vastgelegd dan is dat direct de documentatie en deze is altijd 100%.

4. Complexiteit maar één keer Al maak je gebruik van meerdere servers, obscure software en heb je een complex autorisatiemodel met service accounts, ‘double hop kerberos delegation’, etc. Als je de opzet eenmaal in de configuratiefile hebt dan heb je daar geen last meer van als je nieuwe omgevingen inricht of er nieuwe developers bij komen.

De opzet van Vagrant

Binnen Vagrant zijn er vier onderdelen belangrijk.

  • De provider: dit is de virtualisatie oplossing waar alles uiteindelijk op draait. Standaard wordt virtualbox gebruikt. Maar er is ook ondersteuning voor o.a. VMWare workstation, AWS en MS HyperV.
  • De basebox: De server en het OS worden niet van de grond af aan geinstalleerd maar er wordt altijd uitgegaan van een voorgeinstalleerd server image (de basebox). Je kunt deze zelf maken (http://docs.vagrantup.com/v2/virtualbox/boxes.html) of een voorgebakken box gebruiken (https://vagrantcloud.com/)
  • De provisioner: Als je een basebox hebt uitgekozen en deze kan draaien op een provider dan moet deze nog afgeconfigureerd worden en moet er nog software op geinstalleerd worden. Vagrant doet dit niet zelf maar werkt samen met een aantal standaard provisioning oplossingen. Zo kun je o.a. Puppet en Docker gebruiken (http://Puppetlabs.com/, https://www.docker.io/). Maar je kunt ook simpele shell commando’s uitvoeren.
  • De Vagrantfile Dit is de configuratie file die alles aan elkaar knoopt. Hierin configureer je welke provider je gebruikt, welke basebox, welke provisioner en hoe de provisioner aangeroepen moet worden.

Een voorbeeld

Een klein voorbeeld om te zien hoe dit werkt. We gebruiken hiervoor niet het voorbeeld van een stukje terug met meerdere servers en linux en windows door elkaar maar een wat eenvoudigere opzet.

We hebben een (extreem) simpele NodeJS Express applicatie (alleen een app.js en een package.json)

  • Die laten we draaien op een virtuele Linux server (de guest) op mijn werkstation (de host)
  • We zorgen er voor dat NodeJS op de virtuele linux server wordt geinstalleerd en dat die de applicatiefiles serveert vanaf mijn eigen PC. Op deze manier kan ik eenvoudig wijzigingen maken aan de sourcefiles op mijn eigen werkstation

Hoe zetten we dit op met Vagrant:

  • We maken gebruik van een bestaande Ubuntu basebox die we laten draaien op virtualbox.
  • We gebruiken Puppet om er voor te zorgen dat NodeJS, NPM en express hierop geinstalleerd worden.
  • We zorgen er met Puppet voor dat NodeJS opgestart wodt met Upstart
  • We gebruiken forever (https://github.com/nodejitsu/forever) om ervoor te zorgen dat NodeJS geherstart wordt als er iets wijzigt aan de sourcefiles
  • We zorgen er voor dat de NodeJS server de files serveert vanaf een fileshare die verwijst naar mijn eigen PC

De twee belangrijkste files zijn de vagrantfile en de Puppet configuratie.

Stap 1. De Vagrant file

De eerste stap is het configureren van de vagrantfile. Figuur 2 toont de vagrantfile die we gebruiken. We zien in het eerste blok dat we als basebox hashicorp/precise64 gebruiken (https://vagrantcloud.com/hashicorp/precise64, een standaard ubuntu image met o.a. Puppet al voorgeinstalleerd). We geven hem een private networkadres met IP 192.168.56.10.

Daarna volgt in blok 2 de configuratie van de provider (in dit geval de default, virtualbox). Hier zetten we v.gui = true zodat de virtuele machine met GUI wordt opgestart. Default draait deze headless.

In blok 3 configureren we een shell provisioner. Deze gebruiken we om een inline shell script uit te voeren op de virtuele machine waarmee een aantal Puppet modules worden geinstalleerd die we later nodig hebben.

In blok 4 configureren we vervolgens de Puppet provisioner waarbij we aangeven in welke folder ons Puppet manifest staat en wat het manifest file is.

Figuur 2. Vagrantfile
Figuur 2: Vagrantfile

Stap 2. De Puppet configuratie

In stap één hebben we met Vagrant er voor gezorgt dat we een virtuele machine hebben draaien en hebben we met de shell provisioner er voor gezorgt dat er enkele Puppet modules zijn geinstalleerd en als laatste hebben we de Puppet provisioner afgetrapt. Met Puppet instaleren en configureren we de NodeJS server.

Figuur 3 toont het Puppet manifest dat we gebruiken. We zorgen er eerst voor dat er een ‘apt-get update’ wordt gedraait (1). Hierna is gedefinieerd dat NodeJS geinstalleerd moet zijn (2). Vervolgens definieren we dat de NPM packages express (3) en forever (4) geinstalleerd moeten zijn.

Bij 5 definieren we dat er een symlink gemaakt moet worden van /opt/node naar /Vagrant/files/webapp. Dit zorgt ervoor dat nodejs straks de files serveert vanaf mijn PC (/Vagrant is een default fileshare die Vagrant aanmaakt vanaf je virtuele machine naar de folder waarin je Vagrant hebt opgestart)

Bij 6 zorgen we er voor dat de upstart configuratie die we hebben om onze NodeJS applicatie op te starten aanwezig is in /etc/init en in stap 7 definieren we dat de upstart service moet lopen.

Figuur 3. Puppet manifest
Figuur 3: Puppet manifest

Zelf proberen

Wil je dit in actie zien? Installeer dan Virtualbox 4.3.8 https://www.virtualbox.org/wiki/Download_Old_Builds_4_3 (4.3.10 werkt niet) en installeer Vagrant http://www.vagrantup.com/downloads.html. De files van het voorbeeld kun je uit github halen https://github.com/arnodenuijl/VagrantDemo. Ga vervolgens met een command prompt naar de root folder van de VagrantDemo en run eerst Vagrant plugin install Vagrant-vbguest (éénmalig) en vervolgens Vagrant up. Als alles goed gaat dan wordt het baseimage opgehaald en wordt deze ingericht. Als alles klaar is kun je naar http://192.168.56.10:3000/ en zie je als het goed is de tekst Welcome to my super nice nodejs app.

Rozengeur en maneschijn….

Vagrant is een uitermate gaaf en krachtig stuk technologie en de mogelijkheden strekken ver. Het is technologie die op zijn minst aan de rand staat van ons vakgebied en steeds meer hier binnen komt. Tijdens het typen van dit stuk hoor ik twee collega’s features, vinkjes en rechten op de laptop vergelijken om te achterhalen waarom een project bij de één wel draait en bij de ander niet, dus er is wel een behoefte.

Maar het werken met Vagrant heeft wel een leercurve. Vagrant en de configuratie an sich vallen wel mee maar dat is maar een deel van het verhaal. Voor het afconfigureren kom ja al snel bij Puppet of Chef terecht en dat heeft al weer zijn eigen (best stijle leercurve). En voor zowel Vagrant als Puppet geld dat de ondersteuning voor Windows beperkt is. Het werkt wel, maar je merkt aan alles dat de grootste groep gebruikers uit de Linux wereld komt. Maar laat dat je niet weerhouden hier mee aan de slag te gaan.

[[ In de interne nieuwsbrief van Sogyo schrijf ik, onder de titel ‘gave technologie’, over technologiën waar ik enthousiast over ben en waarvan ik vind dat iedere collega op zijn minst moet weten dat het bestaat. Dit artikel komt uit de Sogyo Nieuwsbrief van maart 2014 ]]


Werken met ?
Kijk dan bij onze mogelijkheden voor starters en/of ervaren IT'ers.


Categorieën: Project- & procesmanagement, Architectuur, Development, Deployment