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

Update, November 17, 2016: otimme tämän blogikirjoituksen sarjan, laajensimme sitä ja muutimme sen kirjaksi nimeltä Terraform: Up & Running!

Update, July 8, 2019: olemme päivittäneet tätä blogikirjoitussarjaa terraform 0.12: lle ja julkaisseet 2. painoksen terraform: Up & Running!

Tämä on osa 1 The Comprehensive Guide to Terraform-kirjasarjaa. Sarjan introssa pohdimme, miksi jokaisen yrityksen tulisi käyttää infrastructure-as-code (IAC) – järjestelmää. Tässä viestissä aiomme keskustella siitä, miksi valitsimme TERRAFORMIN IAC-työkaluksi.

Jos Internetistä etsii ”infra-as-koodia”, on melko helppo keksiä lista suosituimmista työkaluista:

  • Chef
  • Puppet

  • Ansable
  • SaltStack
  • Pilviformaatio
  • Terraform

ei ole helppoa miettiä, mitä näistä kannattaa käyttää. Kaikkia näitä työkaluja voidaan käyttää infrastruktuurin hallintaan koodina. Kaikki ne ovat avointa lähdekoodia, jota tukevat suuret avustajien yhteisöt, ja toimivat monien eri pilvipalvelujen tarjoajien kanssa (poikkeuksena CloudFormation, joka on suljettu lähdekoodi ja AWS-vain). Ne kaikki tarjoavat yritystukea. Kaikki ne ovat hyvin dokumentoituja, sekä virallisen dokumentaation että yhteisön resurssien, kuten blogikirjoitusten ja StackOverflow-kysymysten osalta. Miten päätät?

mikä tekee tästä vielä vaikeampaa on, että useimmat vertailut löydät verkossa näiden työkalujen tehdä vain luetella yleisiä ominaisuuksia kunkin työkalun ja saada se kuulostaa voit olla yhtä onnistunut tahansa niistä. Ja vaikka se on teknisesti totta, siitä ei ole apua. Se on vähän kuin kertoa ohjelmointi newbie että voit olla yhtä onnistunut rakentaa verkkosivuilla PHP, C, tai Assembly — lausuma, joka on teknisesti totta, mutta joka jättää valtava määrä tietoa, joka olisi uskomattoman hyödyllistä tehdä hyvä päätös.

tässä viestissä sukellamme joihinkin hyvin erityisiin syihin, miksi valitsimme Terraformin muiden IAC-työkalujen sijaan. Kuten kaikissa teknologiapäätöksissä, kyse on kompromisseista ja prioriteeteista, ja vaikka erityiset prioriteettisi saattavat olla erilaisia kuin meidän, toivomme, että ajatusprosessimme jakaminen auttaa sinua tekemään oman päätöksesi. Tässä ovat tärkeimmät kompromissit harkitsimme:

  • konfiguraationhallinta vs. Provisioning
  • Procedural vs. Declarative
  • Master vs. Masterless
  • agentti vs. Agentless
  • suuri yhteisö vs. pieni yhteisö
  • kypsä vs. Cutting Edge
  • useiden työkalujen käyttäminen yhdessä

Chef, Puppet, Ansable ja SaltStack ovat kaikki konfiguraationhallinnan välineitä, mikä tarkoittaa, että ne on suunniteltu asentamaan ja hallitsemaan ohjelmistoja olemassa oleville palvelimille. CloudFormation ja Terraform ovat varaustyökaluja, mikä tarkoittaa, että ne on suunniteltu tarjoamaan palvelimet itse (sekä loput infrastruktuurista, kuten kuormataseet, tietokannat, verkkoasetukset, jne), jättäen tehtävän määrittää nämä palvelimet muihin työkaluihin. Nämä kaksi luokkaa eivät sulje toisiaan pois, koska useimmat konfiguraationhallintatyökalut voivat tehdä jonkin verran varauksia ja useimmat varaustyökalut voivat tehdä jonkin verran konfiguraationhallintaa. Mutta keskittyminen kokoonpanon hallinta tai provisioning tarkoittaa, että jotkut työkalut ovat menossa paremmin sopii tietyntyyppisiä tehtäviä.

