Każdy, kto próbował utrzymać spójne środowisko do uruchamiania playbooków, czy to na dedykowanym Ansible Control Node, czy na dowolnym innym serwerze, godząc wymagania różnych kolekcji, wersji Pythona i całej masy zależności, wie, jak szybko potrafi się to zamienić w koszmar. Na szczęście odpowiedzią na ten chaos są środowiska uruchomieniowe (execution environments). Zamiast instalować wszystko na jednym hoście, zamykamy całą automatyzację wraz z jej zależnościami w przenośnym, odizolowanym kontenerze, gwarantując, że zadziała ona zawsze i wszędzie tak samo. Chcę pokazać, jak w praktyce wykorzystać to podejście do zarządzania całym ekosystemem IBM Power, aby raz na zawsze pożegnać problemy z zależnościami.
Podejście: Ansible Control Node
Wyobraź sobie serwer (maszynę wirtualną), który jest Twoim centrum dowodzenia automatyzacją. Instalujesz na nim Ansible, wszystkie potrzebne kolekcje (ansible-galaxy collection install...
), biblioteki Pythona (pip install...
) i inne narzędzia. To jest właśnie Ansible Control Node.
To podejście posiada generuje pewne problemy:
- Chaotyczne zarządzanie zależnościami: Na współdzielonym serwerze każdy może doinstalować coś „tylko dla siebie”, często psując coś komuś innemu. Moduły Pythona instalowane są na przemian przez
dnf
ipip
, raz globalnie dla roota, raz w katalogu domowym (--user
), a do tego dochodzą różne wersje samego Pythona. To prowadzi do kompletnego bałaganu i trudnych do zdiagnozowania błędów. - Brak powtarzalności i syndrom „ale u mnie działało!”: Środowisko na Control Node żyje własnym życiem. Zwykła aktualizacja systemu (
dnf update
) potrafi zaktualizować Ansible lub kluczową bibliotekę, psując playbooki, które działały jeszcze wczoraj. Ponieważ serwer deweloperski, testowy i produkcyjny nigdy nie są identyczne, ten sam kod w jednym miejscu działa, a w innym już nie. - Koszmar utrzymaniowy: Kto zarządza tym serwerem? Co, jeśli aktualizacja systemu operacyjnego zepsuje kluczową zależność Pythona? Control Node staje się współdzielonym zasobem, którego nikt nie chce dotykać w obawie, że coś przestanie działać.
Podejście: Execution Environment (EE)
Execution Environment to kompletne, przenośne i odizolowane środowisko wykonawcze, spakowane w kontener. Zamiast instalować wszystko na jednym serwerze, definiujesz wszystkie zależności w pliku, budujesz z niego obraz kontenera i uruchamiasz swoje playbooki wewnątrz tego kontenera.
Pomyśl o tym tak. Ansible Control Node to jeden, wielki, wspólny warsztat, gdzie wszyscy rzucają swoje narzędzia na jedną kupę. Panuje bałagan, a narzędzia często do siebie nie pasują. Execution Environment to mała, wyspecjalizowana skrzynka z narzędziami. Do pracy z IBM Power bierzesz „skrzynkę IBM Power”, do automatyzacji sieci „skrzynkę sieciową”. Każda jest idealnie przygotowana, samowystarczalna i nie koliduje z innymi.
Dzięki Execution Environment automatyzacja staje się przenośne, spójne i w pełni odtwarzalne.
Własna „skrzynka z narzędziami” dla IBM Power
Dla środowiska IBM Power, taka „skrzynka” (kontener) będzie szczególnie istotna ponieważ mamy tutaj do czynienia z wielomak kolekcjami ansibla dedykowanymi dla każdej warstwy w platformie IBM Power. Nasz kontener bedzie zawierać wszystko, czego potrzebujesz do zarządzania HMC, VIOS czy partycjami AIX/IBM i:
- Kolekcje Ansible:
ibm.power_vios
,ibm.power_hmc
,ibm.power_aix,community.general
itp. - Biblioteki Python: Wszystkie, których te kolekcje wymagają do komunikacji z docelowymi systemami.
- Narzędzia systemowe: Może
sshpass
albo jakiś specyficzny klient, jeśli jest potrzebny.
Chociaż istnieją gotowe, publiczne obrazy EE nie zawierają one wszystkich kolekcji a przede wszystkim tych dla platformy IBM Power, budowanie własnego EE daje również pełną kontrolę, mniejszy rozmiar obrazu i większe bezpieczeństwo.
Proces budowy jest prosty i sprowadza się do trzech kroków.
Definiujesz potrzeby w pliku execution-environment.yml
:
# execution-environment.yml
version: 3
dependencies:
galaxy:
collections:
[ ... ]
- ibm.power_vios
- ibm.power_hmc
[ ... ]
python:
- requests
[ ... ]
YAMLBudujesz obraz kontenera za pomocą ansible-builder
: Dobrą praktyką jest tagowanie obrazu zarówno konkretną wersją (1.0
), jak i tagiem latest
.
ansible-builder build \
--tag my-company-registry/ibmpower-ee:1.0 \
--tag my-company-registry/ibmpower-ee:latest
BashWysyłasz obie wersje do firmowego repozytorium:
podman push my-company-registry/ibmpower-ee:1.0
podman push my-company-registry/ibmpower-ee:latest
BashPrzy budowie EE mozna się wzorować np. na awx-ee
Scenariusze użycia
Teraz, gdy nasza dedykowana „skrzynka” jest gotowa w dwóch wariantach (:1.0
i :latest
), zobaczmy, jak jej użyć.
:1.0
(tag wersji): Używaj w środowiskach produkcyjnych i wszędzie tam, gdzie liczy się stabilność i powtarzalność. Gwarantuje, że zadanie zawsze uruchomi się z tym samym, niezmiennym zestawem narzędzi.:latest
(tag pływający): Używaj w środowiskach deweloperskich i w pipeline’ach CI, które mają testować kod z najnowszą wersją narzędzi.
Sposób 1: Użycie w AWX / Ansible Automation Platform
To podstawowy sposób wykorzystania EE.
- Dodaj EE w AWX: W panelu administratora przejdź do
Administration -> Execution Environments
. - Stwórz dwa wpisy:
- Dla produkcji (stabilne):
- Name:
IBM Power EE 1.0
- Image:
my-company-registry/ibmpower-ee:1.0
- Pull:
Always pull container image before running
- Name:
- Dla deweloperów (najnowsze):
- Name:
IBM Power EE Latest
- Image:
my-company-registry/ibmpower-ee:latest
- Pull:
Always pull container image before running
- Name:
- Dla produkcji (stabilne):
- Podepnij EE do szablonu zadania: W ustawieniach Job Template, np. „Deploy VIOS Production Config”, w polu
Execution Environment
wybierzIBM Power EE 1.0
. Dla zadań deweloperskich możesz wskazaćIBM Power EE Latest
.
Sposób 2: Integracja z GitLab CI (Automatyczne wdrożenia)
Zamiast instalować wszystko od zera w każdym pipeline, po prostu wskazujesz gotowy obraz EE.
# .gitlab-ci.yml
deploy_vios_production:
stage: deploy
# Dla wdrożeń na produkcję używamy konkretnej, zamrożonej wersji.
image:
name: my-company-registry/ibmpower-ee:1.0
script:
- ansible-playbook create_vlan.yml -i inventory.ini --vault-password-file $VAULT_PASS_FILE
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
test_vios_playbook:
stage: test
# W testach możemy używać :latest, by sprawdzać kompatybilność z nowymi narzędziami.
image:
name: my-company-registry/ibmpower-ee:latest
script:
- ansible-playbook create_vlan.yml --syntax-check
- ansible-lint create_vlan.yml
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
YAMLSposób 3: Praca z ansible-navigator
To nowoczesny sposób na pracę z Ansible lokalnie, który idealnie symuluje działanie w AWX w środowisku CLI.
W katalogu z projektem stwórz plik ansible-navigator.yml
:
---
# ansible-navigator.yml
ansible-navigator:
execution-environment:
# Do codziennej pracy deweloperskiej :latest jest wygodny
image: my-company-registry/ibmpower-ee:latest
pull:
policy: missing
YAMLTeraz uruchomienie playbooka to po prostu:
ansible-navigator run create_vlan.yml -i inventory.ini
YAMLJeśli chcesz przetestować coś na starszej wersji EE, możesz nadpisać ustawienie flagą:
ansible-navigator run create_vlan.yml --eei my-company-registry/ibmpower-ee:1.0
YAMLSposób 4: Automatyzacja z ansible-runner
(zaawansowane skrypty)
ansible-runner
to narzędzie „pod maską”, którego używa m.in. AWX. Idealne do integracji Ansible z innymi skryptami. Wymaga specyficznej struktury katalogów.
power_project/
└── private_data_dir/
├── project/
│ └── create_vlan.yml
└── inventory/
└── hosts
YAMLSkrypt w Bashu może wyglądać tak:
#!/bin/bash
# Domyślnie używamy stabilnej wersji, chyba że skrypt zostanie wywołany inaczej
EE_IMAGE_TAG=${1:-"1.0"}
EE_IMAGE="my-company-registry/ibmpower-ee:${EE_IMAGE_TAG}"
PRIVATE_DATA_DIR="./power_project/private_data_dir"
echo "Uruchamiam playbook create_vlan.yml używając obrazu: ${EE_IMAGE}"
ansible-runner run "${PRIVATE_DATA_DIR}" \
-p create_vlan.yml \
--inventory inventory/hosts \
--process-isolation \
--container-image "${EE_IMAGE}"
# Sprawdzenie wyniku...
LATEST_RUN_DIR=$(ls -td "${PRIVATE_DATA_DIR}/artifacts"/*/ | head -1)
if [ -f "${LATEST_RUN_DIR}/status" ] && [ "$(cat "${LATEST_RUN_DIR}/status")" == "successful" ]; then
echo "Playbook zakończony sukcesem."
exit 0
else
echo "Błąd wykonania playbooka! Sprawdź logi w ${LATEST_RUN_DIR}"
cat "${LATEST_RUN_DIR}/stdout"
exit 1
fi
YAMLMożesz teraz uruchomić ten skrypt, opcjonalnie podając tag: ./run_playbook.sh latest
.
Sposób 5: Czysty podman run
(Pełna kontrola)
Świetne do szybkiego testowania i zrozumienia, jak to działa od kuchni. Uruchom to polecenie z katalogu, w którym znajdują się Twoje playbooki.
# Uruchomienie ze stabilną wersją do debugowania problemu produkcyjnego
podman run --rm -it \
-v $(pwd):/runner/project:z \
--workdir /runner/project \
my-company-registry/ibmpower-ee:1.0 \
ansible-playbook create_vlan.yml -i inventory.ini
YAMLRozbijmy to polecenie na czynniki pierwsze:
podman run...
: Uruchom kontener.-v $(pwd):/runner/project:z
: Zamontuj mój obecny katalog (pwd
) wewnątrz kontenera, aby miał on dostęp do playbooka i inwentarza.--workdir /runner/project
: Ustaw katalog roboczy wewnątrz kontenera.my-company-registry/ibmpower-ee:1.0
: Użyj tej konkretnej „skrzynki z narzędziami”.ansible-playbook...
: A to jest komenda, która ma się wykonać w środku.
Podsumowując
Jak widać, Execution Environments to nie tylko nowa funkcja, ale zmiana sposobu myślenia. Koniec z zastanawianiem się, dlaczego playbook działa u Ciebie, a na produkcji już nie. Zamiast bałaganu na serwerze, dostajesz własną, przenośną skrzynkę z narzędziami, która działa tak samo wszędzie. Początkowy wysiłek w jej zbudowanie zwraca się błyskawicznie w postaci spokoju, porządku i automatyzacji, na której wreszcie można w pełni polegać.