Na ostatnich warsztatach z proxmox użyłam automatyzacji w terraform i cloud-init w celu zautomatyzowania całej konfiguracji i dostarczeniu środowiska dla słuchaczy. Pojawiły się komentarze i pytania dlaczego nie użyłem w konfiguracji ansible. Ten wpis odpowie na te pytanie. Zapraszam
Automatyzacja proxmox w terraform - założenia.
Moim założeniem dla pierwszych warsztatów było przygotowanie środowiska dla słuchaczy które, w sposób zautomatyzowany dostarczy środowisko labowe z proxmox. Czyli dla jednego słuchacza będzie dostępny proxmox z 3 nodami już zainstalowany i prekonfigurowany tak by każdy mogł bez konieczności instalacji przystąpić do warsztatów. Oczywiście skalowalność tu gwarantuje mi terraform. Uruchomienie jednej czy 200 maszyn wirtualnych to ta sama procedura. Bazuje na wkładzie, a poniżej jego przykład w json
Jednak potrzebowałem kolejnego kroku który pozwoli mi przygotować konfigurację nie na infrastrukturze która już za pomoca terraform jest zrobiona - cały kod można znaleźć tutaj.
I tutaj padł wybór że będzie to zaimplementowane dalej w terraform. Przeświadczyło za tym kilka powodów.
Kontrola automatyzacji - nie przejmuje się czyj host jest czyj, tzn w konfiguracji terraform mi to planuje, każdy użytkownik jest identyfikowany unikatową nazwą. Nazwa ta potem jest wykorzystywana dla nazwy jego hosta.
Brak konieczności używania dodatkowego narzędzia takiego jak ansible. Rezygnacja z generowania artefaktu konfiguracyjnego dla ansible znacząco przyśpiesza działanie. Przeniesienie konfiguracji do cloud-init spowodowało, że konfiguracja maszyny wirtualnej (pojedynczej) rozpoczynała się już gdy tylko ona została przez API postawiona/uruchomiona. W przypadku gdybym generował artefakt i czekał na zakończenie terraform w celu przekazania do ansible proces mogłby się wydłużyć. Ponieważ ansible musiało by poczekać na zakonczenie działania przez terraform.
Zarządzanie już gotową konfiguracją. Gdybym rozbił to na terraform i ansible w przypadku pojedynczych problemów musiałbym uruchomic terraform i czekać na jego zakończenie po czym ręcznie pojedynczo uruchamiać ansible dla problematycznych hostów. W moim przypadku cała operacja zamyka się w dwóch komendach, terraform state list i terraform taint na problematycznym zasobie. Cała magia pod spodem działa tak samo.
Oczywiście pragnę tu zaznaczyć, że nie uważam ansible za słabe narzędzie, akurat w moim przypadku było to zbędne narzędzie i krok.
Terraform taint i untaint na ratunek
Cała automatyzacje mojej konfiguracji trzymam w dwóch miejscach w github jak miejsce gdzie przechowuje repozytorium i całą zawartość kodu. Drugie miejsce to narzędzie do automatyzacji. Uzywam tutaj github actions oraz dodatkowo wspomagam się Jenkins w przypadku awarii pierwszego narzędzia. Co o ironio miała już miejsce. W github actions (i jenkins) mam skonfigurowane pipeline które realizują takie zadania jak:
Budowanie i konfiguracja infrastruktury (workflow terraform plan i apply)
Wyświetlanie informacji o naszym stanie (terraform state list)
Zwracanie wartości (terraform output)
Oraz narzędzie do rekonfiguracji problematycznych zasobów (terraform taint)
Tutaj skupią Twoją uwagę na przedostatnim i ostatnim punkcie konfiguracji w github actions.
Terraform state - informacje o naszych zasobach.
Terraform state list - polecenie to zwraca informacje o wszystkich naszych zasobach uruchomionych w terraform oraz zarządzanych przez naszą konfigurację. Spojrzmy na poniższą konfigurację github action w yaml
Jest to prosta deklaracja joba który odpowiednio łączy się do naszego stanu by potem po przez komendą terraform state list wyświetlić nam informacje o wszystkich zasobach. Poniższe zdjęcie prezentuje przykład takiego outputu z tego włąsnie github actions.
Wyświetlone w ten sposób informacje mogę wykorzystać w terraform taint i problematyczny zasob oznaczyć ponownie do konfiguracji. Spójrzmy na kod naszego workflow za wykorzystaniem naszego polecnia taint w konfiguracji terraform.
Spójrzmy na początek mojego workflow - deklaruje w nim opcje podania wartości wejściowej co pozwala mi sterować poleceniem taint w ramach tej konfiguracji.
Dzięki temu mogę sterować rekonfiguracja danego zasobu.
Jak to działa w praktyce. Wykorzystanie terraform taint, untaint i state z github actions
Spójrzmy na przykład, dostarczę wkład konfiguracyjny który, uruchomi mi instancje dla moich dwóch uczestników (dla większej konfiguracji to tylko efekt większej skali i dostarczenia większego wkładu).
Teraz wystarczy uruchomić workflow związany z deploymentem konfiguracji:
Oto jego rezultat:
github actions jest uruchamiany:
W międzyczasie jego działania możemy śledzić postęp naszej konfiguracji by zobaczyć jakie zasoby są tworzone modyfikowane itp.
Konfiguracja zakończyła się sukcesem mamy stworzone środowisko dla dwóch uczestników (przy większej liczbie działa to dokładnie tak samo - wydłuża się jedynie czas oraz lista naszych zasobów które są uruchamiane przez terraform).
Teraz by otrzymać listę wszystkich dostępnych zasobów mogę skorzystać z workflow który pozwala wyświetlić właśnie ta listę z terraform state.
Uczestnicy tej konfiguracji mają swój zasób i widzimy go pod adresami:
module.szkolenie.digitalocean_droplet.main["Marcin Koska"]
module.szkolenie.digitalocean_droplet.main["Piotr Koska"]
Dla naszego zrozumienia konfiguracji wyobraźmy sobie że użytkownik oznaczona jako Marcin Koska ma problemy ze swoją instalacją. Problemy to przez pomyłke usunął konfiguracje czy też instalacje proxmoxa w prezentowanym labie na swoim hoscie. Terraform taint pozwoli rozwiązać na problem w sposób pełni automatyczny. Wystarczy, że odwołam się do adresu użytkownika module.szkolenie.digitalocean_droplet.main["Marcin Koska"] i uruchomię workflow związany z taint
Wskazujemy zasób który w tym przypadku jest problematyczny i jak widać na poniższym obrazku operacja wykonuje się prawidłowo.
Podsumowanie ładnie nam prezentuje Jakie zasoby będa tworzone na nowo.
Terraform i cloud-init
Wykorzystanie cloud-init pozwala w tym momencie zautomatyzować cały proces. Nie muszę oczekiwać na artefakt w postaci adresu IP maszyny wirtualnej i przekazywać ją do ansible. Wszystkie operacje zaplanowane w cloud-init wykonują się samodzielnie. I po kilku minutach użytkownika wraca do zabawy z nowym środowiskiem. Ja skupiam się dalej na prezentacji a rekonfiguracja odbywa się automatycznie. A tak prezentuje się cloud-init
Podsumowanie i zakończenie
Jak widać konfiguracja w moim przypadku bez użycia ansible jest uzasadniona. I zmniejsza elementy interakcji z mojej strony do absolutnego minimum. Na koniec daj znać co o tym sądzisz i jakie byłoby Twoje podejście. Pozdrawiam
Comments