miért használjuk a Terraform-ot és nem a Chef-et, a bábot, az Ansible-t, a SaltStack-et vagy a CloudFormation-t

frissítés, 2016. November 17: vettük ezt a blogbejegyzést, kibővítettük, és Terraform: Up & futás!

frissítés, Július 8, 2019: frissítettük ezt a blogbejegyzést sorozat Terraform 0.12 és kiadta a 2. kiadás Terraform: Up & futás!

Ez a Terraform sorozat átfogó útmutatójának 1. része. A sorozat bevezetőjében megvitattuk, hogy miért kell minden vállalatnak infrastruktúra-kódot (IAC) használnia. Ebben a bejegyzésben, fogunk beszélni, hogy miért választottuk Terraform mi IAC eszköz választás.

Ha az interneten “infrastruktúra-kódként” keres, akkor elég könnyű összeállítani a legnépszerűbb eszközök listáját:

  • SaltStack
  • CloudFormation
  • Terraform

mi nem könnyű kitalálni, hogy ezek közül melyiket kell használni. Mindezek az eszközök használhatók az infrastruktúra kódként történő kezelésére. Ezek mindegyike nyílt forráskódú, nagy közreműködő közösségek támogatásával, és számos különböző felhőszolgáltatóval dolgozik együtt(a CloudFormation kivételével, amely zárt forráskódú és AWS-csak). Mindegyik vállalati támogatást kínál. Mindegyik jól dokumentált, mind a hivatalos dokumentáció, mind a közösségi források, például a blogbejegyzések és a StackOverflow kérdések szempontjából. Szóval hogyan döntesz?

ami még nehezebbé teszi ezt, az az, hogy a legtöbb online összehasonlítást ezen eszközök között alig több, mint felsorolni az egyes eszközök általános tulajdonságait, és úgy hangzik, mintha bármelyikükkel ugyanolyan sikeres lenne. És bár ez technikailag igaz,ez nem segít. Ez egy kicsit olyan, mint mondani egy programozási újonc, hogy lehet ugyanolyan sikeres épület egy honlap PHP, C, vagy Assembly-egy nyilatkozatot, hogy technikailag igaz, de az egyik, hogy kihagyja a hatalmas mennyiségű információt, hogy hihetetlenül hasznos lenne abban, hogy egy jó döntés.

ebben a bejegyzésben belemerülünk néhány nagyon konkrét Okba, amiért a Terraform-ot választottuk a többi IAC eszköz felett. Mint minden technológiai döntések, ez az a kérdés, trade-off, prioritások, míg a konkrét prioritásokat lehet más, mint a miénk, reméljük, hogy megosztotta a gondolkodási folyamat segít, hogy a saját döntését. Itt vannak a főbb kompromisszumok, amelyeket figyelembe vettünk:

  • Konfiguráció-Kezelési vs Létesítési
  • Változékony Infrastruktúra vs Állandó Infrastruktúra
  • Eljárási vs Deklaratív
  • Mester vs Gazdátlan
  • Ügynök vs Agentless
  • Nagy Közösségi vs Kis Közösség
  • Érett vs élvonalbeli
  • Segítségével Több eszköz együttes

Szakács, Báb, ansible-nek, valamint SaltStack minden konfiguráció menedzsment eszközök, ami azt jelenti, hogy úgy tervezték meg, hogy telepítse, majd szoftver kezelésére, a meglévő szerverek. A CloudFormation és a Terraform a kiszolgáló eszközök, ami azt jelenti, hogy azokat úgy tervezték, hogy maguk a kiszolgálókat (valamint az infrastruktúra többi részét, például terheléselosztókat, adatbázisokat, hálózati konfigurációt stb.) biztosítsák, hagyva a kiszolgálók konfigurálásának feladatát más eszközökre. E két kategória nem zárja ki egymást, mint a legtöbb konfigurációs menedzsment eszközök képes bizonyos fokú létesítési, illetve provisioning eszközök képes bizonyos fokú konfiguráció menedzsment. A konfigurációkezelésre vagy a létesítésre való összpontosítás azonban azt jelenti, hogy néhány eszköz jobban illeszkedik bizonyos típusú feladatokhoz.