erityisesti olemme huomanneet, että jos käytät Dockeria tai Packeria, valtaosa konfiguraationhallintatarpeistasi on jo hoidettu. Docker ja Packer, voit luoda kuvia (kuten kontteja tai virtuaalikoneen kuvia), jotka ovat kaikki ohjelmiston palvelimen tarvitsee jo asennettu ja määritetty. Kun sinulla on tällainen kuva, kaikki mitä tarvitset on palvelin ajaa sitä. Ja jos sinun tarvitsee vain tarjota joukko palvelimia, niin varaustyökalu, kuten Terraform, tulee yleensä olemaan sopivampi kuin konfiguraationhallintatyökalu (tässä on esimerkki siitä, miten terraformia käytetään Dockerin käyttöönottoon AWS: ssä).

Mutable Infrastructure vs Immutable Infrastructure

Configuration management tools kuten Chef, Puppet, Ansable, and SaltStack tyypillisesti oletuksena mutable infrastructure paradigm. Jos esimerkiksi käsket Chefiä asentamaan uuden version OpenSSL: stä, se suorittaa ohjelmistopäivityksen olemassa olevilla palvelimillasi ja muutokset tapahtuvat paikallaan. Ajan mittaan, kun käytät enemmän ja enemmän päivityksiä, jokainen palvelin rakentaa ainutlaatuinen historia muutoksia. Tämä johtaa usein ilmiöön nimeltä configuration drift, jossa jokainen palvelin tulee hieman erilainen kuin kaikki muut, johtaa hienovarainen kokoonpano vikoja, joita on vaikea diagnosoida ja lähes mahdotonta toistaa.

Jos käytät terraformin kaltaista varaustyökalua Dockerin tai Packerin luomien konekuvien käyttöönottoon, niin jokainen ”muutos” on itse asiassa uuden palvelimen käyttöönotto (aivan kuten jokainen funktionaalisen ohjelmoinnin muuttujan ”muutos” itse asiassa palauttaa uuden muuttujan). Jos haluat esimerkiksi ottaa käyttöön uuden version OpenSSL: stä, Luo uusi kuva Packerin tai Dockerin avulla, kun OpenSSL: n uusi versio on jo asennettu, ota kuva käyttöön täysin uusilla palvelimilla ja poista vanhat palvelimet käytöstä. Tämä lähestymistapa vähentää todennäköisyyttä kokoonpano drift bugeja, helpottaa tietää tarkalleen, mitä ohjelmisto on käynnissä palvelimella, ja voit trivially käyttöön aiemman version ohjelmiston milloin tahansa. Tietenkin, se on mahdollista pakottaa konfiguraationhallintatyökalut tehdä muuttumaton käyttöönottoja liian, mutta se ei ole idiomaattinen lähestymistapa näiden työkalujen, kun taas se on luonnollinen tapa käyttää provisioning työkaluja.

Procedural vs. Declarative

Chef ja Ansible kannustavat proseduraaliseen tyyliin, jossa kirjoitetaan koodi, joka määrittää vaiheittain, miten saavutetaan jokin haluttu lopputila. Terraform, CloudFormation, SaltStack ja Puppet kannustavat deklaratiivisempaan tyyliin, jossa kirjoitat koodia, joka määrittää haluamasi lopputilan, ja IAC-työkalu itse on vastuussa sen selvittämisestä, miten tämä tila saavutetaan.

esimerkiksi, sanotaan, että halusit ottaa käyttöön 10 palvelinta (”EC2 Instances” AWS lingossa) ajaaksesi sovelluksen v1. Tässä on yksinkertaistettu esimerkki mahdollisesta mallista, joka tekee tämän proseduraalisella lähestymistavalla:

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

ja tässä on yksinkertaistettu esimerkki terraform-mallista, joka tekee saman asian deklaratiivisella lähestymistavalla:

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

nyt pinnalla nämä kaksi lähestymistapaa voivat näyttää samanlaisilta, ja kun ne suoritetaan alun perin mahdollisesti tai Terraformilla, ne tuottavat samanlaisia tuloksia. Mielenkiintoista on, mitä tapahtuu, kun haluaa tehdä muutoksen.

esimerkiksi kuvittele, että liikenne on lisääntynyt ja haluat kasvattaa palvelimien määrän 15: een. Kun se on mahdollista, aiemmin kirjoittamasi menettelytapakoodi ei ole enää hyödyllinen; jos vain päivittäisit palvelimien määrän 15: een ja palauttaisit koodin, se ottaisi käyttöön 15 uutta palvelinta, jolloin saat yhteensä 25! Joten sen sijaan, sinun täytyy olla tietoinen siitä, mitä on jo otettu käyttöön ja kirjoittaa täysin uusi menettely skripti lisätä 5 uutta palvelinta:

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

deklaratiivisella koodilla, koska et tee muuta kuin ilmoitat haluamasi lopputilan, ja Terraform selvittää, miten pääset tuohon päätilaan, Terraform on myös tietoinen mistä tahansa aiemmin luomastaan tilasta. Jos haluat ottaa käyttöön 5 palvelinta lisää, sinun tarvitsee vain palata samaan Terraform-malliin ja päivittää lukumäärä 10: stä 15: een:

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

jos suoritit tämän mallin, Terraform tajuaisi, että se oli jo luonut 10 palvelinta ja että sen tarvitsi vain luoda 5 uutta palvelinta. Itse asiassa, ennen tämän mallin ajamista, voit käyttää Terraformin plan komentoa esikatsella mitä muutoksia se tekisi:

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

nyt mitä tapahtuu, kun haluat ottaa v2 palvelun käyttöön? Menettelyllisellä lähestymistavalla molemmat aikaisemmat mahdolliset mallipohjat eivät taaskaan ole hyödyllisiä, joten sinun on kirjoitettava vielä yksi malli jäljittääksesi 10 palvelinta, jotka otit käyttöön aiemmin (vai oliko se nyt 15?) ja huolellisesti päivittää jokainen uuteen versioon. Terraformin deklaratiivisella lähestymistavalla palataan jälleen täsmälleen samaan malliin ja yksinkertaisesti vaihdetaan ami-versionumero v2:

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

ilmeisesti yllä olevat esimerkit ovat yksinkertaistettuja. Ansiblen avulla voit käyttää tageja etsiäksesi olemassa olevia EC2-ilmentymiä ennen uusien käyttöönottoa (esim. käyttämällä instance_tags ja count_tag parametreja), mutta tällaisen logiikan selvittäminen manuaalisesti jokaiselle resurssille, jota hallinnoit Oppiblen kanssa, voi olla yllättävän monimutkaista (esim. löytää olemassa olevat esiintymät paitsi tag, mutta myös kuvaversio, saatavuus vyöhyke, jne). Tämä tuo esiin kaksi merkittävää ongelmaa, jotka liittyvät vaikutustenarviointia koskeviin menettelysääntöihin:

  1. menettelysäännöstöä käsiteltäessä infrastruktuurin tilaa ei ole täysin kuvattu säännöstössä. Lukeminen läpi kolme Ansable malleja loimme edellä ei riitä tietää, mitä on otettu käyttöön. Sinun pitäisi myös tietää, missä järjestyksessä sovelsimme niitä malleja. Jos olisimme soveltaneet niitä eri järjestyksessä, saatamme päätyä eri infrastruktuuriin, eikä sitä voi nähdä itse koodipohjassa. Toisin sanoen, järkeilläksemme mahdollisesta tai Kokkikoodebaasista, sinun on tunnettava kaikkien koskaan tapahtuneiden muutosten koko historia.
  2. prosessikoodin uudelleenkäytettävyys on luonnostaan rajallinen, koska koodebaasin nykytila on otettava manuaalisesti huomioon. Koska tämä tila muuttuu jatkuvasti, viikko sitten käyttämäsi koodi ei ehkä ole enää käyttökelpoinen, koska se on suunniteltu muokkaamaan infrastruktuurisi tilaa, jota ei enää ole. Tämän seurauksena menettelysääntöjen perustat kasvavat yleensä suuriksi ja monimutkaisiksi ajan myötä.

toisaalta terraformissa käytetyllä deklaratiivisella lähestymistavalla koodi edustaa aina infrastruktuurin viimeisintä tilaa. Yhdellä silmäyksellä, voit kertoa, mitä tällä hetkellä käytössä ja miten se on määritetty, ilman huolta historiasta tai ajoituksesta. Tämä helpottaa myös uudelleenkäytettävän koodin luomista, sillä sinun ei tarvitse manuaalisesti ottaa huomioon maailman nykytilaa. Sen sijaan keskityt vain kuvailemaan haluamaasi tilaa, ja Terraform selvittää, miten päästä tilasta toiseen automaattisesti. Tämän seurauksena terraformiset koodibaasit pysyvät yleensä pieninä ja helppotajuisina.

deklaratiivisissa kielissäkin on toki varjopuolia. Ilman pääsyä täyteen ohjelmointikieleen ilmaisuvoimasi on rajallinen. Esimerkiksi tietyntyyppisiä infrastruktuurimuutoksia, kuten jatkuvaa, nollakatkoaikaista käyttöönottoa, on vaikea ilmaista puhtaasti deklaratiivisin termein. Samoin, ilman kykyä tehdä ”logiikkaa” (esim.if-lauseet, silmukat), yleisen, uudelleenkäytettävän koodin luominen voi olla hankalaa (erityisesti Pilvimuotoilussa). Onneksi Terraform tarjoaa joukon voimakkaita primitiivejä, kuten tulomuuttujat, lähtömuuttujat, moduulit, create_before_destroy ja count, joiden avulla on mahdollista luoda puhdasta, konfiguroitavaa, modulaarista koodia jopa deklaratiivisella kielellä. Näistä työkaluista keskustellaan lisää osassa 4, kuinka luodaan uudelleen käytettävää infrastruktuuria Terraform-moduuleilla ja osassa 5, Terraform-vinkkejä & tricks: loops, if-statements, and sudenkuopat.

Master Versus Masterless

oletuksena Chef, Puppet ja SaltStack vaativat kaikki, että käytät master-palvelinta infrastruktuurisi tilan tallentamiseen ja päivitysten jakeluun. Aina kun haluat päivittää jotain infrastruktuurissasi, käytät asiakasta (esim.komentorivityökalua) uusien komentojen antamiseen pääpalvelimelle, ja pääpalvelin joko työntää päivitykset kaikille muille palvelimille tai nämä palvelimet vetävät uusimmat päivitykset säännöllisesti alas pääpalvelimelta.

master server tarjoaa muutamia etuja. Ensinnäkin, se on yksi, keskeinen paikka, jossa voit nähdä ja hallita tilaa infrastruktuurin. Monet konfiguraationhallintatyökalut tarjoavat jopa web-käyttöliittymän (esim.Chef-konsoli, Puppet Enterprise-konsoli) pääpalvelimelle, jotta on helpompi nähdä, mitä tapahtuu. Toiseksi jotkut pääpalvelimet voivat toimia jatkuvasti taustalla ja valvoa määritystäsi. Tällä tavalla, jos joku tekee manuaalisen muutoksen palvelimella, master server voi peruuttaa kyseisen muutoksen estää määritys drift.

pääpalvelimen ajamisella on kuitenkin vakavia haittoja:

  • Extra infrastructure: sinun täytyy ottaa käyttöön ylimääräinen palvelin, tai jopa klusterin ylimääräisiä palvelimia (korkean käytettävyyden ja skaalautuvuuden vuoksi), vain ajaa master.
  • huolto: sinun on ylläpidettävä, päivitettävä, varmuuskopioitava, valvottava ja skaalattava pääpalvelimia.
  • Turvallisuus: sinun täytyy tarjota tapa, jolla asiakas voi kommunikoida pääpalvelimelle (- palvelimille) ja tapa, jolla pääpalvelimet voivat kommunikoida kaikkien muiden palvelimien kanssa, mikä tarkoittaa tyypillisesti lisäporttien avaamista ja ylimääräisten todennusjärjestelmien määrittämistä, mikä kaikki lisää pinta-alaasi hyökkääjille.

Chefillä, Puppetilla ja Saltstackilla on vaihteleva tuki masterless-moodeille, joissa vain suoritat heidän agenttiohjelmistonsa kullakin palvelimellasi, tyypillisesti määräaikaisella aikataululla (esim.cron-työ, joka suoritetaan 5 minuutin välein), ja käytä sitä vetääksesi uusimmat päivitykset versionhallinnasta (eikä pääpalvelimesta). Tämä vähentää merkittävästi liikkuvien osien määrää, mutta kuten seuraavassa osassa käsitellään, tämä jättää edelleen useita vastaamattomia
kysymyksiä, erityisesti siitä, miten palvelimet tulisi toimittaa ja agenttiohjelmisto asentaa niihin ylipäätään.

Ansable, CloudFormation, Heat ja Terraform ovat kaikki oletuksena masterittomia. Tai, tarkemmin, jotkut niistä voivat luottaa master server, mutta se on jo osa infrastruktuuria käytät eikä ylimääräinen pala sinun täytyy hallita. Esimerkiksi Terraform kommunikoi pilvipalvelujen tarjoajien kanssa käyttämällä pilvipalvelujen tarjoajan sovellusliittymiä, joten jossain mielessä API-palvelimet ovat pääpalvelimia, paitsi että ne eivät vaadi ylimääräistä infrastruktuuria tai ylimääräisiä todennusmekanismeja (eli käytä vain API-avaimia). Ansible toimii liittämällä suoraan kunkin palvelimen yli SSH, joten jälleen, sinun ei tarvitse suorittaa mitään ylimääräistä infrastruktuuria tai hallita ylimääräisiä todennusmekanismeja (eli, vain käyttää SSH avaimet).

Agent Versus Agentless

Chef, Puppet ja SaltStack vaativat kaikki, että asennat agenttiohjelmiston (esim.Chef Client, Puppet Agent, Salt Minion) jokaiselle määritettävälle palvelimelle. Agentti toimii tyypillisesti taustalla jokaisella palvelimella ja vastaa
uusimpien konfiguraationhallintapäivitysten asentamisesta.

tällä on muutamia haittoja:

  • Bootstrapping: Miten tarjoat palvelimiasi ja asennat niihin agenttiohjelmiston? Jotkut konfiguraationhallintatyökalut potkivat tölkin tielle olettaen, että jokin ulkoinen prosessi hoitaa tämän (esim.käytät ensin Terraformia ottaaksesi käyttöön joukon palvelimia, joissa on VM-kuva, jossa agentti on jo asennettu); muissa konfiguraationhallintatyökaluissa on erityinen bootstrapping-prosessi, jossa suoritat kertaluonteisia komentoja palvelimien toimittamiseksi pilvipalvelujen tarjoajan sovellusliittymiä käyttäen ja agenttiohjelmiston asentamiseksi kyseisille palvelimille SSH: n kautta.
  • huolto: Agenttiohjelmisto on päivitettävä huolellisesti määräajoin, ja on oltava varovainen, jotta se pysyy synkronoituna pääpalvelimen kanssa, jos sellainen on olemassa. Sinun täytyy myös seurata agentti ohjelmisto ja käynnistä se uudelleen, jos se kaatuu.
  • turvallisuus: Jos agenttiohjelmisto poistaa määritykset pääpalvelimelta (tai joltain muulta palvelimelta, jos et käytä pääpalvelinta), sinun on avattava lähtöportit jokaisella palvelimella. Jos pääpalvelin työntää määrityksen agentille, sinun on avattava saapuvia portteja jokaisella palvelimella. Kummassakin tapauksessa, sinun täytyy selvittää, miten todentaa agentti palvelimelle, jolle se puhuu. Kaikki tämä lisää pinta-alaa hyökkääjille.

jälleen kerran Chefillä, Puppetilla ja Saltstackilla on vaihtelevia tukitasoja agentittomille tiloille (esim.salt-ssh), mutta nämä tuntuvat usein siltä kuin ne olisi laitettu päälle jälkikäteen eivätkä aina tue konfiguraationhallintatyökalun kaikkia ominaisuuksia. Siksi luonnossa, oletus-tai idiomaattinen kokoonpano Chef, Puppet, ja SaltStack lähes aina sisältää agentti, ja yleensä mestari liian.

kaikki nämä ylimääräiset liikkuvat osat tuovat infrastruktuuriisi suuren määrän uusia vikatiloja. Aina kun saat vikailmoituksen kello 3 aamulla, sinun on selvitettävä, onko kyseessä vika sovelluskoodissasi, IAC-koodissasi, konfiguraationhallintaohjelmassasi tai pääpalvelimessa tai muissa palvelimissa, tai miten asiakas puhuu pääpalvelimelle tai-palvelimille, tai…

Ansible, CloudFormation, Heat ja Terraform eivät vaadi ylimääräisten agenttien asentamista. Tai, tarkemmin, jotkut niistä vaativat agentteja, mutta nämä ovat yleensä jo asennettu osana infrastruktuuria käytät. Esimerkiksi AWS, Azure, Google Cloud ja kaikki muut pilvipalvelujen tarjoajat huolehtivat agenttiohjelmiston asentamisesta, hallinnoinnista ja todentamisesta jokaisella fyysisellä palvelimellaan. Terraformin käyttäjänä sinun ei tarvitse huolehtia mistään näistä: annat vain komentoja ja pilvipalveluntarjoajan agentit suorittavat
ne puolestasi kaikilla palvelimillasi. Ansiblen avulla palvelimiesi täytyy suorittaa
SSH-taustaprosessi, joka on yleinen useimmissa palvelimissa muutenkin.

suuri yhteisö vs pieni yhteisö

aina kun valitset jonkin tekniikan, valitset myös yhteisön. Monissa tapauksissa projektin ekosysteemillä voi olla suurempi vaikutus kokemukseesi kuin itse teknologian luontaisella laadulla. Yhteisö määrittää, kuinka monta ihmistä osallistuu projektiin, kuinka monta laajennusta,
integraatiota ja laajennuksia on saatavilla, kuinka helppoa on löytää apua netistä (esim.blogikirjoituksia, kysymyksiä StackOverflow ’ sta) ja kuinka helppoa on palkata joku auttamaan (esim. työntekijä, konsultti tai tukiyhtiö).

paikkakuntien tarkkaa vertailua on vaikea tehdä, mutta joitain trendejä voi bongata etsimällä netistä. Alla olevassa taulukossa on esitetty vertailu suosituista IAC-työkaluista toukokuun 2019 aikana keräämiini tietoihin, mukaan lukien onko IAC-työkalu avointa vai suljettua lähdekoodia, mitä pilvipalvelujen tarjoajia se tukee, osallistujien ja tähtien kokonaismäärä GitHubissa, kuinka monta toimitusta ja aktiivista ongelmaa oli yhden kuukauden aikana huhtikuun puolivälistä toukokuun puoliväliin, kuinka monta avoimen lähdekoodin kirjastoa työkalulle on saatavilla, kuinka monta StackOverflow-työkalussa lueteltua kysymystä ja niiden työpaikkojen määrä, jotka mainitsevat työkalun Indeed.com.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *