Moderne informatiesystemen worden meer en meer cloud gebaseerd. Steeds meer projecten worden overgezet naar de cloud. Vaak gebeurt dit nog in de vorm van “lift en shift”, maar langzamerhand worden steeds meer projecten ontworpen en ontwikkeld als cloud native oplossing.
Een wezenlijk onderdeel van de implementatie van een informatiesysteem is (niet verwonderlijk) de infrastructuur waarop deze zal gaan draaien. Dit is altijd al geweest, en dat zal waarschijnlijk nog wel een tijd blijven. Alleen de manier waarop we met deze infrastructuur omgaan in veranderd.
Trip down memory lane
Een tijdje terug, nog niet echt heel lang geleden (en in sommige gevallen zelfs nu nog) betekende infrastructuur opzetten dat je naar de hardware leverancier moest om server machines, netwerk switches, power bars, UPSsen enzovoorts aan te schaffen om deze dan allemaal aan te sluiten, eventuele operating systemen en overige software installeren, configureren en dan uiteindelijk je implementatie erop te zetten.
Fast forward to now
Tegenwoordig word steeds vaker gebruik gemaakt van gevirtualiseerde omgevingen. Deze trend is ingezet met virtuele computers (op VMWare/HyperV), en is in de tussentijd zodanig uitgebreid dat de totale infrastructuur gevirtualiseerd kan worden. Nagenoeg alle hardware, die we nog niet zo lang geleden “aan ijzer” moesten aanschaffen, is nu virtueel te verkrijgen. Sterker nog, als je gebruik maakt van een cloud provider als bijvoorbeeld Microsoft Azure of Amazon Web Services (AWS), dan ís gewoon alles virtueel. (nou ja, er zijn nog hardware modules die je kan aanschaffen om te gebruiken in je omgeving, maar deze zijn voor heel specifieke toepassingen).
Long story short, waar we vroeger allemaal hardware moesten kopen en aansluiten, kan je nu een hele omgeving “in elkaar klikken” vanuit het platform management dashboard in je browser… of volledig geautomatiseerd door gebruik te maken van de beschikbare APIs.
Introducing IaC (infrastructure as code)
Vooral het feit dat het mogelijk is om via API calls, volledig geautomatiseerd, een infrastructuur in elkaar te zetten heeft voor ons ontwikkelaars een ontzettende plus. Het is namelijk mogelijk om door middel van scripting een infrastructuur uit te rollen, gereed voor de implementatie van je softwareoplossing.
Hier zijn meerdere oplossingen voor, welke we kunnen groeperen in 2 hoofdgroepen, de “Declaratieve” en “Imperatieve” oplossingen.
Imperatieve oplossingen voor IaC
Een imperatieve oplossing voor IaC betekent kort door de bocht dat je totale controle hebt over de opbouw van je infrastructuur. Dit komt tegen een prijs, want je moet dan ook werkelijk alles low-level uitscripten in bijvoorbeeld batch bestanden die tegen de platform APIs van bijvoorbeeld een cloud provider als AWS of Azure praten om elk miniscuul klein detail van je doelplatform uit te rollen.
Dit zorgt er ook voor dat je zelf verantwoordelijk bent voor onder andere de volgorde waarmee je alle componenten uitrolt, maar bij veranderingen op het platform ben je ook zelf verantwoordelijk voor de stappen om van de draaiende situatie naar de nieuwe situatie te komen. (o.a. oude resources opruimen)
Meestal worden hiervoor de verschillende cli-tools van de cloud provider gebruikt in bash of powershell scripts.
Declaratieve oplossingen voor IaC
Meer “gebruikersvriendelijk” zijn de zogenaamde declaratieve oplossingen. Hiermee beschrijf je de (hoog-over) gewenste doelsituatie in een specificatietaal (bijvoorbeeld yaml) en laat je tooling deze beschreven doelsituatie uitwerken. Voordeel hiervan is dat de verantwoordelijkheid voor eventuele volgordelijkheid uit handen genomen wordt en dat bij eventuele wijzigingen op het platform ook alle benodigde opruimstappen automatisch worden meegenomen. Het is overal ook stukken eenvoudiger omdat je niet alle low-level details zelf hoeft te regelen.
Er zijn hiervoor legio tools beschikbaar, de bekendste zijn Hashicorp Terraform, AWS CDK (en/of cloudformation), Azure Resource Manager, en tegenwoordig ook Pulumi.
Deze tools kun je ook weer verder onderverdelen op basis van de manier van specificeren. Waar Terraform, CloudFormation en Azure Resource Manager vooral uitgaan van specificatie in een eigen (yaml/json) gebaseerde specificatietaal, werken AWS CDK en Pulumi met vele “standaard” programmeertalen, zodat een ontwikkelaar makkelijker ook de infra kan “programmeren”.
Immutable?
Het grote verschil tussen infrastructure as code en Immutable infrastructure as code ligt em niet in de techniek an sich. Het is vooral de afspraak dat je infrastructuur NIET MEER wijzigt tussen deployments van je solution, en alle wijzigingen meekomen met de deployments.
Waarom?
We willen dat de infrastructuur van je softwareoplossing in een zogenaamde “known good state” is. Kort samengevat, je software mag er vanuit gaan dat de infrastructuur zodanig opgezet is dat deze geschikt is om de oplossing te kunnen draaien.
Hiermee maak je een situatie onmogelijk dat de software die voor een nieuwe deployment wel op het platform draait, ineens niet meer draait na een deployment omdat er ineens te weinig resources (bijvoorbeeld RAM geheugen) beschikbaar is. Dit is bijvoorbeeld mogelijk omdat een operations engineer het beschikbare geheugen op een VM heeft vergroot, maar dat dit nooit is opgenomen in de IaC scripts/specificatie.
Een heel belangrijk principe wat hierbij vaak wordt toegepast is dat de totale infrastructuur bij elke deployment (al dan niet via blue-green strategie) opnieuw wordt opgebouwd, waarna bij succesvolle deployment de oude infrastructuur wordt afgebroken.
Let hierbij wel op dat je een goede data-retainment strategie hebt! (o.a. backups, data op losstaande storage die niet in de deployment wordt meegenomen, etc…).