Recap Tech Talk Next Level Ansible
In navolging van Ansible Automates 2019 werd er op 17 februari ‘Tech Talk Next Level Ansible’ georganiseerd. Tijdens Ansible Automates gaf Maxim Burgerhout een ijzersterke demo waarbij een Enterprise multi-cloud omgeving werd opgezet met Ansible Tower. Sprekers Maxim Burgerhout en Fred van Zwieten van Red Hat gaven ons tijdens de Tech Talk een kijkje onder de motorkap van deze live-demo voor zowel Windows als Linux. In deze blog geef ik een verslag van deze demo’s en neem ik je mee in de opmerkelijke verschillen tussen beiden.
Aan de slag met Ansible Tower & Linux
Maxim Burgerhout trapt de middag af en neemt ons mee in de techniek achter zijn demonstratie. Het uiteindelijke doel? Een Enterprise multi-cloud omgeving, met Linux als besturingssysteem, opzetten met Ansible Tower waarin de verschillen tussen de diverse cloud providers worden platgeslagen tot een uniforme werkwijze.
Samenwerking tussen beheerders en ontwikkelaars
De cloud providers die gebruikt worden zijn Google, AWS en Azure. Voordat we de techniek in duiken laat Maxim ons zien hoe hij Ansible Tower heeft ingericht voor zowel beheerders als ontwikkelaars; 2 rollen met beide 2 andere interesses. De beheerder wil zich focussen op de infrastructuur en de configuratie van het besturingssysteem. De ontwikkelaar wil zich concentreren op het uitrollen van zijn applicatie, zonder zich te bekommeren op de infrastructuur en onderliggende configuraties.
Door het slim toewijzen van groepen en rechten binnen Ansible Tower worden playbooks, door middel van workflows, verdeeld tussen beide rollen. Dit laat zien dat hierin samenwerking, zonder technische kennis van elkaars vakgebied, mogelijk is. Een briljante inrichting die, in de huidige tijd van DevOps en Agile integraties, perfect laat zien hoe silo organisaties vanuit de techniek worden geholpen in hun digitale transformatie en evolutie.
De workflow
Maxim heeft een Ansible Tower workflow gebouwd waarin er 3 virtuele machines worden aangemaakt op 3 verschillende cloud providers, een load balancer configuratie wordt toegepast en op alle virtuele machines een webapplicatie wordt uitgerold. De playbooks achter de workflows worden voor het infrastructuur gedeelte gebouwd en beheerd door de beheerders, en het deel van de load balancer configuraties en de webapplicatie door de ontwikkelaars.
API Uitdaging
Voor het aanmaken van een virtuele machine op een cloud provider gebruiken we eenvoudig een Ansible module. Deze module geeft een terugkoppeling van de API van de cloud provider. Hier staat informatie in die we nodig hebben in de latere playbooks om de webapplicatie uit te rollen. Het gebruikmaken van verschillende cloud providers heeft altijd de voorkeur, maar brengt wel nieuwe uitdagingen met zich mee op API’s niveau.
Hoewel de API’s van de verschillende providers functioneel op dezelfde manier werken, zitten ze technisch gezien toch heel anders in elkaar. De informatie die de verschillende API’s nodig hebben zijn verschillend en de manier waarop de providers de basis virtuele machine opleveren is ook verschillend. Dit leidt tot weer verschillen in de besturingssystemen op de diverse virtuele machines en dat is natuurlijk niet wenselijk. Zo genereert Azure, bijvoorbeeld, standaard een LVM disk lay-out waar Google en AWS dat niet doen, en zitten er bijvoorbeeld kleine verschillen in de kernel tussen Google en AWS.
Na het aanroepen van de API’s om de virtuele machines te creëren, geven de API’s informatie terug. Geen van de cloud providers geeft de informatie op een eenduidige manier terug. Omdat we de terugkoppeling van de API’s nodig hebben in latere playbooks, moeten we deze verschillen platslaan.
Voor het maken van de playbooks voor de workflows willen we zeker weten dat de 3 virtuele machines identiek aan elkaar zijn. Dit betekent dat ze dezelfde credentials voor deployments moeten bevatten en ze na het aanmaken op een uniforme manier worden opgenomen in de Ansible inventory met eenduidige parameters en variabelen. Dit laatste is belangrijk omdat we onze applicatie deployment playbooks voor alle machines gelijk willen houden.
De eerste stap om de verschillen in de virtuele machines te voorkomen is het maken van een custom image voor iedere cloud provider. Dit garandeert een identieke configuratie van de virtuele machines. Voor het maken van een custom image gebruik je bijvoorbeeld de ingebouwde image builder van RHEL8 cockpit. Hoe dit in z’n werk gaat lees je op deze pagina.
Na het aanmaken van de virtuele machines, hebben we verschillende variabele namen voor gelijke informatie. Het publieke IP adres van iedere virtuele machine moet verkregen worden uit 3 verschillende variabelen. Om dit probleem op te lossen, schrijven we deze variabelen weg naar nieuwe variabelen, zogeheten custom facts. Om deze custom facts tijdens een workflow te delen tussen de infrastructuur playbooks en de playbooks voor de applicatie deployment, maken we gebruik van de “set_stats” module van Ansible. Houd hierbij wel rekening dat de custom facts die hiermee worden gemaakt enkel in-memory zijn en dus na de workflow weer verdwenen zijn.
We maken dus nieuwe virtuele machines, halen informatie die we nodig hebben op uit de 3 verschillende API terugkoppelingen en verwerken deze informatie in custom facts naar de inventory. Door deze manier van werken slaan we de verschillen tussen de cloud providers plat en zetten we eenduidig onze applicatie deployment playbooks in.
Waardevolle tips
Tijdens het maken van onze playbooks gebruiken we wellicht rollen en daarbinnen uiteraard modules van Ansible. Belangrijk is om het “Try and DRY” principe te hanteren. Test je code (Try) en Don’t Repeat Yourself (DRY). Op het moment dat er identieke code op verschillende plaatsen komt te staan, wordt het tijd om deze code op 1 plaats te hebben en aan te roepen op de plekken waar nodig. Dit zorgt ervoor dat het beheer van de code eenvoudiger en gecentraliseerd blijft.
Om te voorkomen dat we zelf het wiel opnieuw gaan uitvinden, is Ansible Galaxy een goed punt om te zoeken naar de code die je nodig hebt. Daarnaast biedt de Ansible Automation Hub goede en ondersteunde verzamelingen van playbooks. Dit zijn de zogeheten “Collections” en worden aangeleverd door de leveranciers van de softwarepakketten waarvoor jij je code nodig hebt.
Als je een rol tegenkomt die niet helemaal aan jouw behoefte voldoet, maak dan een “pull request” in GitHub om jouw aanpassingen op te laten nemen in de rol. Op deze manier help je de community en dus anderen die tegen dezelfde problemen aanlopen als jij. Als laatste tip geeft Maxim ons mee dat tijdens de bouw van onze playbooks we ook in acht moeten nemen dat we playbooks maken om een omgeving af te tuigen. Dit helpt in het test-proces en voorkomt dat je telkens nieuwe virtuele machines moet aanmaken in je development-proces.
Aan de slag met Ansible Tower & Windows
Na Maxim is het de beurt aan Fred van Zwieten. Om zijn demo en presentatie in lijn te trekken hebben ze hem een uitdaging gegeven: “Doe hetzelfde met Ansible wat Maxim deed, alleen dan voor Windows.”. Niet schuw voor een goede uitdaging heeft Fred gekozen voor de “Red Pill”; hoe lastig? Ansible heeft toffe Windows modules, dus we pakken de playbooks van Maxim en zetten overal “win_” voor en klaar maar weer. Toch?
WinRM voor playbooks
Nee, hoewel er veel hetzelfde is, is er ook hier weer heel veel anders. Om te beginnen de snelheid. Waar een Linux image vrij snel gereed is, duurt het starten en configureren van een Windows image erg lang. Sterker nog, op Google en AWS is de snelheid nog acceptabel. Op Azure daarentegen… Wel een opmerkelijke constatering. Ook anders is de manier waarop de custom facts moeten worden opgeslagen, dit moet namelijk middels een PowerShell script. Als laatste grote verschil is er het verschil tussen OpenSSH op Linux en WinRM voor Windows distributies.
Uiteraard is het mogelijk dat we op recente versies van Windows ook OpenSSH benutten, maar waar WinRM al niet de meest snelle oplossing is, is de OpenSSH implementatie op Windows helemaal een draak. De keuze valt dus op het gebruik maken van WinRM voor de playbooks. Hier komen we echter uit op het probleem van het kip en het ei. Waar een Linux distributie standaard OpenSSH aan boord heeft, geldt dit voor WinRM op Windows niet. Wel hebben we vastgesteld dat we WinRM nodig hebben voor aansturing vanuit Ansible. Ook voor dit probleem moeten we een custom image gebruiken.
Een tikkeltje anders dan Linux
Als laatste grote verschil is er de staat van de machine. Wanneer is deze klaar voor een volgende Ansible taak? Je zou verwachten dat deze gereed is op het moment dat dit als zo geadverteerd wordt door de machine. Bij Linux is die aanname correct, bij Windows wederom niet. Waar Windows adverteert gereed te zijn, is deze dat niet. We moeten hier dus gebruik maken van de Ansible module “wait_for_connection” om zeker te zijn dat de machine klaar is voor de volgende stap.
Om de virtuele Windows machine op Azure te creëren geven we de credentials vooraf op en gebruiken we daarnaast de Azure “extensions” vanuit Ansible om WinRM te activeren.
Voor Windows op AWS moeten we gebruikmaken van het veld “user_data” tijdens het creëren van de machine. We lezen de credentials van de machine uit van de API terugkoppeling en genereren met de “win_user” module vervolgens onze deployment credentials.
Bij Google maken we gebruik van het “sysprep” script om WinRM op de machine te activeren. Standaard heeft een machine vanuit Google geen wachtwoord en moeten we dit via online instructies toe gaan passen. Fred heeft hiervoor zelf een module geschreven; “gcp_compute_win_password” om dit probleem uit de wereld te helpen.
Bovenstaande vereist dat we credentials bevragen en toevoegen aan de Windows machines. Dit klinkt eenvoudig, maar omdat we rechtstreeks vanaf de Ansible controller naar de cloud providers praten, gebruiken we een “local” connection type. Dit zorgt er weer voor dat de credentials vanuit het inventory niet werken, omdat we taken op “localhost” uitvoeren. De oplossing hiervoor ligt in het toevoegen van de gegenereerde machines aan het in-memory inventory. We voegen deze “dummy” hosts toe met de opgehaalde credentials en op dat moment gebruiken we die credentials op de individuele machines. Omdat de wijziging op het in-memory inventory is, zijn de credentials alleen tijdens de uitvoer van de playbook beschikbaar en daarna niet meer. Dit zorgt ervoor dat we geen credentials hoeven op te slaan in een “Vault-encrypted” bestand of andere file-based constructie. Lekker veilig en wel zo efficiënt.
Na het creëren van de virtuele machines, moeten we wachten tot de machines daadwerkelijk gereed zijn. Pas hierna configureren we de load balancer en rollen we de webapplicatie uit. Om ook nu de infrastructuur en de applicatie laag met elkaar te laten samenwerken, moeten we custom facts maken. In theorie maken we met Windows custom facts met behulp van PowerShell en de Ansible module “win_template”. Vervolgens gebruiken we de “setup” module samen met “fact_path” om de facts terug te krijgen. De theorie is feilloos, de praktijk leert dat Ansible Tower hier niet goed mee overweg gaat. Na onderzoek is Fred er achter gekomen dat het saneren van de fact cache niet robuust genoeg is voor deze constructie en heeft hij een bug aangemeld. Lang leve de “Red Pill”.
Een workaround voor dit probleem is om, tot de bug is opgelost, gebruik te maken van groepering van de groepen zoals de cloud providers ze terug geeft in het inventory. Deze custom groepen gebruiken we in de deployment om taken toe te wijzen aan machines en op deze manier deployen we succesvol een webapplicatie op een multi-cloud Windows stack.
Missie geslaagd
In de tussentijd is de workflow hiervoor gestart, maar gezien de snelheid van het deployen van de Windows images bij de cloud providers hebben we tijd voor een leuke break-out sessie. Zoals je hebt gelezen heeft Fred zelf een Ansible module gemaakt. In een kwartier tijd loodst hij ons door dit proces heeft en laat hij ons in vogelvlucht zien wat er voor nodig is om zelf een Ansible module te maken. En na 26 minuten is Windows eindelijk helemaal klaar en draait er een webapplicatie achter een load balancer in een multi-cloud omgeving.
Maxim en Fred hebben ons niet alleen de verschillen tussen cloud providers, maar ook tussen besturingssystemen op die cloud providers laten zien. We hebben mee kunnen kijken in de techniek om deze verschillen te overbruggen en daarmee waren deze sessies een waardevolle aanvulling op alles wat we tijdens Ansible Automates hebben gezien en geleerd.
Meer weten? En zelf interactief ervaren?
Heb je voor je gevoel wat informatie gemist? Dat klopt. De break-out sessie over het maken van je eigen Ansible module heb ik je niet meegegeven. Waarom niet? Omdat ik jullie veel liever zie op onze Automation Meetup op 7 april 2020. Tijdens deze Meetup laten we je uitvoerig zien hoe je zelf een Ansible module maakt aan de hand van een presentatie en natuurlijk een demonstratie.
Volg onze Meetup groep ‘HCS Company Meetups’ om op de hoogte te blijven van dit evenement en markeer alvast 7 april in je agenda!