Why we use Terraform and not Chef, Puppet, Ansible, SaltStack, or CloudFormation

Update, 17 November 2016: We namen deze blog postserie, breidden deze uit en maakten er een boek Van genaamd Terraform: Up & Running!

Update, 8 juli 2019: we hebben deze blogpostserie bijgewerkt voor Terraform 0.12 en de 2e editie van Terraform: Up & Running!

Dit is deel 1 van de uitgebreide gids voor Terraform serie. In de intro van de serie bespraken we waarom elk bedrijf gebruik zou moeten maken van infrastructure-as-code (IAC). In deze post gaan we bespreken waarom we Terraform hebben gekozen als onze IAC-tool van keuze.

Als u op het Internet zoekt naar “infrastructure-as-code”, is het vrij eenvoudig om een lijst te maken van de meest populaire tools:

  • Chef
  • Puppet
  • Ansible
  • SaltStack
  • CloudFormation
  • Terraform

wat niet gemakkelijk is, is uitzoeken welke van deze U moet gebruiken. Al deze tools kunnen worden gebruikt om infrastructuur als code te beheren. Ze zijn allemaal open source, ondersteund door grote gemeenschappen van bijdragers, en werken met veel verschillende cloud-providers (met de opmerkelijke uitzondering van CloudFormation, dat is gesloten bron en AWS-only). Alle van hen bieden enterprise ondersteuning. Alle van hen zijn goed gedocumenteerd, zowel in termen van officiële documentatie en community middelen zoals blog posts en StackOverflow vragen. Hoe beslis je dan?

wat dit nog moeilijker maakt is dat de meeste vergelijkingen die je online vindt tussen deze tools weinig meer doen dan een lijst van de algemene eigenschappen van elke tool en het laten klinken alsof je net zo succesvol zou kunnen zijn met een van hen. En hoewel dat technisch waar is, helpt het niet. Het is een beetje als het vertellen van een programmering newbie dat je net zo succesvol zou kunnen zijn het bouwen van een website met PHP, C, of Assembly — een verklaring die is technisch waar, maar een die een enorme hoeveelheid informatie weglaat die ongelooflijk nuttig zou zijn bij het maken van een goede beslissing.

in dit bericht gaan we ingaan op een aantal zeer specifieke redenen waarom we Terraform boven de andere IAC tools kozen. Zoals bij alle technologische beslissingen, is het een kwestie van afwegingen en prioriteiten, en hoewel uw specifieke prioriteiten anders kunnen zijn dan de onze, hopen we dat het delen van ons denkproces u zal helpen uw eigen beslissing te nemen. Hier zijn de belangrijkste trade-offs die we overwogen:

  • Configuration Management vs Provisioning
  • Veranderlijk Infrastructuur vs Onveranderlijk Infrastructuur
  • Procedurele vs Declaratieve
  • Master vs Masterless
  • Agent vs Agentless
  • Grote Gemeenschap versus Kleine Gemeenschap
  • Volwassen vs Cutting Edge
  • het Gebruik van Meerdere Instrumenten Samen

Chef, Puppet, Ansible, en SaltStack zijn alle configuratie management tools, wat betekent dat ze zijn ontworpen om te installeren en beheren van software op bestaande servers. CloudFormation en Terraform zijn provisioning tools, wat betekent dat ze zijn ontworpen om de servers zelf te leveren (evenals de rest van uw infrastructuur, zoals load balancers, databases, netwerkconfiguratie, enz.), waardoor de taak van het configureren van die servers aan andere tools. Deze twee categorieën sluiten elkaar niet uit, omdat de meeste configuratiebeheertools een bepaalde mate van provisioning kunnen doen en de meeste provisioningtools een bepaalde mate van Configuratiebeheer kunnen doen. Maar de focus op Configuratiebeheer of provisioning betekent dat sommige van de tools gaan om een betere pasvorm voor bepaalde soorten taken.

in het bijzonder hebben we ontdekt dat als u Docker of Packer gebruikt, de overgrote meerderheid van uw configuratiebeheerbehoeften al is afgehandeld. Met Docker en Packer kunt u afbeeldingen maken (zoals containers of virtuele machine-afbeeldingen) die alle software die uw server nodig heeft, al hebben geïnstalleerd en geconfigureerd. Zodra je zo ‘ n image hebt, heb je alleen een server nodig om het uit te voeren. En als alles wat je hoeft te doen is het verstrekken van een bos van servers, dan is een provisioning tool zoals Terraform is meestal gaat om een betere pasvorm dan een configuratie management tool (hier is een voorbeeld van hoe Terraform te gebruiken om Docker implementeren op AWS).