különösen azt találtuk, hogy ha Docker-t vagy Packer-t használ, a konfigurációkezelési igények túlnyomó többsége már gondoskodott. A Docker és a Packer segítségével olyan képeket (például konténereket vagy virtuális gépképeket) hozhat létre, amelyek rendelkeznek a szerver által már telepített és konfigurált összes szoftverrel. Miután ilyen képed van, csak egy szerverre van szükséged a futtatásához. Ha csak annyit kell tennie, hogy a rendelkezést egy csomó szerverek, akkor létrehozási eszköz, mint Terraform jellemzően lesz jobbat is, mint egy konfigurációs menedzsment eszköz (itt egy példa, hogyan kell használni Terraform telepíteni Docker a AWS).

Változékony Infrastruktúra vs Állandó Infrastruktúra

Konfiguráció-menedzsment eszközök, mint a Szakács, Báb, ansible-nek, valamint SaltStack általában alapértelmezett a változékony infrastruktúra paradigma. Ha például azt mondja A Chef-nek, hogy telepítse az OpenSSL új verzióját, akkor a szoftverfrissítést a meglévő szervereken futtatja, a változások pedig a helyszínen történnek. Idővel, ahogy egyre több frissítést alkalmaz, minden szerver egyedi változási előzményeket készít. Ez gyakran vezet a jelenség az úgynevezett configuration drift, ahol minden szerver lesz kicsit más, mint az összes többi, ami finom konfigurációs hibákat, amelyeket nehéz diagnosztizálni, és szinte lehetetlen reprodukálni.

ha olyan létesítő eszközt használ, mint például a Terraform a Docker vagy a Packer által létrehozott gépi képek telepítéséhez, akkor minden “változás” valójában egy új kiszolgáló telepítése (csakúgy, mint a funkcionális programozás minden változója “módosítása” valójában egy új változót ad vissza). Például az OpenSSL új verziójának telepítéséhez új képet hozna létre a Packer vagy a Docker segítségével, az OpenSSL új verziójával már telepítve, telepítené ezt a képet egy teljesen új szerverre, majd visszavonhatja a régi szervereket. Ez a megközelítés csökkenti annak valószínűségét, konfigurációs drift hibák, megkönnyíti, hogy pontosan tudja, milyen szoftver fut a szerveren, és lehetővé teszi, hogy triviálisan telepíteni minden korábbi verzióját a szoftver bármikor. Természetesen lehetőség van arra, hogy a konfigurációkezelő eszközöket megváltoztathatatlan telepítésekre kényszerítsük, de ez nem az idiomatikus megközelítés ezekre az eszközökre, mivel ez természetes módja a létesítő eszközök használatának.

Procedural vs Deklarative

séf és Ansible ösztönözzék az eljárási stílus, ahol írni kódot, amely meghatározza, lépésről-lépésre, hogyan lehet elérni néhány kívánt végállapot. A Terraform, a CloudFormation, a SaltStack és a báb mind egy deklaratívabb stílust ösztönöz, ahol olyan kódot írsz, amely meghatározza a kívánt végállapotot, és maga az IAC eszköz felelős azért, hogy kitalálja, hogyan lehet ezt az állapotot elérni.

például tegyük fel, hogy 10 kiszolgálót (“EC2 példányok” az AWS lingo-ban) akart telepíteni egy alkalmazás v1 futtatásához. Itt van egy egyszerűsített példa egy lehetséges sablonra, amely ezt eljárási megközelítéssel teszi:

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

és itt egy egyszerűsített példa egy Terraform sablonra, amely ugyanezt teszi deklaratív megközelítéssel:

most a felszínen ez a két megközelítés hasonlónak tűnhet, és amikor először végrehajtja őket Ansible vagy Terraform, hasonló eredményeket fognak produkálni. Az érdekes dolog az, hogy mi történik, ha változtatni akarsz.

például képzelje el, hogy a forgalom nőtt, és a kiszolgálók számát 15-re szeretné növelni. Az Ansible-rel a korábban írt eljárási kód már nem hasznos; ha csak frissíti a szerverek számát 15-re, és átirányítja ezt a kódot, akkor 15 új kiszolgálót telepítene, összesen 25-öt adva! Tehát ehelyett tisztában kell lennie azzal, hogy mi már telepítve van, és írjon egy teljesen új eljárási szkriptet az 5 új szerver hozzáadásához:

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

A deklaratív kód, mivel csak kijelentem, hogy a végén állami akarsz, Terraform kitalálja, hogy azt a végén állam, Terraform is tisztában bármely állam létrehozta a múltban. Ezért telepíteni 5 szerverek, annyit kell tenned, hogy menjen vissza, hogy az azonos Terraform sablont, majd frissítse a szám 10-től 15:

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

