Wśród narzędzi CI/CD Jenkins jest jednym z najpopularniejszych i darmowych narzędzi dostępnych w wielu organizacja i procesach devops. Jedni go kochają inni nienawidzą. Sam artykuł nie jest o tym czy to narzędzie jest popularne czy też nie, ale każdy sie zemną zgodzi że jest idelnym toolsetem do nauki procesów CI/CD oraz do automatyzacji zadań.
Pierwszy projekt w jenkins
Kluczem do każdej konfiguracji jest dobre rozplanowanie tego co chcemy uzyskać i co mamy ustawić / skonfigurować. Weźmy rozdzielmy na czynniki pierwsze konfiguracje z tego materiału - Terraform w procesach CI/CD w postaci grafu
Prosty przepływ składający się z 5 jobów z których w łatwy sposób wyróżnić 3 główne od których zależy cała logika. Logika w tym przypadku przekładająca się na konfigurację w claud za pomocą IaC narzędzia jakim jest terraform.
I choć długo podobały mi się projekty zwane "Freestyle project", które swoją prostotą powodują że łatwiej nam wejść w skórę devopsa i skonfigurować taki projekt to mają one pewną wadę. Spójrzmy na te 5 poszczególnych jobów. Mają one na pierwszy rzut oka jeden wspólny kod git, jednak jak możemy zobaczyć musimy go w każdym jobie podawać osobno i konfigurować. Dostarcza to dodatkowej pracy. A i może spowodować to, że przy n-tej próbie wpisywania i uzupełniania tych danych możemy zrobić literówkę.
I wcale tu nie chodzi o jakieś generalizowanie czy też zniechęcenie do tego rodzaju projektów czy też konstrukcji własnych procesów CI/CD własnie w ten sposób. A gdyby tak tą całą konfiguracje przekształcic w kod i zapisać za pomocą pliku tekstowego i przechowywać ją w git. Znacząco by to ułatwiło konfiguracje i pracę z takim pipelinem / projektem.
Jenkins pipeline projekt
By sprostać temu zadaniu spójrzmy na pipeline syntax dostępnym w dokumentacji Jenkins do pipeline. Na podstawie zgromadzonej tu dokumentacji możemy stworzyć prosty zarys naszego projektu. Spójrzmy najpierw na prostą konstrukcje, która nam wszystko wytłumaczy:
Podnajmy analizie ten "pseudo kod":
agent any:
Wskazuje, że ten potok może być uruchamiany na dowolnym agencie dostępnym w środowisku Jenkins.
stage('Build'):
Etap ten ma za zadanie kompilację kodu źródłowego. Po pomyślnej kompilacji, artefakty z budowy są przenoszone w pożądaną lokalizację.
stage('Test'):
W tym etapie najpierw sprawdza się, czy artefakty są obecne we właściwej lokalizacji.
Następnie dane testowe są ładowane do bazy danych.
Wykonuje się testy.
Kontynuacja następuje tylko w przypadku, gdy testy zostaną zakończone pomyślnie.
stage('Deploy'):
W etapie tym pobierany jest przetestowany kod, który następnie jest wdrażany na produkcję.
Spójrzmy raz jeszcze na nasz graf tak by zobaczyć czy uda nam się dostrzec te elementy w naszej konfiguracji:
Wyodrębniłem trzy kroki:
Krok pierwszy to nasz build - czyli pobieranie kody z repozytorium git w kontekście naszego joba czyli naszej deklaracji w jenkins pepline.
Krok drugi tu zbiorczo nasze test:
validate, security, plan, graph - z diagramu tez widzimy że nasze security i graph nie jest istotne z punktu przepływy pracy naszego joba. Ich rezultat nie wpływa na nasz pipeline (jeżeli podąrzamy za zielona linią).
Krok trzeci nasz deploy - czyli w tym przypadku apply, który to już publikuje nasze zmiany w stanie terraform i na naszym cloud.
Przedstawmy to w postaci pseudokodu:
node:
Pseudo-kod ten jest zapisany w starszym stylu deklaratywnnych pipeline'ów Jenkins. Używa on słowa kluczowego `node`, co oznacza, że wszystkie etapy i kroki wewnątrz tego bloku będą wykonywane na jednym agentcie Jenkins.
stage('Build'):
W tym etapie wydaje się, że kod z repozytorium git jest klonowany.
Następnie następuje inicjalizacja środowiska Terraform poprzez komendę `terraform init`.
stage('Test'):
Etap testowania rozpoczyna się od sprawdzenia poprawności składniowych i błędów w konfiguracji za pomocą `terraform validate`.
Następnie jest tworzony plan działania (bez rzeczywistego stosowania zmian) za pomocą `terraform plan`.
Warunek if:
Sprawdza się status bieżącej kompilacji (`currentBuild.currentResult`). Jeśli wynik bieżącej kompilacji to 'SUCCESS', oznacza to, że etapy 'Build' i 'Test' zakończyły się pomyślnie i można przejść do etapu 'Deploy'.
stage('Deploy'):
W tym etapie rzeczywiste zmiany są stosowane w środowisku za pomocą `terraform apply`.
Jest to prosta definicja pipeline, która wykorzystuje narzędzie Terraform do budowy, testowania i wdrażania infrastruktury jako kod (Infrastructure as Code, IaC). Kluczowe etapy obejmują inicjalizację Terraform, walidację, planowanie i zastosowanie zmian w infrastrukturze.
Aby ten pseudo-kod mógł być używany w rzeczywistym środowisku, muszę zastąpić komentarze rzeczywistymi poleceniami i skryptami, które będą realizować te działania. Warto również dodać obsługę błędów i ewentualne notyfikacje w przypadku niepowodzenia któregokolwiek z kroków.
Ja jeszcze dodatkowo rozbije DEPLOY na osobny Jenkinspepline. I powstaną mi dwa joby Jenkins pepline które, nazwe plan i apply.
Skąd ten jenkins pipeline
Można zadać pytanie skąd zatem brać tą konfigurację - nauka składni może być barierą wejścia która, bardziej przekonuje nas do freestyle projekt niż minusy stosowania właśnie powtórzeń i powieleń.
Możemy skorzystać z generatora który, jest dostępny i wbudowany w Jenkins. Pomoże on nam skonfigurować nasz kod który, jest potrzebny do działania z Jenkins pepline. Aby wejsść w generator do nazwy naszego projektu należy dopisać po "/" fraze "pipeline-syntax/" - dla przykładu https://jenkins.koska.in/job/HomeEnv/job/Terraform/job/testo/pipeline-syntax/
Albo w konfiguracji naszego Jenkins pipline job przejść do sekcji Configuration i kikamy Pipeline Syntax
I z pomocą składni Jenkins pipeline uda nam się złożyć naszą konfigurację. Oczywiście musimy pamiętać o dodaniu naszych sekretów itp tak by nasza konfiguracja kodu była bezpieczna i nie powodowała wycieku danych:
Oto szczegółowa analiza dostarczonego kodu Jenkins pipeline:
Agent:
Pipeline jest wykonywany na agencie z etykietą `terraform`.
W przypadku braku dostępności agenta, Jenkins będzie próbować ponownie do 5 razy.
Etap 'Clean workspace':
Wysyła powiadomienie do Slacka o rozpoczęciu tego etapu.
Czyszczenie przestrzeni roboczej za pomocą komendy `cleanWs()`.
Etap 'Repo Clone':
Wysyła powiadomienie do Slacka o rozpoczęciu tego etapu.
Klonuje repozytorium git z określonej konfiguracji (z gałęzi 'main').
Etap 'terraform init':
Wysyła powiadomienie do Slacka o rozpoczęciu tego etapu.
Inicjalizuje Terraform z konfiguracją backendu.
Etap 'terraform validate':
Wysyła powiadomienie do Slacka o rozpoczęciu tego etapu.
Sprawdza poprawność składni konfiguracji Terraform za pomocą `terraform validate`.
Etap 'terraform plan':
Wysyła powiadomienie do Slacka o rozpoczęciu tego etapu.
Uruchamia `terraform plan` z uwzględnieniem różnych zmiennych.
Sprawdza wynik w poszukiwaniu określonych błędów i wysyła powiadomienia na Discord w przypadku wykrycia.
Sekcja 'post':
W zależności od wyniku wykonania pipeline, wykonuje różne kroki, takie jak archiwizacja artefaktów i wysyłanie powiadomień do Slacka o statusie.
Powiadomienia są dostosowane do różnych stanów wyników, takich jak `success`, `regression`, `fixed`, `aborted`, `unstable` i `unsuccessful`.
Pipeline ten skupia się na operacjach związanych z Terraform, takich jak inicjalizacja, walidacja i planowanie. Ważnym aspektem jest również komunikacja z zespołem poprzez powiadomienia na Slacka oraz w przypadku błędów na Discord.
Teraz z apply pójdzie nam jeszcze łatwiej:
Analizując dostarczony kod, możemy zidentyfikować kilka różnic i nowych funkcjonalności w porównaniu do poprzedniej wersji:
Options:
- W kodzie dodano sekcję `options`, która umożliwia stosowanie globalnych opcji dla całego pipeline. Tutaj wykorzystano `timestamps()`, co sprawia, że każdy log z tego pipeline będzie zawierał znacznik czasu, ułatwiając analizę logów.
Etap "copy plan.file":
- Ten etap służy do kopiowania artefaktów z innego projektu/buildu w Jenkinsie. Specjalnie kopiuje plik `plan.file` z projektu o nazwie `WorkEnv/TerraformWorkEnv/work-familmed-terraform-prod/terraform-plan`. Opcja `fingerprintArtifacts: true` oznacza, że Jenkins będzie śledzić i zapisywać metadane dla skopiowanych artefaktów, co może być przydatne w celach audytu.
Etap "terraform apply":
- W tym etapie następuje faktyczne zastosowanie planu infrastruktury terraform. Najpierw jest inicjalizacja terraform z odpowiednią konfiguracją backendu (poprzednio omówione). Następnie, używając flagi `-auto-approve`, automatycznie zatwierdza się zmiany zaproponowane przez terraform bez potrzeby ręcznej interwencji. Wykorzystuje to wcześniej skopiowany plik `plan.file`.
Post:
- Sekcja `post` i jej działanie pozostały takie same, jak w poprzedniej wersji kodu, i zostały już omówione w poprzedniej analizie. Obejmuje ona różne akcje, które mają zostać wykonane po zakończeniu wszystkich etapów, w zależności od wyniku pipeline (np. zawsze wysyłać wiadomość na Slack, archiwizować artefakty po udanej kompilacji itp.).
Podsumowując, ten kod Jenkins pipeline koncentruje się na pobieraniu i aplikowaniu planu terraform, zapewniając odpowiednie powiadomienia na Slack oraz archiwizację niezbędnych artefaktów. Obejmuje także znaczniki czasu dla wszystkich logów dzięki globalnej opcji `timestamps()`. Względem poprzedniej wersji kodu brakuje etapów związanych z walidacją i planowaniem terraform, co sugeruje, że ten pipeline jest prawdopodobnie kontynuacją lub dopełnieniem procesu rozpoczętego w poprzednim kodzie. Spójrzmy teraz na nasz stage view.
Jak poprzednio (mój podział w freestyle) tu też widzimy podział na etapy.
A sama konfiguracja naszego projektu polega jedynie na wskazaniu gdzie szukać naszego kodu w jakim repozytorium + plus konfiguracja credential
Oczywiście konfiguracji w naszym jenkins pepline jest więcej i możemy bardziej wymyślne konfiguracje tu układać. Jednak w tym wpisie to wszystko. Pozdrawiam i do usłyszenie.
Komentarze