Mutable Infrastructure vs Immutable Infrastructure

Configuratiebeheertools zoals Chef, Puppet, Ansible en SaltStack zijn doorgaans standaard voor een mutable infrastructure paradigma. Bijvoorbeeld, als u Chef vertelt om een nieuwe versie van OpenSSL te installeren, zal het de software-update op uw bestaande servers uitvoeren en de wijzigingen zullen op zijn plaats gebeuren. Na verloop van tijd, als u meer en meer updates toe te passen, elke server bouwt een unieke geschiedenis van veranderingen. Dit leidt vaak tot een fenomeen dat bekend staat als configuration drift, waarbij elke server iets anders wordt dan alle andere, wat leidt tot subtiele configuratiefouten die moeilijk te diagnosticeren en bijna onmogelijk te reproduceren zijn.

als u een provisioning tool zoals Terraform gebruikt om machine images te implementeren die door Docker of Packer zijn gemaakt, dan is elke “verandering” in feite een implementatie van een nieuwe server (net als elke “verandering” in een variabele in functioneel programmeren geeft eigenlijk een nieuwe variabele terug). Als u bijvoorbeeld een nieuwe versie van OpenSSL wilt implementeren, maakt u een nieuwe image aan met Packer of Docker met de nieuwe versie van OpenSSL die al is geïnstalleerd, implementeert u die image over een reeks volledig nieuwe servers en ontkoppelt u de oude servers. Deze aanpak vermindert de kans op Configuratie drift bugs, maakt het gemakkelijker om precies te weten welke software wordt uitgevoerd op een server, en kunt u triviaal implementeren van een eerdere versie van de software op elk gewenst moment. Natuurlijk is het mogelijk om configuratiebeheertools te dwingen om onveranderlijke implementaties te doen, maar het is niet de idiomatische aanpak voor deze tools, terwijl het een natuurlijke manier is om provisioningtools te gebruiken.

procedureel Versus declaratief

Chef en Ansible moedigen een procedurestijl aan waarbij u code schrijft die stap voor stap specificeert hoe u een gewenste eindtoestand kunt bereiken. Terraform, CloudFormation, SaltStack en Puppet moedigen allemaal een meer declaratieve stijl aan waarbij je code schrijft die je gewenste eindstatus specificeert, en het IAC gereedschap zelf is verantwoordelijk voor het uitzoeken hoe je die status kunt bereiken.

bijvoorbeeld, laten we zeggen dat je 10 servers (“EC2 Instances” in AWS lingo) wilde inzetten om v1 van een app uit te voeren. Hier is een vereenvoudigd voorbeeld van een Ansible sjabloon dat doet dit met een procedurele aanpak:

- ec2:
count: 10
image: ami-v1
instance_type: t2.micro

En dit is een vereenvoudigd voorbeeld van een Terravorm sjabloon die hetzelfde doet met een declaratieve aanpak:

resource "aws_instance" "example" {
count = 10
ami = "ami-v1"
instance_type = "t2.micro"
}

Nu aan de oppervlakte, deze twee benaderingen kunnen er hetzelfde uitzien, en wanneer u in eerste instantie uit te voeren met Ansible of Terravorm, zij zal dezelfde resultaten. Het interessante is wat er gebeurt als je iets wilt veranderen.

bijvoorbeeld, stel je voor dat het verkeer is gestegen en je wilt het aantal servers verhogen naar 15. Met Ansible, de procedurele code die u eerder schreef is niet langer nuttig; als je gewoon bijgewerkt het aantal servers naar 15 en reran die code, het zou deploy 15 nieuwe servers, waardoor u 25 totaal! Dus in plaats daarvan, je moet je bewust zijn van wat er al is geïmplementeerd en schrijf een totaal nieuw procedureel script om de 5 nieuwe servers toe te voegen:

- ec2:
count: 5
image: ami-v1
instance_type: t2.micro

met declaratieve code, omdat het enige wat je doet is de gewenste eindtoestand declareren, en Terraform uitzoekt hoe je bij die eindtoestand komt, zal Terraform ook op de hoogte zijn van elke toestand die het in het verleden heeft gecreëerd. Daarom, om nog 5 servers te implementeren, hoef je alleen maar terug te gaan naar hetzelfde Terraform template en de telling bij te werken van 10 naar 15:

resource "aws_instance" "example" {
count = 15
ami = "ami-v1"
instance_type = "t2.micro"
}

als je dit template uitvoert, zou Terraform zich realiseren dat het al 10 servers had aangemaakt en dus dat het alleen maar 5 nieuwe servers hoefde te maken. Voordat u dit sjabloon uitvoert, kunt u de opdracht terraform plan gebruiken om een voorbeeld te geven van welke wijzigingen Het zou aanbrengen:

$ terraform plan+ aws_instance.example.11
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.12
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.13
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.14
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.15
ami: "ami-v1"
instance_type: "t2.micro"Plan: 5 to add, 0 to change, 0 to destroy.

Wat gebeurt er nu als u v2 de service wilt implementeren? Met de procedurele aanpak, beide van uw vorige Ansible templates zijn weer niet nuttig, dus je moet nog een sjabloon te schrijven om de 10 servers die u eerder ingezet (of was het 15 nu?) en zorgvuldig updaten elk naar de nieuwe versie. Met de declaratieve benadering van Terraform, ga je weer terug naar exact dezelfde sjabloon en verander je gewoon het AMI versienummer naar v2:

resource "aws_instance" "example" {
count = 15
ami = "ami-v2"
instance_type = "t2.micro"
}

Uiteraard zijn de bovenstaande voorbeelden vereenvoudigd. Met Ansible kunt u wel tags gebruiken om te zoeken naar bestaande EC2-instanties voordat u nieuwe implementeert (bijvoorbeeld met behulp van deinstance_tags encount_tag parameters), maar het handmatig uitzoeken van dit soort logica voor elke bron die u beheert met Ansible, gebaseerd op de geschiedenis van elke bron, kan verrassend ingewikkeld zijn (bijv. het vinden van bestaande instanties niet alleen op tag, maar ook image versie, beschikbaarheid zone, etc). Dit wijst op twee belangrijke problemen met procedurele IAC-instrumenten:

  1. bij het behandelen van procedurele code wordt de toestand van de infrastructuur niet volledig in de code opgenomen. Het lezen van de drie Ansible templates die we hierboven hebben gemaakt is niet genoeg om te weten wat er wordt ingezet. Je moet ook weten in welke volgorde we die sjablonen hebben toegepast. Als we ze in een andere volgorde hadden toegepast, hadden we misschien een andere infrastructuur, en dat is niet iets wat je kunt zien in de code base zelf. Met andere woorden, om over een Ansible of Chef-codebase te redeneren, moet u de volledige geschiedenis van elke verandering kennen die ooit is gebeurd.
  2. de herbruikbaarheid van procedurele code is inherent beperkt omdat u handmatig rekening moet houden met de huidige status van de codebase. Omdat die toestand voortdurend verandert, kan de code die je een week geleden gebruikte niet langer bruikbaar zijn omdat het ontworpen was om een toestand van je infrastructuur te wijzigen die niet meer bestaat. Als gevolg daarvan, procedurele code bases hebben de neiging om te groeien groot en ingewikkeld in de tijd.

aan de andere kant, met de soort declaratieve benadering die in Terraform wordt gebruikt, geeft de code altijd de laatste staat van uw infrastructuur weer. In één oogopslag kunt u zien wat er momenteel wordt geïmplementeerd en hoe het is geconfigureerd, zonder zich zorgen te maken over de geschiedenis of de timing. Dit maakt het ook gemakkelijk om herbruikbare code te maken, omdat je niet handmatig rekening hoeft te houden met de huidige toestand van de wereld. In plaats daarvan richt je je gewoon op het beschrijven van je gewenste toestand, en Terraform zoekt uit hoe je automatisch van de ene toestand naar de andere kunt komen. Als gevolg daarvan, Terraform codebases hebben de neiging om klein en gemakkelijk te begrijpen te blijven.

natuurlijk zijn er ook nadelen aan declaratieve talen. Zonder toegang tot een volledige programmeertaal is uw expressieve kracht beperkt. Sommige soorten wijzigingen in de infrastructuur, zoals een rolling, zero-downtime implementatie, zijn bijvoorbeeld moeilijk uit te drukken in louter declaratieve termen. Evenzo, zonder de mogelijkheid om “logica” te doen (bijvoorbeeld if-statements, loops), kan het creëren van generieke, herbruikbare code lastig zijn (vooral in CloudFormation). Gelukkig biedt Terraform een aantal krachtige primitieven, zoals invoervariabelen, uitvoervariabelen, modules, create_before_destroy, en count, die het mogelijk maken om schone, configureerbare, modulaire code te maken, zelfs in een declaratieve taal. We zullen deze tools meer bespreken in Deel 4, Hoe herbruikbare infrastructuur te maken met Terraform modules en deel 5, Terraform tips & tricks: loops, if-statements, en valkuilen.

Master Versus Masterless

standaard vereisen Chef, Puppet en SaltStack dat u een masterserver draait voor het opslaan van de status van uw infrastructuur en het distribueren van updates. Elke keer dat u iets in uw infrastructuur wilt bijwerken, gebruikt u een client (bijvoorbeeld een opdrachtregelprogramma) om nieuwe opdrachten uit te geven aan de masterserver, en de masterserver pusht de updates naar alle andere servers, of deze servers halen regelmatig de laatste updates van de masterserver naar beneden.

een masterserver biedt een paar voordelen. Ten eerste is het een centrale plek waar u de status van uw infrastructuur kunt zien en beheren. Veel configuration management tools bieden zelfs een webinterface (bijvoorbeeld de Chef Console, Puppet Enterprise Console) voor de master server om het gemakkelijker te maken om te zien wat er aan de hand is. Ten tweede kunnen sommige masterservers continu op de achtergrond draaien en je configuratie afdwingen. Op die manier, als iemand een handmatige wijziging maakt op een server, kan de masterserver die wijziging terugdraaien om configuratie drift te voorkomen.

echter, het draaien van een masterserver heeft een aantal ernstige nadelen:

  • Extra infrastructuur: u moet een extra server implementeren, of zelfs een cluster van extra servers (voor hoge beschikbaarheid en schaalbaarheid), alleen om de master uit te voeren.
  • onderhoud: u moet de masterserver(s) onderhouden, upgraden, back-uppen, monitoren en schalen.
  • beveiliging: U moet een manier bieden voor de client om te communiceren met de masterserver(s) en een manier voor de masterserver(s) om te communiceren met alle andere servers, wat meestal betekent dat u extra poorten opent en extra authenticatiesystemen configureert, wat uw oppervlak vergroot voor aanvallers.

Chef, Puppet en SaltStack hebben verschillende niveaus van ondersteuning voor masterless modi waar je gewoon hun agent software draait op elk van je servers, meestal op een periodiek schema (bijvoorbeeld een cron-taak die elke 5 minuten draait), en dat gebruiken om de laatste updates van versiebeheer (in plaats van van een masterserver) naar beneden te halen. Dit vermindert aanzienlijk het aantal bewegende delen, maar, zoals besproken in de volgende paragraaf, laat dit nog steeds een aantal onbeantwoorde
vragen, vooral over hoe de servers te voorzien en de agent software op hen te installeren in de eerste plaats.

Ansible, CloudFormation, Heat en Terraform zijn standaard allemaal masterless. Of, om nauwkeuriger te zijn, sommigen van hen kunnen vertrouwen op een master server, maar het is al een deel van de infrastructuur die u gebruikt en niet een extra stuk dat je moet beheren. Terraform communiceert bijvoorbeeld met cloudproviders via de API ‘ s van de cloudprovider, dus in zekere zin zijn de API-servers masterservers, behalve dat ze geen extra infrastructuur of extra authenticatiemechanismen nodig hebben (dat wil zeggen, gebruik gewoon je API-sleutels). Ansible werkt door direct verbinding te maken met elke server via SSH, dus nogmaals, je hoeft geen extra infrastructuur te draaien of extra authenticatie mechanismen te beheren (dat wil zeggen, gebruik gewoon je SSH sleutels).

Agent Versus Agentless

Chef, Puppet en SaltStack vereisen allemaal dat u agent software (bijvoorbeeld Chef Client, Puppet Agent, Salt Minion) installeert op elke server die u wilt configureren. De agent draait meestal op de achtergrond op elke server en is verantwoordelijk voor het installeren van de laatste updates voor Configuratiebeheer.

