Infrastruktura jako Kod (IaC) - to nie tylko zalety, ale i nowe wyzwania - część pierwsza.
Infrastruktura jako Kod (ang. Infrastructure as Code, w skrócie IaC) to obecnie wiodący sposób wdrażania rozwiązań na środowiskach chmurowych. W Hostersach traktujemy go jako standard wdrożeniowy pozostawiając manualne, tzw. "wyklikiwane" konfiguracje serwisów chmurowych dla tworzenia bardzo małych, zwykle krótkich i nierozwojowych projektów lub częściej do projektów eksperymentalnych tzw. PoCów (ang. Proof of Concept).
Z założenia zastosowanie IaC ma pomóc w rozwiązaniu kluczowych problemów związanych z zarządzaniem zasobami chmurowymi, a lista tych problemów (lub wyzwań, jak to woli) jest długa. Wymienimy poniżej tylko kilka z nich – wg nas najbardziej istotnych, ujawniających się bardzo szybko w najmniej spodziewanym momencie jako konsekwencja tworzenia konfiguracji zasobów chmurowych manualnie np. za pomocą kreatorów w konsoli webowej.
A więc co nam może zagrażać?
- Utrata kontroli nad konfiguracją serwisów i zasobów – problem staje się szczególnie dotkliwy w przypadku, gdy zarządzamy infrastrukturą ogromnej skali np. dziesiątkami tysięcy zasobów.
- Czasochłonny i kosztowny manualny proces zmiany czy aktualizacji konfiguracji nierzadko setek lub tysięcy różnorakich komponentów chmurowych, obarczony dodatkowo ryzykiem błędu ludzkiego.
- Rozbieżności i brak spójności pomiędzy konfiguracjami instancji tych samych serwisów lub zasobów chmurowych.
- Brak łatwego sposobu przywrócenia poprzednich ustawień po wprowadzeniu błędnych zmian.
- Brak możliwości śledzenia historii zmian konfiguracji komponentów chmurowych.
- Brak możliwości sprawdzenia i przeglądu modyfikacji, przewidywanych rezultatów po wdrożeniu oraz potencjalnych skutków ubocznych na środowisku chmurowym przed ich bezpośrednim wykonaniem.
- Brak dokumentacji samej infrastruktury bądź dokonywanych zmian.
- Brak spójnego i niezawodnego mechanizmu aktualizacji konfiguracji infrastruktury chmurowej.
- Brak kontroli nad zależnościami pomiędzy zasobami chmurowymi.
Odpowiedzią na te problemy jest metoda znana jako Infrastruktura jako Kod (IaC), realizowana w różnej formie: serwisów takich jak AWS CloudFormation, narzędzi opartych na dedykowanych językach typu DSL (ang. Domain Specfic Language) np. Terraform czy też narzędzi pochodnych jak AWS CDK (Cloud Development Kit) opartych o imperatywne języki programowania ogólnego przeznaczenia jak Python czy Java.
Jednak upowszechnienie się IaC i zastosowanie tej stosunkowo młodej technologii rodzi nowe wyzwania. Niedostatek wypracowanych, dojrzałych i wielokrotnie sprawdzonych wzorców projektowych, na których brak cierpi prawie każda technologia w swym wieku "dojrzewania" powoduje, że wielu naszych klientów zdaje się na wiedzę czerpaną z niesprawdzonych źródeł lub eksperymentuje ucząc się na własnych błędach. Tymczasem to jest właśnie te spektrum wiedzy, w którym Hostersi mają już doświadczenie eksperckie i mogą pomóc w uniknięciu potencjalnych problemów, a przez to znacznie obniżyć koszty i przyspieszyć implementacje projektów chmurowych bazując na wieloletnim doświadczeniu zebranym przy wdrażaniu i utrzymywaniu za pomocą IaC setek projektów chmurowych.
W przypadku samodzielnych wdrożeń IaC nasi klienci zmagają się często z następującymi bolączkami:
- "Piekło kodu monolitycznego" ( "Monolithic Hell") – przypadek, w którym wszystkie serwisy i zasoby chmurowe są wdrażane i zdefiniowane w jednym, bardzo obszernym kawałku kodu (monolicie), bez podziału na niezależne części, warstwy powiązanych komponentów lub grupy serwisów i zasobów o jasno zdefiniowanej roli, obszarze czy zakresie odpowiedzialności. Ten problem szczególnie boleśnie objawia się różnymi błędami podczas wdrożeń na środowiskach produkcyjnych w AWS CDK (Cloud Develoment Kit), związanymi często z przekroczeniem limitów poszczególnych serwisów stanowiących część tzw. stosu zasobów (ang. resource stack) zarządzanego przez ten monolit kodu.
- Pochodną powyższego problemu jest również wysokie ryzyko pomyłki przy wdrażaniu zmian w stosie zasobów stworzonych na bazie monolitu kodu. Drobna lub niezamierzona literówka w kodzie CDK może spowodować reakcję łańcuchową i kaskadę niekontrolowanych zmian a nawet przypadkowe zniszczenie krytycznych elementów infrastruktury wchodzących w skład stosu.
- Zbyt skomplikowana hierarchia kodu IaC i zastosowanie zaawansowanych, choć często nieadekwatnych do sytuacji mechanizmów danego języka czy narzędzia. Wykorzystanie wielopoziomowego dziedziczenia czy polimorfizmu języków obiektowych w przypadku implementacji kodu aplikacyjnego zwykle sprawdza się znakomicie, to jednak w przypadku implementacji kodu infrastruktury niekoniecznie będą to właściwe opcje i wybory. Nieraz spotkaliśmy się z przypadkami, gdzie po odejściu autora lub autorów kodu infrastruktury nikt z zespołu klienta nie ważył się dotknąć pozostawionego kodu z obawy przed konsekwencjami wprowadzania zmian, których efekty uboczne na środowisku produkcyjnym nie były proste do przewidzenia i groziły przypadkowym zniszczeniem lub modyfikacją kluczowych z punktu widzenia aplikacji serwisów. Stopień skomplikowania oraz szereg zależności pomiędzy projektami IaC sprawiał, że zrozumienie, w jaki sposób zadziała z pozoru prosta nawet zmiana, nie było całkiem trywialne i wymagało nawigowania oraz przełączania się pomiędzy kilkoma projektami by dotrzeć do sedna. To wtedy też firmy zwracają się do Hostersów z prośbą o wsparcie i zwykle po analizie kodu oraz rzeczywistej konfiguracji serwisów na chmurze nasi DevOpsi bezpiecznie wprowadzają wymagane modyfikacje.
- Brak konwencji nazewniczej oraz spójności w strukturze projektu IaC – brak przyjętych standardów w kwestiach organizacji struktury i nazewnictwa pakietów, modułów, klas lub brak konsekwencji w stosowaniu i egzekwowaniu tychże standardów powoduje, że z czasem zarządzanie takim projektem staje się nie lada wyzwaniem. Wówczas często spotkamy się z przypadkami wielokrotnego kopiowana tych samych lub bardzo podobnych kawałków kodu. Nierzadko nowy programista infrastruktury ma problem z wyszukaniem i zastosowaniem już wcześniej przygotowanego komponentu – więc odkrywając koło na nowo implementuje tę samą funkcjonalność po raz kolejny.
- Rozbieżności pomiędzy źródłem prawdy ( "Single source of truth"), którym powinna być aktualna wersja kodu IaC w repozytorium, a rzeczywistym wdrożeniem na środowiskach chmurowych, szczególnie produkcyjnych. Najczęściej jest to niezamierzony rezultat jednej lub dwóch niepożądanych sytuacji:
- Braku jednolitego mechanizmu wdrażania kodu IaC i aplikowanie zmian w kodzie z lokalnych komputerów programistów infrastruktury.
- Możliwości manualnego/ręcznego wprowadzania modyfikacji konfiguracji - najczęściej z poziomu konsoli webowej.
- Brak wiedzy i doświadczenia w danym języku programowania czy stosowaniu narzędzia IaC – gdzie efektem zwykle jest implementacja kodu w sposób nie zawsze w pełni optymalny ze względu na zastosowania niewłaściwych konstrukcji języka programowania np. wielokrotne kopiowanie tych samych fragmentów kodu lub tworzenie własnych komponentów zamiast wykorzystania już istniejących konstrukcji wbudowanych w język lub technologię IaC.
Jak więc sobie radzić z powyższymi problemami? O tym opowiemy już wkrótce, w drugiej części posta.
Autor: Adam Smolnik, Senior Cloud Architect w Hostersi i AWS Community Hero.