Bloki, rescue i always – obsługa błędów w playbookach
Automatyzacja zadań administracyjnych w Ansible zakłada nie tylko poprawne wykonanie działań, ale także odpowiednią reakcję w przypadku błędów. W środowiskach produkcyjnych każdy etap wdrożenia powinien być kontrolowany i bezpieczny. W tym artykule omówię mechanizmy block, rescue i always, które pozwalają na obsługę wyjątków i błędów w playbookach Ansible.
1. Czym są bloki w Ansible
Mechanizm block umożliwia grupowanie zadań w logiczne sekcje. Każdy blok może zawierać zestaw zadań głównych, sekcję rescue (obsługa błędów) oraz always (działania wykonywane zawsze, niezależnie od wyniku).
Struktura ogólna:
– block:
– name: Zadania główne
…
rescue:
– name: Zadania w razie błędu
…
always:
– name: Zadania wykonywane zawsze
…
Dzięki temu można kontrolować przepływ zadań nawet w przypadku niepowodzenia jednego z nich.
2. Użycie block w praktyce
Instrukcja block przydaje się szczególnie tam, gdzie kilka zadań musi być wykonanych razem — np. przygotowanie środowiska, instalacja oprogramowania lub wdrożenie plików. Jeśli jedno z zadań w bloku zakończy się błędem, pozostałe z tego bloku nie zostaną wykonane, a sterowanie przechodzi do sekcji rescue.
Przykład:
– name: Install and configure web service
hosts: webservers
become: yes
tasks:
– block:
– name: Install nginx
ansible.builtin.package:
name: nginx
state: present
– name: Deploy configuration
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
– name: Start nginx service
ansible.builtin.service:
name: nginx
state: started
rescue:
– name: Rollback on failure
ansible.builtin.service:
name: nginx
state: stopped
– name: Notify administrator
ansible.builtin.debug:
msg: „Deployment failed – nginx stopped.”
always:
– name: Log completion of task
ansible.builtin.debug:
msg: „Playbook finished (success or error).”
W tym przykładzie, jeśli instalacja lub konfiguracja nginx zakończy się błędem, Ansible zatrzyma usługę i wyświetli komunikat ostrzegawczy, po czym zawsze wykona logowanie zakończenia pracy.
3. Sekcja rescue – reakcja na błąd
Sekcja rescue jest wykonywana tylko wtedy, gdy jedno z zadań w sekcji block zakończy się błędem. Zazwyczaj zawiera zadania przywracające poprzedni stan systemu, np. cofanie zmian, restart usług lub wysyłanie powiadomień.
Przykład: automatyczne przywrócenie poprzedniej konfiguracji
– block:
– name: Deploy new configuration
ansible.builtin.copy:
src: new.conf
dest: /etc/app/app.conf
backup: yes
rescue:
– name: Restore previous configuration
ansible.builtin.command: cp /etc/app/app.conf.backup /etc/app/app.conf
ignore_errors: yes
Dzięki sekcji rescue można automatycznie przywrócić system do poprzedniego, działającego stanu bez ręcznej interwencji.
4. Sekcja always – działania końcowe
Sekcja always wykonywana jest zawsze – niezależnie od tego, czy zadania w bloku zakończyły się sukcesem czy błędem. Najczęściej używana jest do logowania, czyszczenia plików tymczasowych lub informowania o zakończeniu procesu.
Przykład:
– block:
– name: Try to deploy
ansible.builtin.shell: ./deploy.sh
rescue:
– name: Deployment failed
ansible.builtin.debug:
msg: „Deployment failed.”
always:
– name: Clean temporary files
ansible.builtin.file:
path: /tmp/deploy.lock
state: absent
Nawet jeśli skrypt wdrożeniowy się nie powiedzie, plik tymczasowy zostanie usunięty.
5. Kontrola błędów a idempotentność
Bloki nie naruszają zasady idempotentności – jeśli zadania w bloku nie wprowadzają zmian, kolejne uruchomienia playbooka nie wykonują ich ponownie. Natomiast dzięki sekcji rescue i always można bezpiecznie reagować na błędy bez przerywania całego procesu automatyzacji.
6. Dobre praktyki w obsłudze błędów
- grupowanie zadań krytycznych w bloki,
- stosowanie rescue do przywracania stanu lub powiadomień,
- używanie always do czyszczenia środowiska,
- unikanie nadmiernego ignorowania błędów (ignore_errors: yes tylko w uzasadnionych przypadkach),
- łączenie bloków z handlerami i warunkami dla pełnej kontroli przepływu.
Podsumowanie
Mechanizmy block, rescue i always umożliwiają tworzenie odpornych na błędy i przewidywalnych playbooków. Dzięki nim można skutecznie zarządzać wyjątkami, minimalizować ryzyko awarii i zapewnić ciągłość działania systemów. Świadome wykorzystanie tych narzędzi jest kluczowe w profesjonalnych środowiskach DevOps i produkcyjnych automatyzacjach.