Dit heeft een paar nadelen:

  • Bootstrapping: Hoe levert u uw servers en installeert u de agent software op hen in de eerste plaats? Sommige hulpprogramma ’s voor Configuratiebeheer schoppen de blik op de weg, ervan uitgaande dat een extern proces dit voor hen zal regelen (bijvoorbeeld, je gebruikt eerst Terraform om een stel servers te implementeren met een VM-image waarin de agent al is geïnstalleerd); Andere hulpprogramma’ s voor Configuratiebeheer hebben een speciaal bootstrapping proces waarbij je eenmalige commando ’s uitvoert om de servers te voorzien met behulp van de cloud provider API’ s en de agent software op die servers via SSH installeert.
  • onderhoud: Je moet de agent software zorgvuldig updaten op een periodieke basis, wees voorzichtig om het synchroon te houden met de master server als er een is. U moet ook de agent software te controleren en opnieuw op te starten als het crasht.
  • beveiliging: als de agent software de configuratie van een masterserver pullt (of een andere server als u geen master gebruikt), dan moet u uitgaande poorten openen op elke server. Als de master server de configuratie naar de agent pusht, dan moet je binnenkomende poorten openen op elke server. In beide gevallen moet je uitzoeken hoe je de agent kunt authenticeren op de server waarmee hij praat. Dit alles verhoogt uw oppervlakte aan aanvallers.

nogmaals, Chef, Puppet, en SaltStack hebben verschillende niveaus van ondersteuning voor agentless modi (bijvoorbeeld salt-ssh), maar deze hebben vaak het gevoel dat ze als een bijzaak werden aangekoppeld en ondersteunen niet altijd de volledige featureset van het configuratiebeheerprogramma. Dat is de reden waarom in het wild, de standaard of idiomatische configuratie voor Chef, Puppet, en SaltStack bijna altijd een agent, en meestal een meester ook.

al deze extra bewegende delen introduceren een groot aantal nieuwe foutmodi in uw infrastructuur. Elke keer dat je om 3 uur ‘ s ochtends een bug rapport krijgt, moet je uitzoeken of het een bug is in je applicatie code, of je IAC code, of de configuratie management client, of de master server(s), of de manier waarop de client praat met de master server(s), of de manier waarop andere servers praten met de master server(s), of…

Ansible, CloudFormation, Heat, en Terraform vereisen dat je geen extra agents installeert. Of, om nauwkeuriger te zijn, sommige van hen vereisen agenten, maar deze zijn meestal al geïnstalleerd als onderdeel van de infrastructuur die u gebruikt. AWS, Azure, Google Cloud en alle andere cloudproviders zorgen bijvoorbeeld voor het installeren, beheren en verifiëren van agentsoftware op elk van hun fysieke servers. Als gebruiker van Terraform hoeft u zich daar geen zorgen over te maken: u geeft alleen commando ‘ s uit en de agenten van de cloudprovider voeren ze voor u uit op al uw servers. Met Ansible moeten uw servers
de SSH-Daemon draaien, wat op de meeste servers toch gebruikelijk is.

grote gemeenschap versus kleine gemeenschap

wanneer u een technologie kiest, kiest u ook een gemeenschap. In veel gevallen kan het ecosysteem rondom het project een grotere impact hebben op uw ervaring dan de inherente kwaliteit van de technologie zelf. De community bepaalt hoeveel mensen bijdragen aan het project, hoeveel plug-ins,
integraties en extensies beschikbaar zijn, hoe gemakkelijk het is om online hulp te vinden (bijvoorbeeld blogberichten, vragen over StackOverflow), en hoe gemakkelijk het is om iemand in te huren om u te helpen (bijvoorbeeld een werknemer, consultant of ondersteunend bedrijf).

Het is moeilijk om een nauwkeurige vergelijking te maken tussen gemeenschappen, maar u kunt een aantal trends herkennen door online te zoeken. De tabel hieronder toont een vergelijking van populaire IAC-tools, met gegevens die ik verzamelde in Mei 2019, waaronder of de IAC-tool open source of closed source is, welke cloudproviders het ondersteunt, het totale aantal bijdragers en sterren op GitHub, hoeveel commits en actieve problemen er waren over een periode van een maand van half April tot half mei, hoeveel open source-bibliotheken beschikbaar zijn voor de tool, het aantal vragen voor die tool op StackOverflow, en het aantal jobs dat de tool vermeldt op Indeed.com.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *