Hvorfor vi bruker Terraform og Ikke Chef, Puppet, Ansible, SaltStack, Eller CloudFormation

Update, November 17, 2016: vi tok denne blogginnlegget serien, utvidet den, og slått den inn i en bok som heter Terraform: Up & Kjører!

Oppdatering 8. juli 2019: Vi har oppdatert denne blogginnleggsserien For Terraform 0.12 og utgitt 2. utgave Av Terraform :Up & Kjører!

Dette Er Del 1 Av Den Omfattende Guide Til Terraform-serien. I introen til serien diskuterte vi hvorfor hvert selskap bør bruke infrastruktur-som-kode (iac). I dette innlegget skal vi diskutere hvorfor Vi valgte Terraform som vårt iac-verktøy.

hvis Du søker På Internett etter «infrastruktur-som-kode», er det ganske enkelt å komme opp med en liste over de mest populære verktøyene:

  • Chef
  • Puppet
  • Ansible
  • SaltStack
  • Cloudform
  • Terraform

Det som ikke er lett er å finne ut hvilken av disse du bør bruke. Alle disse verktøyene kan brukes til å administrere infrastruktur som kode. Alle av dem er åpen kildekode, støttet av store samfunn av bidragsytere, og arbeider med mange forskjellige skyleverandører(med unntak Av CloudFormation, som er lukket kilde og AWS-only). Alle av dem tilbyr enterprise-støtte. Alle er godt dokumentert, både når det gjelder offisiell dokumentasjon og fellesskapsressurser som blogginnlegg og StackOverflow-spørsmål. Så hvordan bestemmer du?det som gjør dette enda vanskeligere er at de fleste sammenligningene du finner på nettet mellom disse verktøyene, gjør lite mer enn å liste de generelle egenskapene til hvert verktøy og få det til å høres ut som om du kan være like vellykket med noen av dem. Og mens det er teknisk sant, er det ikke nyttig. Det er litt som å fortelle en programmeringsnyhet at du kan være like vellykket å bygge et nettsted med PHP, C eller Assembly — en uttalelse som er teknisk sant, men en som utelater en stor mengde informasjon som ville være utrolig nyttig for å ta en god beslutning.I dette innlegget skal vi dykke inn i noen svært spesifikke grunner til hvorfor Vi plukket Terraform over de ANDRE iac-verktøyene. Som med alle teknologiske beslutninger, er det et spørsmål om avveininger og prioriteringer, og mens dine spesielle prioriteringer kan være annerledes enn vår, håper vi at deling av vår tankeprosess vil hjelpe deg med å ta din egen beslutning. Her er de viktigste avveiningene vi vurderte:

  • Configuration Management vs Provisioning
  • Foranderlig Infrastruktur vs Uforanderlig Infrastruktur
  • Prosedyremessig vs Deklarativ
  • Master vs Masterless
  • Agent vs Agentløs
  • Stort Fellesskap vs Lite Samfunn
  • Moden vs Cutting Edge
  • Ved Hjelp Av Flere Verktøy Sammen
  • Kokk, Marionett, Ansible og SaltStack er alle konfigurasjonsverktøy, som betyr at de er designet for å installere og administrere programvare På Eksisterende Servere. CloudFormation Og Terraform er provisioning verktøy, noe som betyr at de er utformet for å forsyne serverne selv (så vel som resten av infrastrukturen, som lastbalancere, databaser, nettverkskonfigurasjon, etc), og forlater jobben med å konfigurere disse serverne til andre verktøy. Disse to kategoriene er ikke gjensidig utelukkende, da de fleste konfigurasjonsadministrasjonsverktøy kan gjøre en viss grad av klargjøring, og de fleste klargjøringsverktøy kan gjøre en viss grad av konfigurasjonsstyring. Men fokuset på konfigurasjonsstyring eller klargjøring betyr at noen av verktøyene kommer til å passe bedre til visse typer oppgaver.spesielt har vi funnet ut at Hvis Du bruker Docker eller Packer, er det store flertallet av konfigurasjonsbehovene dine allerede tatt vare på. Med Docker Og Packer kan du lage bilder (for eksempel beholdere eller virtuelle maskinbilder) som har all programvaren serveren din trenger allerede installert og konfigurert. Når du har et slikt bilde, er alt du trenger en server for å kjøre den. Og hvis alt du trenger å gjøre er å levere en haug med servere, vil Et provisjonsverktøy som Terraform vanligvis være en bedre passform enn et konfigurasjonsadministrasjonsverktøy (her er et eksempel på hvordan Du bruker Terraform til å distribuere Docker på AWS).

    Mutable Infrastructure vs Immutable Infrastructure

    Konfigurasjonsstyringsverktøy som Chef, Puppet, Ansible og SaltStack er vanligvis standard til et foranderlig infrastrukturparadigme. Hvis Du for eksempel ber Chef om å installere En ny Versjon Av OpenSSL, kjører den programvareoppdateringen på de eksisterende serverne dine, og endringene skjer på stedet. Over tid, etter hvert som du bruker flere og flere oppdateringer, bygger hver server opp en unik historie med endringer. Dette fører ofte til et fenomen kjent som konfigurasjonsdrift, hvor hver server blir litt annerledes enn alle de andre, noe som fører til subtile konfigurasjonsfeil som er vanskelig å diagnostisere og nesten umulig å reprodusere.Hvis Du bruker et klargjøringsverktøy Som Terraform for å distribuere maskinbilder laget Av Docker eller Packer, er hver «endring» faktisk en distribusjon av en ny server (akkurat som hver «endring» til en variabel i funksjonell programmering returnerer faktisk en ny variabel). For eksempel, for å distribuere En ny Versjon Av OpenSSL, ville du opprette et nytt bilde ved Hjelp Av Packer eller Docker med den nye versjonen Av OpenSSL allerede installert, distribuere bildet over et sett med helt nye servere, og deretter oppheve distribusjon av de gamle serverne. Denne tilnærmingen reduserer sannsynligheten for konfigurasjonsdrift, gjør det lettere å vite nøyaktig hvilken programvare som kjører på en server, og lar deg trivielt distribuere en tidligere versjon av programvaren når som helst. Selvfølgelig er det mulig å tvinge konfigurasjonsstyringsverktøy til å gjøre uforanderlige distribusjoner også, men det er ikke den idiomatiske tilnærmingen for disse verktøyene, mens det er en naturlig måte å bruke klargjøringsverktøy på.

    Procedural vs Declarative

    Chef og Ansible oppfordrer til en prosessuell stil der du skriver kode som angir, trinnvis, hvordan du skal oppnå ønsket sluttstatus. Terraform, CloudFormation, SaltStack og Puppet oppfordrer alle til en mer deklarativ stil der du skriver kode som angir ønsket sluttstatus, og iac-verktøyet selv er ansvarlig for å finne ut hvordan du oppnår den tilstanden.la oss for eksempel si at du ønsket å distribuere 10 servere («EC2 Instances» I AWS lingo) for å kjøre v1 av en app. Her er et forenklet eksempel På En Ansible-mal som gjør dette med en prosessuell tilnærming:

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

    Og her er et forenklet eksempel På En Terraform-mal som gjør det samme ved hjelp av en deklarativ tilnærming:

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

    nå på overflaten kan disse to tilnærmingene se like ut, og når du først utfører Dem Med Ansible eller Terraform, de vil gi lignende resultater. Det interessante er hva som skjer når du vil gjøre en endring.

    tenk deg for eksempel at trafikken har gått opp og du vil øke antall servere til 15. Med Ansible er prosesskoden du skrev tidligere ikke lenger nyttig; hvis du bare oppdaterte antall servere til 15 og reran den koden, ville den distribuere 15 nye servere, noe som gir deg 25 totalt! Så i stedet må du være klar over hva som allerede er distribuert og skrive et helt nytt prosessskript for å legge til de 5 nye serverne:

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

    med deklarativ kode, siden alt du gjør er å erklære slutttilstanden du vil ha, Og Terraform finner ut hvordan Du kommer til den slutttilstanden, Vil Terraform også være oppmerksom på hvilken tilstand Den opprettet tidligere. Derfor, for å distribuere 5 flere servere, er alt du trenger å gjøre, gå tilbake til samme Terraform-mal og oppdater tellingen fra 10 til 15:

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

    Hvis Du utførte denne malen, Ville Terraform innse at Den allerede hadde opprettet 10 servere, og derfor at alt det trengte å gjøre var å opprette 5 nye servere. Faktisk, før du kjører denne malen, kan Du bruke Terraformsplan kommando for å forhåndsvise hvilke endringer det ville gjøre:

    $ 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.

    hva skjer når du vil distribuere v2 tjenesten? Med prosessmetoden er begge dine tidligere Ansible-maler igjen ikke nyttige, så du må skrive enda en mal for å spore opp de 10 serverne du distribuerte tidligere(eller var det 15 nå ?) og nøye oppdatere hver enkelt til den nye versjonen. Med terraforms deklarative tilnærming går du tilbake til nøyaktig samme mal igjen og endrer bare ami-versjonsnummeret til v2:

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

    Åpenbart er eksemplene ovenfor forenklet. Ansible tillater deg å bruke tagger for å søke etter eksisterende EC2-forekomster før du distribuerer nye (f. eks. ved å bruke instance_tags og count_tag parametere), men å måtte manuelt finne ut denne typen logikk for hver enkelt ressurs du administrerer Med Ansible, basert på hver ressursens tidligere historie, kan være overraskende komplisert (f. eks. finne eksisterende forekomster ikke bare etter tag, men også bildeversjon, availability zone, etc). Dette fremhever to store problemer med prosessuelle iac verktøy:

    1. Når du arbeider med prosesskode, tilstanden til infrastrukturen er ikke fullt fanget i koden. Å lese gjennom de tre Ansible malene vi opprettet ovenfor, er ikke nok til å vite hva som er distribuert. Du må også vite rekkefølgen der vi brukte disse malene. Hadde vi brukt dem i en annen rekkefølge, kan vi ende opp med annen infrastruktur, og det er ikke noe du kan se i kodebasen selv. Med andre ord, å resonnere om En Ansible eller Kokk kodebase, må du vite hele historien om hver endring som noen gang har skjedd.
    2. gjenbrukbarheten av prosesskode er iboende begrenset fordi du må manuelt ta hensyn til kodebasens nåværende tilstand. Siden denne tilstanden er i stadig endring, kan koden du brukte for en uke siden ikke lenger være brukbar fordi den ble designet for å endre en tilstand av infrastrukturen din som ikke lenger eksisterer. Som et resultat, prosessuelle kodebaser tendens til å vokse store og kompliserte over tid.

    på den annen side, med den typen deklarativ tilnærming som brukes I Terraform, representerer koden alltid den nyeste tilstanden til infrastrukturen din. På et øyeblikk kan du se hva som for øyeblikket er distribuert og hvordan det er konfigurert, uten å måtte bekymre deg for historie eller timing. Dette gjør det også enkelt å lage gjenbrukbar kode, da du ikke trenger å manuelt ta hensyn til verdens nåværende tilstand. I stedet fokuserer du bare på å beskrive ønsket tilstand, Og Terraform finner ut hvordan du kommer fra en stat til den andre automatisk. Som et resultat har Terraform-kodebaser en tendens til å være små og enkle å forstå.

    selvfølgelig er det ulemper med deklarative språk også. Uten tilgang til et fullt programmeringsspråk er din uttrykksfulle kraft begrenset. For eksempel er enkelte typer infrastrukturendringer, for eksempel en rullende distribusjon uten nedetid, vanskelig å uttrykke i rent deklarative termer. Hvis-setninger, looper), kan det være vanskelig å lage generisk, gjenbrukbar kode (spesielt I CloudFormation). Heldigvis Gir Terraform en rekke kraftige primitiver, som inngangsvariabler, utgangsvariabler, moduler, create_before_destroy og count, som gjør det mulig å lage ren, konfigurerbar, modulær kode selv i et deklarativt språk. Vi diskuterer disse verktøyene mer I Del 4, hvordan lage gjenbrukbar infrastruktur Med Terraform-moduler Og Del 5, Terraform tips & triks: looper, if-setninger og fallgruver.

    Master Versus Masterless

    Som standard Krever Chef, Puppet og SaltStack at du kjører en master server for lagring av tilstanden til infrastrukturen og distribusjon av oppdateringer. Hver gang du vil oppdatere noe i infrastrukturen din, bruker du en klient (f.eks. et kommandolinjeverktøy) til å utstede nye kommandoer til masterserveren, og masterserveren skyver enten oppdateringene ut til alle de andre serverne, eller de serverne trekker de siste oppdateringene ned fra masterserveren regelmessig.

    en master server tilbyr noen fordeler. Først er det et enkelt, sentralt sted hvor du kan se og administrere statusen til infrastrukturen din. Mange konfigurasjonsverktøy gir til og med et webgrensesnitt (F. eks. Chef Console, Puppet Enterprise Console) for master server for å gjøre det lettere å se hva som skjer. For det andre kan noen master-servere kjøre kontinuerlig i bakgrunnen, og håndheve konfigurasjonen. På den måten, hvis noen gjør en manuell endring på en server, kan hovedserveren gå tilbake til denne endringen for å forhindre konfigurasjonsdrift.

    men å måtte kjøre en master server har noen alvorlige ulemper:Ekstra infrastruktur: Du må distribuere en ekstra server, eller til og med en klynge med ekstra servere (for høy tilgjengelighet og skalerbarhet), bare for å kjøre mesteren.Vedlikehold: du må vedlikeholde, oppgradere, sikkerhetskopiere, overvåke og skalere hovedserveren(e).

  • Sikkerhet: du må gi en måte for klienten å kommunisere til master-serveren (e) og en måte for master-serveren (e) å kommunisere med alle de andre serverne, som vanligvis betyr å åpne ekstra porter og konfigurere ekstra autentiseringssystemer, som alle øker overflaten til angripere.Chef, Puppet og SaltStack har varierende nivåer av støtte for masterless modes hvor du bare kjører agentprogramvaren på hver av serverne dine, vanligvis på en periodisk tidsplan (f.eks. en cron-jobb som kjører hvert 5. minutt), og bruk den til å trekke ned de siste oppdateringene fra versjonskontroll (i stedet for fra en master server). Dette reduserer antall bevegelige deler betydelig, men som diskutert i neste avsnitt, etterlater dette fortsatt en rekke ubesvarte spørsmål, spesielt om hvordan man klargjør serverne og installerer agentprogramvaren på dem i utgangspunktet.

    Ansible, CloudFormation, Heat og Terraform er alle mesterløse som standard. Eller, for å være mer nøyaktig, noen av dem kan stole på en master server, men det er allerede en del av infrastrukturen du bruker og ikke et ekstra stykke du må administrere. For eksempel Kommuniserer Terraform med skyleverandører ved Hjelp av skyleverandørens Apier, SÅ PÅ en måte ER API-serverne master-servere, bortsett fra at DE ikke krever ekstra infrastruktur eller ekstra autentiseringsmekanismer (dvs.bare bruk API-nøklene dine). Ansible fungerer ved å koble direkte til hver server over SSH, så igjen trenger du ikke å kjøre ekstra infrastruktur eller administrere ekstra autentiseringsmekanismer(dvs. bare bruk SSH-tastene).

    Agent Versus Agentless

    Chef, Puppet og SaltStack krever at du installerer agentprogramvare (F. eks. Chef Client, Puppet Agent, Salt Minion) på hver server du vil konfigurere. Agenten kjører vanligvis i bakgrunnen på hver server og er ansvarlig for å installere de nyeste konfigurasjonsadministrasjonsoppdateringene.

    Dette har noen ulemper:

    • Bootstrapping: Hvordan klargjør du serverne dine og installerer agentprogramvaren på dem i utgangspunktet? Du bruker Først Terraform til å distribuere En haug med servere med ET VM-bilde som har agenten allerede installert); andre konfigurasjonsadministrasjonsverktøy har en spesiell bootstrapping-prosess der du kjører engangskommandoer for å klargjøre serverne ved hjelp av skyleverandørens Apier og installere agentprogramvaren på disse serverne over SSH.
    • Vedlikehold: Du må nøye oppdatere agentprogramvaren regelmessig, og være forsiktig med å holde den synkronisert med hovedserveren hvis det er en. Du må også overvåke agentprogramvaren og starte den på nytt hvis den krasjer.
    • Sikkerhet: hvis agentprogramvaren trekker ned konfigurasjonen fra en masterserver (eller en annen server hvis du ikke bruker en masterserver), må du åpne utgående porter på hver server. Hvis hovedserveren skyver konfigurasjonen til agenten, må du åpne innkommende porter på hver server. I begge tilfeller må du finne ut hvordan du autentiserer agenten til serveren den snakker med. Alt dette øker overflatearealet til angripere.Igjen Har Chef, Puppet og SaltStack varierende nivåer av støtte for agentløse moduser(f. eks. Derfor inneholder standard eller idiomatisk konfigurasjon for Kokk, Marionett og SaltStack nesten alltid en agent, og vanligvis en mester også.

      Alle disse ekstra bevegelige delene introduserer et stort antall nye feilmoduser i infrastrukturen din. Hver gang du får en feilrapport klokka 3, må du finne ut om det er en feil i programkoden din, ELLER IAC-koden din, eller konfigurasjonsadministrasjonsklienten, eller master-serveren(e), eller måten klienten snakker til master-serveren(e), eller måten andre servere snakker til master-serveren(e), eller … Eller, for å være mer nøyaktig, noen av dem krever agenter, men disse er vanligvis allerede installert som en del av infrastrukturen du bruker. FOR EKSEMPEL TAR AWS, Azure, Google Cloud og alle andre skyleverandører seg av å installere, administrere og godkjenne agentprogramvare på hver av sine fysiske servere. Som Bruker Av Terraform trenger du ikke å bekymre deg for noe av det: du utsteder bare kommandoer og skyleverandørens agenter utfører dem for deg på alle serverne dine. Med Ansible må serverne dine kjøre SSH-Demonen, som er vanlig å kjøre på de fleste servere uansett.

      Stort Fellesskap vs Lite Samfunn

      Når du velger en teknologi, velger du også et fellesskap. I mange tilfeller kan økosystemet rundt prosjektet ha større innvirkning på din erfaring enn den iboende kvaliteten på selve teknologien. Samfunnet bestemmer hvor mange som bidrar til prosjektet, hvor mange plugin-moduler, integrasjoner og utvidelser som er tilgjengelige, hvor lett det er å finne hjelp på nettet (for eksempel blogginnlegg, spørsmål om StackOverflow), og hvor lett det er å ansette noen til å hjelpe deg (for eksempel en ansatt, konsulent eller støtteselskap).

      det er vanskelig å gjøre en nøyaktig sammenligning mellom samfunn, men du kan se noen trender ved å søke på nettet. Tabellen nedenfor viser en sammenligning av populære iac-verktøy, med data jeg samlet Inn I Mai 2019, inkludert om iac-verktøyet er åpen kildekode eller lukket kilde, hvilke skyleverandører den støtter, totalt antall bidragsytere og stjerner på GitHub, hvor mange forpliktelser og aktive problemer det var over en måneds periode fra midten av April til Midten Av Mai, hvor mange open source-biblioteker er tilgjengelige for verktøyet, antall spørsmål som er oppført for det verktøyet På StackOverflow, og antall jobber som nevner verktøyet på Indeed.com.

  • Legg igjen en kommentar

    Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *