Zanim przejdziemy do głębszego omówienia tematu, musimy ustalić sobie pewne fakty i definicje. Zatem, czymże jest „infrastruktura jak kod” (infrastructure as code – IAC)?
Jest to koncepcja, w myśl, której cała infrastruktura i procesy jej przygotowania i konfiguracji powinny być w możliwie jak największym stopniu traktowane i zarządzane w ten sam sposób, co kod tegoż programu, który jest testowany bądź dewelopowany. Oznacza to, że najlepsze praktyki stosowane w procesach wytwarzania kodu zaczynają być aplikowane do procesów przygotowania i konfigurowania infrastruktury. Powyższa zasada jest przede wszystkim omawiana i chwalona w kontekście środowiska chmurowego. W przypadku tego artykułu chciałbym pokazać tą zasadę z punktu widzenia walidacji, a zwłaszcza procesów zarządzania środowiskiem testowym.
Jeśli chcesz być zadowolony z życia, używaj IAC
Pomyślmy zatem, co w kontekście walidacji, a zwłaszcza testów funkcjonalnych i ‘hardware-in-the-loop’ pożera bardzo dużo czasu, jest źródłem ciągłej frustracji i wraca niezmiennie jak bumerang? Z mojego doświadczenia, jest to oczywiście temat przygotowania środowiska testowego. Fizycznych komputerów, serwerów („bare metal DUT”) zawsze jest za mało. Bardzo często w wyniku uruchamianych na nich testów psują się i potrzebują jakichś mniejszych czy większych napraw. Na jednej maszynie często trzeba uruchamiać kilka różnych zestawów testów, co wymaga zmian w konfiguracji albo totalnej zmiany systemu operacyjnego. A na sam koniec tego wszystkiego, w zespole jest tylko jeden specjalista, który tak naprawdę wie, jak przygotować maszynę pod dany zestaw testowy i akurat jest na urlopie.
Na wszystkie powyższe bolączki, lekarstwem jest „Infrastruktura jak kod”. Poszczególne zalety używania narzędzi do wdrażania i zarządzania konfiguracją (przykładowo: Ansible, Salt Stack, Chef, Puppet) opiszę jeszcze w dalszej części artykułu. Przede wszystkim jednak największy zysk jest w „jakości życia” inżynierów w codziennej pracy. W moim własnym zespole utrzymujemy około pięćdziesięciu serwerów. W naszym konkretnym przypadku do zarządzania tym parkiem maszynowym wykorzystujemy Ansible i jego webowy dashboard – AWX. Nasza zaimplementowana automatyzacja pozwala nam w pełni zarządzać tym co się dzieje ze wszystkimi serwerami. Codziennie sprawdzany jest stan każdego serwera. Na życzenie jesteśmy w stanie wgrać dowolny potrzebny nam system operacyjny. Raz w tygodniu automatycznie uruchamia się update do najnowszych wersji oprogramowania. No i wiele więcej.
Poniższy obraz zawiera zdefiniowane przykładowe inventory z użyciem Ansible oraz minimalistyczny playbook, który tworzy kontener dockera i dodaje go do istniejącego inventory. Maszyny w inventory można dzielić na grupy według naszych potrzeb. Wszystko pisane jest w języku YAML.
IAC to nie tylko automatyzacja
Aktualnie w świecie IT bardzo popularne stały się praktyki Continous Integration i Continous Delivery, a także metodologia DevOps. W szerszym spojrzeniu wszystkie te skróty i zasady odnoszą się raczej do środowisk osadzonych w chmurze i zakładające maksymalną automatyzację. Niestety, kiedy stajemy w obliczu testowania sprzętu lub oprogramowania niższego poziomu, dochodzimy do miejsca, gdzie nie wszystko zautomatyzować się da. Czasami testy manualne są wymagane i stanowią niemały zgrzyt w świetnie naoliwionej maszynie walidacji ? Mimo to, w żadnym razie nie powinniśmy rezygnować z tego co nam dają te narzędzia. A właśnie podstawą dla nich jest zasada „infrastruktura jak kod”. Tam, gdzie nie docierają narzędzia do automatyzacji, jeśli będziemy trzymać się wyznaczonych zasad, to nadal poczynimy milowe kroki. A o to w tym wszystkim chodzi, aby ciągle starać się iść ku lepszemu.
Ujednolicony proces przygotowania środowiska testowego – bez tego ani rusz
Jak każdy tester wie, procesy, które dzieją się przed i po zestawach testowych, spożywają duży ułamek czasu i zasobów przeznaczanych na przetestowanie produktu. Nie raz i nie dwa widuje się przypadki, gdzie proces przygotowania środowiska testowego spędza sen z powiek inżynierów. Opanowanie kapryśnego sprzętu i oprogramowania pod presją czasu to nie lada wyzwanie. Każdy tester spotkał się z sytuacją, gdzie testy działają poprawnie na jednej maszynie, a na drugiej nie. Albo jeszcze bardziej ekstremalny tego przypadek – kiedy dany zestaw testów działa tylko na jednej wybranej „magicznej” maszynie i nikt nie wie do końca, dlaczego. Kompletna i czytelna dokumentacja to święty graal, o który bardzo ciężko w realnym świecie. W momencie, gdy nie ma ujednoliconej, a co ważniejsze, powtarzalnej i jasnej metody na przygotowanie środowiska, nie ma mowy o jakichkolwiek próbach automatyzacji tych procesów, a każda kolejna paczka, każdy kolejny release to, niemalże, droga przez mękę dla zespołu testowego.
Dlatego właśnie „infrastruktura jak kod”
Przechodząc więc do clue – co właściwie zyskujemy stosując się do zasad „infrastruktura jako kod”?
- Przede wszystkim, jest to pierwszy krok do automatyzacji tych procesów. Ten sposób myślenia jest fundamentem, na którym oparte są CI/CD oraz DevOps.
- Automatyzując te procesy w oczywisty sposób zyskamy na czasie. Zyskamy również możliwość konfigurowania całej infrastruktury na raz.
- W momencie, kiedy całą naszą infrastrukturę traktujemy jak kod, tak jak tenże kod właśnie, jesteśmy w stanie w prosty sposób odtworzyć całą naszą strukturę. W moim projekcie w formie kodu przechowujemy nie tylko konfigurację serwerów testowych. Jenkins z użyciem wtyczki JenkinsConfigAsCode jest budowany i uruchamiany wprost z kodu przechowywanego na repozytorium. Odtworzenie konfiguracji, jobów, historia buildów, dashboardy – wszystko to jest zapisane w skryptach i odtwarzalne w przypadku katastrofalnych błędów. Podobnie Ansible AWX – konfiguracja jego przechowywana jest jako zestaw poleceń Helm’a Kubernetesa oraz skryptów Tower CLI. Wszystko co tylko się da przerobić na kod, ląduje na repozytorium.
- Bardzo, ale to bardzo ważna rzecz! W momencie, kiedy cała konfiguracja jest przechowywana na repozytorium w formie kodu, automatycznie jest ona wersjonowana. A każdy wie jakie są zalety wersjonowania ? Wszelkie zmiany są w pełni widoczne – także nie może dojść do sytuacji, gdzie ktoś gdzieś coś zmienia i nikt nic nie wie. Wszystkie zmiany są łatwe do odkręcenia – wystarczy cofnąć dany commit na repozytorium. Dodatkowo jest to spójne, wszyscy korzystają z tego samego kodu.
- Kolejny zysk jest nieco innej natury. Traktując infrastrukturę jako kod, tenże kod zaczyna podlegać takim samym standardom, jakie obowiązują w części deweloperskiej zespołu. Dodatkowo przechodzi review, co pozwala wyłapać potencjalnie niebezpieczne pomyłki już na wczesnym etapie.
- Dodatkowo, kompletnie za darmo stymulujemy wymianę wiedzy i doświadczeń między deweloperami a testerami czy DevOps’ami. Deweloperzy mogą uczestniczyć w procesie tworzenia i konfiguracji infrastruktury. Inżynierowie operacyjni w wyniku interakcji z deweloperami zyskują lepsze zrozumienie produktu. Zespół się integruje i następuje naturalny przepływ informacji.
- Poza tym, w momencie kiedy cała infrastruktura jest spisana w formie kodu, automatycznie staje się dla siebie najlepszą dokumentacją.
- Ostatecznie, gdy już wszystko jest zaimplementowane, cały zespół i produkt wiele zyskuje na jakości. Z czasem natomiast, jakość ta przekłada się na oszczędności dla firmy i na całkiem inną jakość pracy inżynierów.
Skoro ja mam IAC, to Ty też możesz mieć
Jak mam nadzieję udało mi się to przytoczyć w powyższym artykule, traktowanie infrastruktury jak kodu niesie za sobą wiele korzyści, w pełni wymiernych oraz nieco bardziej subtelnych. Mając na uwadze wszystkie tego zalety i potencjalny egzystencjalny ból wywołany niekorzystaniem z nich – wzywam was wszystkich do akcji! Korzystajcie z „infrastruktura jako kod”, to łatwe i naprawdę bezbolesne ?
Zostaw komentarz