Ha végre ezt a sablont, Terraform volna észre, már létrehozott 10 szerverek, ezért csak ennyi kellett létrehozni 5 új szerverek. Valójában a sablon futtatása előtt használhatja a Terraform plan parancsot, hogy megnézze, milyen változtatásokat hajtana végre:

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

most mi történik, ha telepíteni szeretné a v2 szolgáltatást? Az eljárási megközelítéssel mindkét korábbi Ansible sablonja ismét nem hasznos,ezért még egy sablont kell írnia az előző telepített 10 szerver nyomon követéséhez (vagy most 15 volt?) és gondosan frissítse mindegyiket az új verzióra. A Terraform deklaratív megközelítésével ismét pontosan ugyanarra a sablonra tér vissza, és egyszerűen csak az ami verziószámát v2-re változtatja:

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

nyilvánvaló, hogy a fenti példák egyszerűsödnek. Az Ansible lehetővé teszi a címkék használatát a meglévő EC2 példányok kereséséhez az új példányok telepítése előtt (például a instance_tags és count_tag paraméterek használatával), de manuálisan kell kitalálnia ezt a logikát minden egyes erőforráshoz, amelyet Ansible-rel kezel, az egyes erőforrások múltbeli története alapján, meglepően bonyolult lehet (pl. a meglévő példányok megtalálása nem csak címkével, hanem képverzióval, elérhetőségi zónával stb.). Ez rávilágít az eljárási IAC eszközök két fő problémájára:

  1. az eljárási kód kezelésekor az infrastruktúra állapota nem szerepel teljes mértékben a kódban. A fent létrehozott három lehetséges sablon olvasása nem elég ahhoz, hogy tudjuk, mi van telepítve. Azt is tudnia kell, hogy milyen sorrendben alkalmaztuk ezeket a sablonokat. Ha más sorrendben alkalmaznánk őket, talán más infrastruktúrát kapnánk, és ez nem az, amit maga a kódbázisban láthatunk. Más szóval, ahhoz, hogy egy Ansible vagy Chef codebase-ről beszéljünk, ismernie kell minden olyan változás teljes történetét, amely valaha történt.
  2. az eljárási kód újrafelhasználhatósága eredendően korlátozott, mivel manuálisan kell figyelembe vennie a kódbázis aktuális állapotát. Mivel ez az állapot folyamatosan változik, az egy héttel ezelőtt használt kód már nem használható, mert úgy tervezték, hogy módosítsa az infrastruktúra állapotát, amely már nem létezik. Ennek eredményeként az eljárási kódbázisok idővel egyre nagyobbak és bonyolultabbak lesznek.

másrészről, a Terraformban alkalmazott deklaratív megközelítéssel a kód mindig az infrastruktúra legújabb állapotát képviseli. Egy pillanat alatt meg tudja mondani, hogy mi van jelenleg telepítve, hogyan van konfigurálva, anélkül, hogy aggódnia kellene a történelem vagy az időzítés miatt. Ez megkönnyíti az újrafelhasználható kód létrehozását is, mivel nem kell manuálisan figyelembe vennie a világ jelenlegi állapotát. Ehelyett csak a kívánt állapot leírására összpontosít, a Terraform pedig kitalálja, hogyan lehet automatikusan eljutni az egyik állapotból a másikba. Ennek eredményeként a Terraform kódbázisok általában kicsik és könnyen érthetőek maradnak.

természetesen vannak hátrányai a deklaratív nyelveknek is. A teljes programozási nyelv elérése nélkül a kifejező ereje korlátozott. Például az infrastrukturális változások bizonyos típusait, például a gördülő, nulla állásidő telepítését nehéz tisztán deklaratív módon kifejezni. Hasonlóképpen, anélkül, hogy képes lenne “logikát” (például if-nyilatkozatok, hurkok) készíteni, az Általános, újrafelhasználható kód létrehozása trükkös lehet (különösen a Felhőformációban). Szerencsére a Terraform számos nagy teljesítményű primitívet biztosít, például bemeneti változókat, kimeneti változókat, modulokat, create_before_destroy és count, amelyek lehetővé teszik tiszta, konfigurálható, moduláris kód létrehozását még deklaratív nyelven is. Ezeket az eszközöket részletesebben tárgyaljuk a 4. részben, hogyan lehet újrafelhasználható infrastruktúrát létrehozni Terraform modulokkal és az 5. részben, Terraform tippek & trükkök: hurkok, if-nyilatkozatok és buktatók.

Master Versus Masterless

alapértelmezés szerint a Chef, Puppet, and SaltStack mind megköveteli, hogy futtasson egy mesterkiszolgálót az infrastruktúra állapotának tárolására és a frissítések terjesztésére. Minden alkalommal, amikor szeretné frissíteni valamit az infrastruktúra, használja a kliens (pl. egy parancssori eszköz), hogy adjon új parancsokat a master server, illetve a központi szerver vagy tolja a frissítések minden más szerverek, vagy azok a szerverek húzza a legújabb frissítéseket le a mester szerver rendszeresen.

a mesterkiszolgáló néhány előnyt kínál. Először is, ez egy központi hely, ahol láthatja és kezelheti az infrastruktúra állapotát. Számos konfigurációkezelő eszköz még webes felületet is biztosít (például a Chef konzolt, a Puppet Enterprise konzolt) a mesterkiszolgáló számára, hogy könnyebben láthassa, mi folyik itt. Másodszor, egyes mesterkiszolgálók folyamatosan futhatnak a háttérben, és végrehajthatják a konfigurációt. Így, ha valaki kézi változást hajt végre egy kiszolgálón, a mesterkiszolgáló visszaállíthatja ezt a változást, hogy megakadályozza a konfigurációs eltolódást.

a mesterkiszolgáló futtatásának azonban komoly hátrányai vannak:

  • extra infrastruktúra: egy extra kiszolgálót, vagy akár egy extra szervercsoportot kell telepítenie (a magas rendelkezésre állás és skálázhatóság érdekében), csak a mester futtatásához.
  • Karbantartás: van, fenntartása, frissítése, vissza, monitor, valamint a skála a mester szerver(ek).
  • Biztonság: Meg kell adni a módját, hogy az ügyfél közli a központi szerver(ek), valamint a központi szerver(ek) kommunikálni a többi szerver, ami általában azt jelenti, nyílás extra port konfigurálása extra hitelesítési rendszer, amely növeli a felület, hogy a támadók.

Szakács, Báb, valamint SaltStack van különböző szintű támogatása gazdátlan mód, ahol csak fuss az ügynök szoftver minden a szerverek, általában rendszeres menetrend (pl. egy cron job fut minden 5 perc), majd ezzel az, hogy húzza le a legújabb frissítéseket a verziókezelő (ahelyett, hogy egy központi szerver). Ez jelentősen csökkenti a mozgó alkatrészek számát, de amint azt a következő részben tárgyaltuk, ez továbbra is számos megválaszolatlan
kérdést hagy maga után, különösen arról, hogyan kell a kiszolgálókat biztosítani, és telepíteni az ügynökszoftvert rájuk.

Ansible, CloudFormation, Heat, and Terraform are all masterless by default. Vagy, hogy pontosabbak legyünk, némelyikük egy mesterkiszolgálóra támaszkodhat, de ez már része a használt infrastruktúrának, nem pedig egy extra darabnak, amelyet kezelnie kell. Például a Terraform felhőszolgáltatókkal kommunikál a felhőszolgáltató API-k segítségével, így bizonyos értelemben az API-kiszolgálók mesterkiszolgálók, kivéve, hogy nem igényelnek extra infrastruktúrát vagy extra hitelesítési mechanizmusokat (azaz csak használja az API-kulcsokat). Az Ansible úgy működik, hogy közvetlenül csatlakozik az egyes kiszolgálókhoz az SSH-n keresztül, így ismét nem kell további infrastruktúrát futtatnia vagy további hitelesítési mechanizmusokat kezelnie (azaz csak használja az SSH kulcsokat).

Agent Versus Agentless

Chef, Puppet, and SaltStack all require you to install agent software (pl Chef Client, Puppet Agent, Salt Minion) on each server you want to configure. Az ügynök általában a háttérben fut minden kiszolgálón, és felelős a
a legújabb konfigurációs menedzsment frissítések telepítéséért.

ennek néhány hátránya van:

  • Bootstrapping: Hogyan látja el a szervereit, és hogyan telepíti rájuk az ügynökszoftvert? Néhány konfigurációs menedzsment eszközök rúgni az elkerülhetetlent, feltételezve, hogy egy külső folyamat, majd elintézem őket (pl., hogy az első használat Terraform telepíteni egy csomó szerver VM kép, hogy az ügynök már telepítve); egyéb konfigurációs menedzsment eszközök különleges bootstrapping folyamat, ahol egy-le parancsok rendelkezés a szerverek segítségével a cloud szolgáltató APIs, majd telepítse az ügynök szoftver azok a szerverek SSH-n át.
  • karbantartás: Rendszeresen gondosan frissítenie kell az ügynökszoftvert, ügyelve arra, hogy szinkronban tartsa a mesterkiszolgálóval, ha van ilyen. Figyelnie kell az ügynökszoftvert is, majd újra kell indítania, ha összeomlik.
  • biztonság: Ha az ügynökszoftver egy mesterkiszolgálóról (vagy más szerverről) húzza le a konfigurációt, akkor minden kiszolgálón meg kell nyitnia a kimenő portokat. Ha a mesterkiszolgáló a konfigurációt az ügynökre tolja, akkor minden kiszolgálón bejövő portokat kell megnyitnia. Mindkét esetben ki kell derítenie, hogyan hitelesítheti az ügynököt annak a kiszolgálónak, akivel beszél. Mindez növeli a felület a támadók.

ismét, Szakács, Báb, valamint SaltStack van különböző szintű támogatása agentless módok (pl. só-ssh), de ezek gyakran érzem magam, mint voltak hozzátétele, mint utólag nem mindig támogatja a teljes funkcionalitással a konfiguráció menedzsment eszköz. Ezért a vadonban a séf, a Báb és a SaltStack alapértelmezett vagy idiomatikus konfigurációja szinte mindig tartalmaz egy ügynököt, általában egy mestert is.

mindezek az extra mozgó alkatrészek számos új meghibásodási módot vezetnek be az infrastruktúrába. Minden alkalommal, amikor egy hibajelentést, hajnali 3-kor, akkor azt kell kitalálni, ha egy bogár a kérelem kód, vagy az IAC-kód, vagy a konfiguráció menedzsment ügyfél, vagy a központi szerver(ek), vagy az ügyfél beszél, hogy a mester szerver(ek), vagy ahogy más szerverek beszélni a mester szerver(ek), vagy…

ansible-nek, CloudFormation, Hő, pedig Terraform nem követeli meg, hogy telepítse a plusz ügynökök. Vagy, hogy pontosabb legyen, némelyikük ügynököket igényel, de ezek általában már telepítve vannak a használt infrastruktúra részeként. Például az AWS, az Azure, a Google Cloud és az összes többi felhőszolgáltató gondoskodik az ügynökszoftverek telepítéséről, kezeléséről és hitelesítéséről minden fizikai szerverükön. A Terraform felhasználójaként nem kell emiatt aggódnia: csak parancsokat ad ki, a felhőszolgáltató ügynökei pedig
– t hajtanak végre az Ön számára az összes kiszolgálón. A Ansible, a szerverek kell futtatni
Az SSH démon, ami gyakori, hogy fut a legtöbb szerveren egyébként.

nagy közösség vs kis közösség

amikor kiválaszt egy technológiát, akkor is közösséget választ. Sok esetben a projekt körüli ökoszisztéma nagyobb hatással lehet tapasztalataira, mint maga a technológia rejlő minősége. A közösség meghatározza, hogy hány ember járul hozzá a projekthez, hány plug-in,
integrációk és bővítmények állnak rendelkezésre, milyen könnyű online segítséget találni (pl. blogbejegyzések, kérdések a StackOverflow-ról), és milyen könnyű felvenni valakit, aki segít önnek (pl. alkalmazott, tanácsadó vagy támogató cég).

nehéz pontos összehasonlítást végezni a közösségek között, de bizonyos tendenciákat online kereséssel észlelhet. Az alábbi táblázat azt mutatja, összehasonlítása népszerű IAC eszközök, adatok azt során gyűjtött Május 2019, ideértve azt is, hogy az IAC eszköz nyílt forráskódú vagy zárt forráskódú, mi cloud szolgáltatók támogatja, a teljes száma a közreműködők, a csillagok a GitHub, hogy hány követ el, aktív kérdések több, mint egy hónapos időszak közepétől április közepéig Lehet, hogy sok nyílt forráskódú könyvtárak állnak rendelkezésre, az eszköz, a kérdések száma szerepel, hogy az eszköz a StackOverflow, a munkahelyek száma beszélve, hogy az eszköz Indeed.com.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük