Przeszedłem z Terraform na CloudFormation — i tego żałuję

Reprezentowanie infrastruktury w postaci kodu w powtarzalnym formacie tekstowym to prosta i najlepsza praktyka dla systemów, która nie wymaga wysiłku. Praktykę tę nazwało się — Infrastruktura jako kod, a jak dotąd w jej realizacji, szczególnie w AWS, są dwa popularne narzędzia: Terraform i CloudFormation.

Przeszedłem z Terraform na CloudFormation — i tego żałuję
Porównuję doświadczenie z Terraform i CloudFormation

Przed przyjściem do Twitch (inaczej Amazon Jr.) pracowałem w jednym startupie i przez około trzy lata korzystałem z Terraform. W nowym miejscu również intensywnie używałem Terraform, a potem firma nacisnęła na przejście na wszystko w stylu Amazon, w tym CloudFormation. Ciężko pracowałem nad najlepszymi praktykami zarówno dla jednego, jak i dla drugiego, i używałem obu narzędzi w bardzo złożonych procesach roboczych na poziomie organizacyjnym. Później, po starannym przemyśleniu skutków przejścia z Terraform na CloudFormation, upewniłem się, że Terraform jest prawdopodobnie najlepszym wyborem dla organizacji.

Terraform Przerażający

Wersja beta oprogramowania

Terraform nawet nie doczekał się jeszcze wersji 1.0, co stanowi mocny argument przeciwko jego używaniu. Od momentu, gdy sam go po raz pierwszy wypróbowałem, znacznie się zmienił, ale wtedy jeszcze terraform apply często się psuł po kilku aktualizacjach lub po prostu po kilku latach użytkowania. Powiedziałbym, że „teraz to wszystko jest inne”, ale… chyba wszyscy tak mówią, prawda? Są zmiany, które nie są zgodne z poprzednimi wersjami, chociaż są uzasadnione, a nawet odnoszę wrażenie, że składnia i abstrakcje zasobów teraz wyglądają jak trzeba. Narzędzie wydaje się naprawdę lepsze, ale… :-0

Z drugiej strony, AWS dobrze się spisał, utrzymując kompatybilność z poprzednimi wersjami. Prawdopodobnie dlatego, że ich usługi są często dokładnie testowane wewnętrznie przed publikacją po zmianie nazwy. Więc „dobrze się spisali” to i tak zbyt mało powiedziane. Utrzymanie kompatybilności z poprzednimi wersjami API w tak zróżnicowanym i skomplikowanym systemie, jak AWS, jest niesamowicie trudne. Każdy, kto musiał utrzymywać publiczne API używane na tak szeroką skalę, powinien rozumieć, jak trudno to robić przez tyle lat. Natomiast zachowanie CloudFormation, o ile pamiętam, nigdy się z biegiem lat nie zmieniło.

Poznaj nogę… to kula

Z tego, co wiem, usunięcie zasobu osobnego Nie można importować stanu CloudFormation z własnego stosu CF. Podobnie sprawa wygląda z Terraform. Umożliwia on importowanie istniejących zasobów do swojego stosu. Ta funkcja jest, można powiedzieć, niesamowita, ale z wielką mocą przychodzi wielka odpowiedzialność. Wystarczy, że dodasz zasób do stosu, a dopóki pracujesz ze swoim stosem, nie można usunąć ani zmienić tego zasobu. Raz spotkałem się z takim przypadkiem. Pewnego razu na stronie Twitch ktoś, nie myśląc o żaden sposób źle, przypadkiem zaimportował czyjąś grupę zabezpieczeń AWS do swojego własnego stosu Terraform. Wprowadził kilka poleceń i… grupa zabezpieczeń (razem z przychodzącym ruchem) zniknęła.

Terraform Wielki

Przywracanie z niepełnych stanów

Czasami CloudFormation nie jest w stanie całkowicie przejść z jednego stanu do drugiego. W takim przypadku spróbuje wrócić do poprzedniego. Szkoda, że nie zawsze jest to wykonalne. Naprawienie tego, co się wydarzyło, bywa dość przerażające — nigdy nie wiesz, czy CloudFormation będzie zadowolony, że się go łamie — nawet jeśli w celach naprawczych. A to, czy uda się wrócić do poprzedniego stanu, to coś, czego nie potrafi określić, a domyślnie może wisieć w oczekiwaniu na cud przez godziny.

Terraform natomiast ma tendencję do zwracania się po nieudanych przejściach w sposób znacznie bardziej elegancki i oferuje rozszerzone narzędzia diagnostyczne.

Bardziej przejrzyste zmiany w dokumentach stanu

„Dobrze, równoważnik obciążenia, zmieniasz się. Ale jak?”

—zaniepokojony inżynier, gotowy nacisnąć przycisk „zaakceptuj”.

Czasami muszę wykonać pewne manipulacje z równoważnikiem obciążenia w stosie CloudFormation — na przykład dodać numer portu lub zmienić grupę zabezpieczeń. CloudFormation słabo odzwierciedla zmiany. Ja jednak, jak na igłach, dziesięć razy sprawdzam plik yaml, aby upewnić się, że niczego potrzebnego nie usunąłem, a zbędnego — nie dodałem.

Terraform w tym zakresie jest znacznie bardziej przejrzysty. Czasami jest nawet zbyt przejrzysty (czytaj: uciążliwy). Na szczęście w ostatniej wersji dodano ulepszony widok zmian — teraz dokładnie widać, co się zmienia.

Elastyczność

Piszesz oprogramowanie od tyłu.

Mówiąc wprost, najważniejszą cechą długowiecznego oprogramowania jest zdolność do dostosowywania się do zmian. Każde oprogramowanie pisz od końca. Najczęściej myliłem się, biorąc 'prosty' serwis, a potem starałem się wpasować wszystko w jedną strukturę CloudFormation lub Terraform. Oczywiście, po miesiącach okazywało się, że wszystko zrozumiałem nie tak, a serwis wcale nie był prosty! Potrzebowałem więc w jakiś sposób podzielić duży stos na mniejsze części. Pracując z CloudFormation, można to zrobić tylko po wcześniejszym odtworzeniu istniejącego stosu, czego ja, ze swoimi bazami danych, nie robię. Terraform natomiast pozwalał na wydzielanie stosu i rozdzielenie go na bardziej zrozumiałe mniejsze części.

Moduły w git

Dzielenie się kodem Terraform pomiędzy licznymi stosami jest znacznie łatwiejsze niż dzielenie się kodem CloudFormation. Z Terraform możesz umieścić kod w repozytorium git i odwoływać się do niego z użyciem semantycznej kontroli wersji. Każdy, kto ma dostęp do tego repozytorium, może na nowo wykorzystać wspólny kod. Odpowiednikiem w CloudFormation jest S3, ale nie ma on tych samych zalet, a nie ma żadnego powodu, dla którego mielibyśmy zrezygnować z gita na rzecz S3.

Organizacja rosła, a zdolność do dzielenia się wspólnymi stosami osiągnęła krytyczny poziom. Z Terraform wszystko to jest łatwe i naturalne, podczas gdy CloudFormation zmusi cię do przeskakiwania przez przeszkody, zanim będziesz mógł uzyskać coś podobnego.

Operacje jako kod

«Napiszmy skrypt i będzie dobrze».

—inżynier 3 lata przed wynalezieniem roweru Terraform.

Kiedy mowa o tworzeniu oprogramowania, to Go lub program w Java to nie tylko kod.

Przeszedłem z Terraform na CloudFormation — i tego żałuję
Kod jako kod

Jest jeszcze infrastruktura, na której to działa.

Przeszedłem z Terraform na CloudFormation — i tego żałuję
Infrastruktura jako kod

Ale skąd ona tam? Jak ją monitorować? Gdzie mieszka twój kod? Czy programiści potrzebują pozwolenia na dostęp?

Przeszedłem z Terraform na CloudFormation — i tego żałuję
Operacje jako kod

Bycie programistą to nie tylko pisanie kodu.

Nie samym AWS człowiek żyje: na pewno korzystasz z usług innych dostawców. SignalFx, PagerDuty czy Github. Może masz wewnętrzny serwer Jenkins do CI/CD lub wewnętrzną konsolę Grafana do monitorowania. Infrastruktura jako kod jest wybierana z różnych powodów, a każdy z nich jest równie ważny dla wszystkiego, co związane z oprogramowaniem.

Kiedy pracowałem w Twitchu, przyspieszaliśmy usługi wewnątrz złożonych systemów wbudowanych i systemów AWS Amazona. Wytwarzaliśmy i utrzymywaliśmy wiele mikroserwisów, zwiększając koszty operacyjne. Dyskusje przebiegały mniej więcej w ten sposób:

  • Ja: Cholera, za dużo ruchów, żeby rozwinąć jeden mikroserwis. Muszę użyć tego narzędzia, żeby stworzyć konto AWS (dążyliśmy do 2 kont na mikroserwis), potem tego — do ustawienia powiadomień, jeszcze tego — do repozytorium kodu, i tego — do listy adresów e-mail, no i ten…
  • Lead: Zeskriptujemy i będzie z tym spokój.
  • Ja: Jasne, ale sam skrypt się zmieni. Będzie potrzebny sposób, aby sprawdzić, czy wszystkie te wbudowane elementy Amazona są aktualne.
  • Lead: Brzmi dobrze. I dla tego napiszemy skrypt.
  • Ja: Świetnie! A skrypt z pewnością będzie musiał przyjąć parametry. Przyjmie je?
  • Lead: Oczywiście, że przyjmie! Gdzie ma uciec!
  • Ja: Proces może się zmienić, utracimy wsteczną kompatybilność. Potrzebny będzie jakiś semantyczny kontroler wersji.
  • Lead: Świetny pomysł!
  • Ja: Narzędzia można zmieniać ręcznie, w interfejsie użytkownika. Potrzebujemy sposobu, aby to sprawdzać i poprawiać.

…3 lata później:

  • Lead: I powstał nam terraform.

Morał tej bajki jest taki: nawet jeśli jesteś po uszy w całym ekosystemie Amazona,nadal korzystasz z czegoś, co nie pochodzi z AWS, a te usługi mają stany, które wykorzystują język do konfiguracji, aby ten stan zsynchornizować.

CloudFormation lambda vs moduły git terraform

Lambda to rozwiązanie CloudFormation dla pytania o logikę użytkownika. Z pomocą lambda można tworzyć makra lub zasób niestandardowy. Takie podejście stwarza dodatkowe trudności, których nie ma w semantycznym kontrolerze wersji modułów git w Terraform. Największym problemem dla mnie stało się zarządzanie uprawnieniami dla wszystkich tych użytkowników lambda (a to dziesiątki kont AWS). Drugim ważnym problemem była kwestia 'co było pierwsze — kura czy jajko?': dotyczyła ona kodu lambda. Sama ta funkcja to infrastruktura i kod, i sama potrzebuje monitorowania i aktualizacji. Ostatnim gwoździem do trumny była trudność w semantycznym aktualizowaniu zmian w kodzie lambda; trzeba było jeszcze zrobić tak, żeby działanie stosu nie zmieniało się między uruchomieniami bez bezpośredniego polecenia.

Pamiętam, jak pewnego dnia postanowiłem stworzyć kanarkowe wdrożenie dla środowiska Elastic Beanstalk z klasycznym load balancerem. Najprościej byłoby zrobić drugie wdrożenie dla EB obok środowiska produkcyjnego, robiąc jeszcze jeden krok: połączyć grupę automatycznie skalowalną kanarkowego wdrożenia z LB wdrożenia w środowisko produkcyjne. A skoro Terraform używa ASG beantalk jako wyjście, to wymaga 4 dodatkowych linii kodu w Terraform. Kiedy zapytałem, czy istnieje porównywalne rozwiązanie w CloudFormation, wskazano mi cały repozytorium na git z pipeline'm wdrożeniowym i innymi: wszystko to dla zaledwie 4 linii kodu w Terraform.

Lepiej wykrywa dryf

Upewnij się, że rzeczywistość odpowiada oczekiwaniom.

Wykrywanie dryfu — to bardzo potężna funkcja operations as code, ponieważ pomaga upewnić się, że rzeczywistość odpowiada oczekiwaniom. Jest dostępna zarówno w CloudFormation, jak i w Terraform. Jednak w miarę wzrostu rozmiaru stosu, wyszukiwanie dryfu w CloudFormation generowało coraz więcej fałszywych wykryć.

Z Terraform masz znacznie bardziej zaawansowane hooki cyklu życia do wykrywania dryfu. Na przykład, wpisujesz polecenie ignore_changes bezpośrednio w definicji zadania ECS, jeśli chcesz zignorować zmiany w definicji jakiegoś konkretnego zadania, nie ignorując przy tym zmian w całym wdrożeniu ECS.

CDK i przyszłość CloudFormation

CloudFormation jest trudny do zarządzania w dużych, międzyinfrastrukturalnych skalach. Wiele z tych trudności zostało uznanych, a narzędzie potrzebuje takich rzeczy jak aws-cdk, struktura do definiowania infrastruktury chmurowej w kodzie i przeprowadzania jej przez AWS CloudFormation. Ciekawie będzie zobaczyć, co czeka aws-cdk w przyszłości, ale trudno mu będzie konkurować z innymi zaletami Terraform; aby dogonić CloudFormation, potrzebne będą globalne zmiany.

Aby Terraform nie zawiódł

To jest przecież «infrastruktura jako KOD», a nie «jako tekst».

Moje pierwsze wrażenie na temat Terraform było dość negatywne. Myślę, że po prostu nie zrozumiałem podejścia. Prawie wszyscy inżynierowie na początku błędnie postrzegają go jako format tekstowy, który należy przekształcić w pożądaną infrastrukturę. NIE TRZEBA TAK.

Prawdy uniwersalne dotyczące dobrej praktyki w tworzeniu oprogramowania odnoszą się również do Terraform

Widziałem, jak wiele praktyk stosowanych do tworzenia dobrego kodu jest ignorowanych w Terraform. Uczyłeś się przez lata, aby stać się dobrym programistą. Nie rezygnuj z tego doświadczenia tylko dlatego, że pracujesz z Terraform. Prawdy dotyczące dobrej inżynierii oprogramowania odnoszą się również do Terraform.

Jak można pisać kod i nie dokumentować go?

Spotykałem ogromne stosy Terraform całkowicie bez dokumentacji. Jak można pisać kod przez strony — zupełnie bez dokumentacji? Dodawaj dokumentację, w której wyjaśniasz swój kod Terraform (uwaga na słowo „kod”), dlaczego ten dział jest tak ważny oraz co robisz.

Jak można wdrażać usługi, które kiedyś były jedną dużą funkcją main()?

Spotykałem bardzo złożone stosy Terraform, przedstawione jako jeden moduł. Dlaczego nie wdrażamy oprogramowania w ten sposób? Dlaczego dzielimy duże funkcje na mniejsze? Te same odpowiedzi mają zastosowanie również w przypadku Terraform. Jeśli masz zbyt duży moduł — należy go podzielić na mniejsze.

Czy twoja firma nie korzysta z bibliotek?

Widziałem, jak inżynierowie, rozpoczynając nowy projekt za pomocą Terraform, bezmyślnie kopiowali ogromne fragmenty z innych projektów do swoich, a potem poprawiali je, aż zaczęły działać. Czy w twojej firmie pracowalibyście tak z „produkcyjnym” kodem? Nie korzystamy z bibliotek bez przyczyny. Tak, nie wszystko musi być biblioteką, ale jak w ogóle moglibyśmy funkcjonować bez wspólnych bibliotek?

Czy nie korzystasz z PEP8 lub gofmt?

W większości języków istnieje standardowy schemat formatowania. W Pythonie to PEP8. W Go — gofmt. Terraform ma swój: terraform fmt. Korzystaj bez obaw!

Czy zaczniesz używać React, nie znając JavaScript?

Moduły Terraform mogą uprościć niektóre części tworzonej przez ciebie złożonej infrastruktury, ale to nie znaczy, że możesz w tym nie mieć pojęcia. Chcesz używać Terraform prawidłowo bez zrozumienia zasobów? Jesteś skazany na porażkę: czas będzie mijał, a ty wciąż nie opanujesz Terraform.

Czy piszesz singletony, czy wprowadzasz zależności?

Wstrzykiwanie zależności to uznawana za najlepszą praktykę w tworzeniu oprogramowania, preferowana przez singletony. Jak to można wykorzystać w Terraformie? Spotkałem moduły Terraform, które zależą od zdalnego stanu. Zamiast pisać moduły wyciągające ze zdalnego stanu, napisz moduł, który akceptuje parametry. A następnie przekaż te parametry do modułu.

Twoje biblioteki wykonują dziesięć rzeczy dobrze czy jedną — doskonale?

Najlepiej działają biblioteki skoncentrowane na jednej zadaniu, które wykonują doskonale. Zamiast pisać duże moduły Terraform, które próbują robić wszystko naraz, składaj je z części, które dobrze robią coś konkretnego. A potem połącz je tak, jak to potrzebne.

Jak wprowadzasz zmiany w bibliotekach bez zachowania kompatybilności wstecznej?

Ogólny moduł Terraform, podobnie jak zwykła biblioteka, musi jakoś powiadomić użytkowników o zmianach bez zachowania kompatybilności wstecznej. Gdy takie zmiany zachodzą w bibliotekach, jest to frustrujące, i dokładnie tak samo frustrujące, gdy zmiany bez kompatybilności wstecznej są wprowadzane w modułach Terraform. Zaleca się stosowanie git tags i semver przy używaniu modułów Terraform.

Czy serwis produkcyjny działa na twoim laptopie, czy w centrum danych?

Hashicorp ma narzędzia takie jak terraform cloud do uruchamiania twojego terraformu. Te scentralizowane usługi ułatwiają zarządzanie, audyt i zatwierdzanie zmian terraformu.

Czy nie piszesz testów?

Inżynierowie uznają, że kod należy testować, ale często zaniedbują sprawdzanie podczas pracy z Terraformem. Dla infrastruktury może to prowadzić do niebezpiecznych sytuacji. Radzę „testować” lub „tworzyć przykłady” stosów z użyciem modułów, które można poprawnie wdrożyć do testowania podczas CI/CD.

Terraform i mikroserwisy

Życie i śmierć firm mikroserwisowych zależy od prędkości, aktualizacji i niszczenia nowych mikroserwisowych stosów roboczych.

Najczęściej występujący negatywny aspekt związany z architekturami mikroserwisowymi, od którego nie da się uwolnić, dotyczy pracy, a nie kodu. Jeśli traktujesz Terraform jako sposób automatyzacji tylko infrastrukturalnej strony architektury mikroserwisowej, pozbawiasz się prawdziwych korzyści z tego systemu. Teraz już wszystko — jako kod.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster