Ik ben van Terraform naar CloudFormation overgestapt — en het was een vergissing

Infrastructuur presenteren als code in een herhaalbaar tekstformaat is een eenvoudig betere praktijk voor systemen waarmee je niet hoeft te rommelen. Deze praktijk staat bekend als — Infrastructure as Code, en totdat nu zijn er vooral twee populaire tools voor implementatie, vooral in AWS: Terraform en CloudFormation.

Ik ben van Terraform naar CloudFormation overgestapt — en het was een vergissing
Ik vergelijk de ervaring met Terraform en CloudFormation

Voor ik bij Twitch (ook wel bekend als Amazon Jr.) werkte, heb ik in een startup gewerkt en heb drie jaar Terraform gebruikt. Bij mijn nieuwe werkgever heb ik ook volop Terraform gebruikt, maar daarna heeft het bedrijf de overstap naar alles dat lijkt op Amazon doorgedrukt, inclusief CloudFormation. Ik heb hard gewerkt aan de beste praktijken voor zowel het een als het ander, en beide tools gebruikt in zeer complexe workflows op organisatorische schaal. Later, na zorgvuldig de gevolgen van de overstap van Terraform naar CloudFormation af te wegen, realiseerde ik me dat Terraform waarschijnlijk de beste keuze voor de organisatie is.

Terraform is verschrikkelijk

Beta-versie van de software

Terraform heeft zelfs nog geen versie 1.0 uitgebracht, en dat is een goede reden om het niet te gebruiken. Sinds ik het voor het eerst probeerde, is het aanzienlijk veranderd, maar destijds was het nog terraform apply soms kapot na een paar updates of gewoon na een paar jaar gebruik. Ik zou zeggen: ‘nu gaat alles anders’, maar… dat zegt iedereen blijkbaar, toch? Er zijn veranderingen die niet compatibel zijn met eerdere versies, hoewel ze gepast zijn, en het voelt zelfs alsof de syntaxis en abstracties van resource repositories nu deugdelijk zijn. De tool lijkt echt beter te zijn geworden, maar… :-0

Aan de andere kant heeft AWS goed zijn best gedaan om compatibiliteit met eerdere versies te behouden. Waarschijnlijk komt dat omdat hun services vaak grondig intern worden getest en pas daarna, onder een andere naam, worden gepubliceerd. Dus zeggen dat ze ‘goed hun best hebben gedaan’ is nog zwak uitgedrukt. Compatibiliteit met eerdere versies van de API behouden voor zo'n variabele en complexe systeem zoals AWS is ongelooflijk moeilijk. Iedereen die ooit openbare API's heeft onderhouden die zo wijdverbreid zijn, moet begrijpen hoe moeilijk het is om dit jarenlang te doen. Het gedrag van CloudFormation is volgens mij in de loop der jaren nooit veranderd.

Maak kennis met je voet… dit is een kogel

Voor zover ik weet, kun je een externe bron niet verwijderen. Het is niet mogelijk om een CloudFormation-stack vanuit je CF-stack te importeren. Hetzelfde geldt ongeveer voor Terraform. Dit stelt je in staat om bestaande resources in je stack te importeren. Het is een indrukwekkende functie, maar met grote kracht komt ook grote verantwoordelijkheid. Nadat je een resource in de stack hebt toegevoegd, kun je deze niet verwijderen of wijzigen terwijl je met je stack werkt. Eens leidde dit tot problemen. Iemand importeerde per ongeluk een beveiligingsgroep van AWS in zijn eigen Terraform-stack op de Twitch-website. Hij voerde een paar opdrachten in en... de beveiligingsgroep (samen met het inkomende verkeer) verdween.

Terraform de Grote

Herstellen vanuit onvolledige toestanden

Soms is CloudFormation niet in staat om volledig van de ene toestand naar de andere over te gaan. In dat geval probeert het terug te keren naar de vorige toestand. Helaas is dat niet altijd mogelijk. Het kan behoorlijk eng zijn om te debuggen wat het resultaat is — je weet nooit of CloudFormation blij is dat je het probeert te hakken — zelfs als het om te herstellen is. Of het lukt om naar de vorige toestand terug te keren, weet het niet echt en standaard hangt het urenlang te wachten op een wonder.

Terraform daarentegen is over het algemeen beter in het herstellen na mislukte overgangen en biedt een uitgebreid debugging-hulpmiddel.

Duidelijkere verandering in documenttoestanden

‘Goed, load balancer, je verandert. Maar hoe?’

— Een bezorgde engineer, klaar om op de knop 'accepteren' te drukken.

Soms moet ik een aantal handelingen uitvoeren met de load balancer in de CloudFormation-stack — bijvoorbeeld een poortnummer toevoegen of de beveiligingsgroep wijzigen. CloudFormation toont wijzigingen slecht weer. Ik controleer het yaml-bestand wel tien keer om er zeker van te zijn dat ik niets belangrijks heb verwijderd en niets overbodigs heb toegevoegd.

Terraform is hierin veel transparanter. Soms zelfs te transparant (lees: irritant). Gelukkig is in de laatste versie verbeterde weergave van wijzigingen toegevoegd — nu is het precies zichtbaar wat er verandert.

Flexibiliteit

Schrijf software van achter naar voren.

Eerlijk gezegd, de belangrijkste onderscheidende eigenschap van levensduursoftware is het vermogen zich aan te passen aan veranderingen. Schrijf elke software van de achterkant naar voren. Ik heb vaak de fout gemaakt om een 'simpele' service te kiezen, om vervolgens alles in één CloudFormation- of Terraform-stack te proppen. En natuurlijk kwam na maanden naar voren dat ik het helemaal verkeerd begreep, en dat de service eigenlijk helemaal niet simpel was! Ik moest op de een of andere manier de grote stack in kleinere onderdelen splitsen. Bij het werken met CloudFormation is het alleen mogelijk om dit te doen door eerst de bestaande stack te reconstrueren, wat ik met mijn databases niet doe. Terraform maakte het echter mogelijk om de stack te dissecteren en deze in meer begrijpelijke kleinere delen op te splitsen.

Modules in git

Het delen van Terraform-code tussen talloze stacks is veel eenvoudiger dan het delen van CloudFormation-code. Met Terraform kun je code in een git-repository plaatsen en deze aanspreken met semantische versiecontrole. Iedereen met toegang tot deze repository kan de gedeelde code opnieuw gebruiken. Het CloudFormation-equivalent is S3, maar dat heeft niet dezelfde voordelen, en er is geen enkele reden waarom we überhaupt S3 ten koste van git zouden moeten gebruiken.

De organisatie groeide en de mogelijkheid om gedeelde stacks te delen bereikte een kritiek niveau. Met Terraform gaat dit allemaal gemakkelijk en natuurlijk, terwijl CloudFormation je door hoepels laat springen voordat je iets dergelijks aan de praat krijgt.

Operations as code

"Laten we het scripten en klaar."

- een ingenieur drie jaar voordat hij de fiets Terraform uitvond.

Als het om softwareontwikkeling gaat, is Go of een programma in Java niet zomaar code.

Ik ben van Terraform naar CloudFormation overgestapt — en het was een vergissing
Code als Code

Er is ook de infrastructuur waarop het draait.

Ik ben van Terraform naar CloudFormation overgestapt — en het was een vergissing
Infrastructure as Code

Maar waar komt het vandaan? Hoe monitor je het? Waar woont jouw code? Hebben ontwikkelaars toestemming voor toegang nodig?

Ik ben van Terraform naar CloudFormation overgestapt — en het was een vergissing
Operations as Code

Software-ontwikkeling is niet alleen code schrijven.

Niet alleen AWS: je gebruikt ongetwijfeld de diensten van andere leveranciers. SignalFx, PagerDuty of Github. Misschien heb je een interne Jenkins-server voor CI/CD of een intern Grafana-dashboard voor monitoring. Infra as Code wordt om verschillende redenen gekozen, en elke reden is even belangrijk voor alles wat met software te maken heeft.

Toen ik bij Twitch werkte, versnelden we de services binnen gemengde embedded systemen en de AWS-systemen van Amazon. We produceerden en ondersteunden talloze microservices, waardoor de operationele kosten toenamen. De discussies gingen ongeveer als volgt:

  • Ik: Tja, dat is wel veel gedoe om één microservice op te starten. Ik moet dit spul gebruiken om een AWS-account aan te maken (we gingen naar 2 accounts op microservice), daarna dit — voor het instellen van meldingen, dit — voor de code-repository, en dit — voor de lijst met e-mailadressen, en ook dit…
  • Lead: Laten we het automatiseren, dat is prima.
  • Ik: Oké, maar het script zal veranderen. We hebben een manier nodig om te controleren of al deze ingebouwde dingetjes van Amazon up-to-date zijn.
  • Lead: Klinkt goed. En daarvoor schrijven we een script.
  • Ik: Geweldig! En het script moet zeker ook parameters hebben. Neemt hij die aan?
  • Lead: Ja, dat doet hij, dat kan niet anders!
  • Ik: Het proces kan veranderen, er kan verlies van achterwaartse compatibiliteit zijn. We hebben een of andere semantische versiecontrole nodig.
  • Lead: Geweldige idee!
  • Ik: Hulpmiddelen kunnen handmatig worden gewijzigd, binnen de gebruikersinterface. We hebben een manier nodig om dit te controleren en te corrigeren.

…3 jaar later:

  • Lead: En zo kregen we Terraform.

De moraal van het verhaal is: zelfs als je tot je nek in alles wat van Amazon is, gebruik je nog steeds iets dat niet van AWS is, en die services hebben een status die een taal gebruikt voor configuratie om deze status te synchroniseren.

CloudFormation lambda vs git-modules terraform

lambda is de CloudFormation-oplossing voor het probleem van gebruikerslogica. Met lambda kun je macro's of gebruikersresource. Deze benadering brengt extra complexiteit met zich mee die niet aanwezig is in de semantische versiecontrole van git-modules in Terraform. Voor mij was het grootste probleem het beheer van machtigingen voor al deze gebruikerslambda (en dat zijn tientallen AWS-accounts). Een ander belangrijk probleem was de vraag 'wat was er eerst — de kip of het ei?': deze was gerelateerd aan de lambda-code. Deze functie is zowel infrastructuur als code, en ze moet ook gemonitord en bijgewerkt worden. De laatste hamer op de spijker was de moeilijkheid van semantisch bijwerken van wijzigingen in de lambda-code; het moest ook zo zijn dat de acties van de stack niet veranderd werden tussen uitvoeringen zonder directe instructie.

Ik herinner me dat ik op een gegeven moment een canary deployment voor de Elastic Beanstalk-omgeving wilde maken met een klassieke load balancer. Het zou het eenvoudigste zijn om een tweede deployment voor EB naast de productie-omgeving te maken, en een extra stap te zetten: de automatisch schaalbare groep van de canary deployment combineren met de LB van de productie-omgeving. Aangezien Terraform gebruikt maakt van ASG beantalk als output, dit vereist 4 extra regels code in Terraform. Toen ik vroeg of er een vergelijkbare oplossing in CloudFormation was, werd ik doorverwezen naar een hele repository in git met een deployment pipeline en meer: en dit alles voor wat we met slechts 4 ongelukkige regels Terraform-code zouden kunnen doen.

Het detecteert drift beter

Zorg ervoor dat de werkelijkheid overeenkomt met de verwachtingen.

Diften van drift — is een zeer krachtige functie van operations as code, omdat het helpt ervoor te zorgen dat de werkelijkheid overeenkomt met de verwachtingen. Het is beschikbaar in zowel CloudFormation als Terraform. Maar naarmate de stack groeit, gaf het zoeken naar drift in CloudFormation steeds meer valse ontdekkingen.

Met Terraform heb je veel meer geavanceerde lifecycle hooks voor drift detectie. Bijvoorbeeld, je typt het commando ignore_changes rechtstreeks in de taakdefinitie van ECS als je wijzigingen in de definitie van een specifieke taak wilt negeren, zonder wijzigingen in de hele ECS deployment te negeren.

CDK en de toekomst van CloudFormation

CloudFormation is moeilijk te beheren op grote, inter-infrastructurele schalen. Veel van deze moeilijkheden zijn erkend en het hulpmiddel heeft dingen nodig zoals aws-cdk, een structuur voor het definiëren van cloud infrastructuur in code en het doorgeven ervan aan AWS CloudFormation. Het zal interessant zijn om te zien wat de toekomst brengt voor aws-cdk, maar het zal moeilijk zijn om te concurreren met de andere voordelen van Terraform; om CloudFormation bij te trekken, zijn wereldwijde veranderingen nodig.

Om teleurstellingen met Terraform te voorkomen

Dit is "infrastructure as CODE", en niet "als tekst".

Mijn eerste indruk van Terraform was vrij negatief. Ik denk dat ik de aanpak gewoon niet begreep. Bijna alle ingenieurs beschouwen het in het begin onbewust als een tekstformaat dat moet worden omgezet in de gewenste infrastructuur. DAT MOET NIET.

De basisprincipes van goede softwareontwikkeling zijn ook van toepassing op Terraform

Ik heb gezien dat veel praktijken die nodig zijn voor het schrijven van goede code, worden genegeerd in Terraform. Je hebt jaren geleerd om een goede programmeur te worden. Geef die ervaring niet op alleen omdat je met Terraform werkt. De basisprincipes van goede softwareontwikkeling zijn ook van toepassing op Terraform.

Hoe kun je code niet documenteren?

Ik ben enorme Terraform-stacks tegengekomen zonder enige documentatie. Hoe kun je pagina's vol code schrijven — zonder enige documentatie? Voeg documentatie toe die jouw code Terraform (de nadruk ligt hier op het woord 'code'), waarom is dit gedeelte zo belangrijk en wat doe je?

Hoe kun je services implementeren die ooit één grote functie main() waren?

Ik ben zeer complexe Terraform-stacks tegengekomen die als één enkele module werden gepresenteerd. Waarom implementeren we software op deze manier niet? Waarom splitsen we grote functies op in kleinere? Dezelfde antwoorden gelden ook voor Terraform. Als je module te groot is, moet je deze opsplitsen in kleinere modules.

Gebruikt jouw bedrijf geen bibliotheken?

Ik heb gezien dat ingenieurs, terwijl ze een nieuw project met Terraform opzetten, letterlijk enorme stukken uit andere projecten in hun eigen projecten kopieerden en plakte, en vervolgens bleven rommelen tot het werkte. Zou jij in jouw bedrijf op deze manier met 'productiewerk' omgaan? We gebruiken bibliotheken niet voor niets. Ja, niet alles moet een bibliotheek zijn, maar waar zouden we zonder gemeenschappelijke bibliotheken in het algemeen zijn?!

Gebruik je geen PEP8 of gofmt?

De meeste programmeertalen hebben een standaard opmaak. In Python is dit PEP8. In Go is het gofmt. Terraform heeft de zijn: terraform fmt. Maak er gebruik van!

Zou je React gebruiken zonder JavaScript te kennen?

Terraform-modules kunnen een deel van de complexe infrastructuur die je opbouwt vereenvoudigen, maar dat betekent nog niet dat je er helemaal geen kennis van moet hebben. Wil je Terraform correct gebruiken zonder begrip van de middelen? Je bent gedoemd: de tijd zal verstrijken en je zult Terraform niet onder de knie krijgen.

Programmeert je met singletons, of duik je in afhankelijkheden?

Dependency injection is considered the best practice for software development, particularly favored by singletons. How does this apply to Terraform? I've encountered Terraform modules that depend on remote state. Instead of writing modules that extract from remote state, write a module that accepts parameters. Then pass these parameters to the module.

Do your libraries do ten things well or one thing excellently?

Libraries that focus on a single task and execute it exceptionally well perform best. Instead of writing large Terraform modules that try to do everything at once, break them down into pieces that do one thing well. Then combine them as needed.

How do you make changes to libraries without breaking backward compatibility?

A general Terraform module, like any regular library, needs a way to inform users about breaking changes. Such changes in libraries are frustrating, and the same goes for breaking changes in Terraform modules. It is advisable to apply git tags and semver when using Terraform modules.

Is your production service running on your laptop or in a data center?

Hashicorp has tools like terraform cloud to run your Terraform. These centralized services make it easier to manage, audit, and approve Terraform changes.

Aren't you writing tests?

Engineers acknowledge the need to test code, yet often neglect checks when working with Terraform. This can lead to tricky situations in infrastructure. I recommend 'testing' or 'creating examples' of stacks using modules that can be properly deployed for verification during CI/CD.

Terraform and microservices

The life and death of microservice companies depend on the speed, updating, and dismantling of new microservice working stacks.

The most common downside associated with microservice architectures that cannot be avoided is related to operations, not code. If you view Terraform merely as a way to automate the infrastructural side of microservice architecture, you are missing out on the true benefits of this system. Currently, already everything is code.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster