Playbooki w Ansible to zestaw instrukcji w których definiujemy co Ansible ma wykonać. Upraszczając, jest to zestaw skryptów, które mają zostać po sobie wykonane.
Playbook:
-zadanie2
-zadanie3
-zadanie4
………………………
-zadanie(n)
Naturalnie, wszystkie Playbooki przygotowujemy z wykorzystaniem języka YAML.
Dokładnie format YAML wyjaśniam w tym artykule: https://blog.askomputer.pl/co-to-jest-yaml/
Playbook to pojedynczy plik YAML. Zawiera on zestaw komend, które Ansible ma za zadanie wykonać. Poniżej masz jeden z najprostszych przykładów Playbooka, który można wykonać.
Wykonuje zaledwie jedno zadanie. Jest to instalacja aplikacji. W tym wypadku Zabbix Agent. Wygląda to następująco:
---
- hosts: bazadanych
become: True
tasks:
- name: Instalacja Zabbix Agent
yum: name="https://repo.zabbix.com/zabbix/7.4/release/alma/10/noarch/zabbix-release-latest-7.4.el10.noarch.rpm"
Jak to działa?
Warto się tu zatrzymać i omówić kolejne linie kodu.
1) hosts: bazadanych
Oznacza grupę hostów na jakich wykonujemy zadania. W tym przypadku grupa serwerów bazadanych. Informacja ta zostaje pobrana z pliku inventory.
2) become: True
Oznacza, że skrypt wykonywany jest z uprawnieniami konta root.
3) tasks:
Oznacza zadania do wykonania.
4) – name: Instalacja Zabbix Agenta
Oznacza nazwę naszego zadania. Możesz tu wpisać cokolwiek. Wszystko wg. swojego uznania. Grunt, by zacząć od – name:
5) yum: name=”http://repo.zabbix.com/zabbix/7.4/stable/alma/10/x86_64/zabbix-agent2-7.4.2-release1.el10.x86_64.rpm”
Oznacza instrukcję dotyczącą zadania. W tym wypadku korzystamy z modułu yum oznaczającego instalację konkretnego pakietu oprogramowania. W tym wypadku http://repo.zabbix.com/zabbix/7.4/stable/alma/10/x86_64/zabbix-agent2-7.4.2-release1.el10.x86_64.rpm
Warto jeszcze omówić „myślniki” zawarte w skrypcie.
Te trzy pierwsze w kodzie to najzwyczajniej część języka YAML. Oznacza start kodu. Można je jednak pominąć.
Natomiast te „myślniki” zawarte w skrypcie (przy hosts i name) oznaczają początek sekwencji. Ewentualnie, jak mówi oficjalna dokumentacja Ansible, listy. Obie nazwy są poprawne i możesz je stosować.
Warto dodać, że w Playbookach często jeszcze się stosuje polecenie:
update_cache=yes
oznacza aktualizację pakietów. Jest to coś w stylu apt-get update na Linuxie.
Uruchomienie Playbooka
Ansible przy uruchamianiu zadań korzysta z tzw. Modułów. Jest to zestaw dodatków i poleceń, które możemy stosować. Spis znajduje się w dokumentacji Ansible:
https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
Aby uruchomić przygotowany wcześniej Playbook należy uruchomić komendę:
ansible-playbook <nazwa pliku playbook>
Możesz wyświetli pomoc dotyczącą tej komendy:
ansible-playbook -–help
Ansible grupuje wyniki rezultatów kolorami:
Czerwień – zadanie nie wykonane
Żółty – wykonane
Zielone – nic nie trzeba było wykonać. Oznacza to, że stan jest już taki jak pożądany, więc Ansible nie wykonuje zmiany.
Playbook – Ćwiczenia
Zróbmy coś praktycznego. Stwórzmy prostą automatyzację. Najpierw w postaci zadania ad-hoc. Następnie przerobimy go na Playbook.
Wejdź do pliku, który uruchomiliśmy w części „Inwentarz”:
vi /root/agentz/inventory.txt
Mamy tam target1 i target2. Co prawda nie utworzyliśmy grupy, ale możesz użyć „all” jest to domyślna grupa dla wszystkich hostów w pliku inventory.
Najprostsza komenda wygląda następująco:
ansible all -m ping -i test-project/inventory.txt
Jest to tzw. polecenie ad-hoc. Nie wymaga żadnego pisania skryptów. Wystarczy:
– wywołać grupę ( w tym przypadku all)
– podać polecenie za pomocą flagi -m (tutaj prosty moduł ping)
– wskazać plik inwentaryzacyjny za pomocą flagi -i (możesz nie podawać tego, a wtedy Ansible skorzysta z domyślnego pliku inwentarza)
Więcej o module ping znajdziesz w tym miejscu. https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ping_module.html
Po uruchomieniu otrzymasz taki wynik:
Zautomatyzujmy to jeszcze bardziej! Przerobimy teraz to polecenie na Playbooka. Dzięki temu nie musisz za każdym razem wywoływać wszystkich poleceń. Wystarczy, że uruchomisz gotowy Playbook. Utworzymy sobie plik yaml:
vi playbook-pingtest.yaml
Wprowadź taką zawartość:
-
name: Test połączenia
hosts: all
tasks:
- name: Ping
ping:
Zapisujemy i odpalamy polecenie:
ansible-playbook playbook-pingtest.yaml -i test-project/inventory.txt
Jak widzisz, polecenie zostało wykonane poprawnie:
Module
Moduły to narzędzie Ansible, które pozwala nam tworzyć jeszcze bardziej rozbudowane zadania. Mają one na celu odwzorowanie poleceń systemu lub aplikacji, które chcemy zautomatyzować. Przykładowo Moduły „File” mają za zadanie zarządzanie plikami na takiej samej zasadzie jak to robisz w systemie operacyjnym.
Tu znajdziesz spis wszystkich modułów:
https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
Jeżeli nie wiesz jak działa dane polecenie to możesz je na szybko sprawdzić za pomocą:
ansible-doc polecenie
Np.:
ansible-doc ping
Listę wszystkich modułów i wtyczek wyświetlisz za pomocą:
ansible-doc -l
Możesz również szukać konkretnych wyrażeń jak w przykładzie poniżej:
ansible-doc -l | grep azure
Wyszukuje ono wszystkie moduły związane z Azure
Możemy również podejrzeć fragment kodu związanego z danym modułem za pomocą:
ansible-doc -s ping
Ta komenda tworzy plik new.txt w katalogu root hosta 192.168.0.202
ansible target1 -i inventory.txt -m copy -a 'content=”cos tu wpisz” dest=/root/new.txt’
Zauważ, ze jak uruchomisz jeszcze raz tą komendę, ale z inną treścią to usunie to co wcześniej wprowadziliśmy.
Taka komenda tworzy katalog z uprawieniami 755:
ansible target1 -i inventory.txt -m file -a „path=/root/nowe state=directory mode=755”
Warto zaznaczyć, że Ansible udostępnia przystępną dokumentację modułów. Wystarcz wpisać to co chcesz zrobić. Choćby „kopiowanie”:
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html
Jak zjedziesz niżej to znajdziesz dokładne przykłady użycia komend:

Jeszcze więcej ćwiczeń
Ok, trochę już umiesz. Utrwalimy teraz to wszystko. Plus, podniesiemy poprzeczkę. Wykonamy, pierwszy, bardziej rozbudowany projekt. Utworzymy skrypt, który automatycznie będzie instalował Zabbix Agent.
Jeżeli nie wiesz co to jest Zabbix to zapraszam w to miejsce:
Tworzymy nowy dysk projektowy
mkdir /root/agentz
Tworzymy w tym katalogu inventory.txt i podajemy dane do połączeń do naszych hostów.
Jak masz już inventory w innym miejscu to możesz sobie skopiować. Przykładowo:
cp /root/wdp/inventory.txt /root/agentz/
/root/wdp/inventory.txt to moja ścieżka z moim plikiem inwentaryzacyjnym.
Przetestuj połączenie z hostami:
ansible wdp -i /root/agentz/inventory.txt -m ping
wdp to host na którym będę instalował agent Zabbix.
W tym samym katalogu tworzę plik:
instalacja_agenta.yml
Posłuży mi za playbook.
Wybieram pasującą do mojego systemu wersję Zabbix Agent ze strony:

W tym przypadku:
http://repo.zabbix.com/zabbix/7.4/stable/alma/10/x86_64/zabbix-agent2-7.4.2-release1.el10.x86_64.rpm
Tworzymy prosty Playbook:
---
- hosts: all
become: True
tasks:
- name: Instalacja Zabbix Agent
dnf:
name: http://repo.zabbix.com/zabbix/7.4/stable/alma/10/x86_64/zabbix-agent2-7.4.2-release1.el10.x86_64.rpm
state: present
disable_gpg_check: yes
Uruchom playbook:
ansible-playbook -i inventory.txt instalacja_agenta.yml
Działa. Zainstalowane. Fajnie! Za chwilę to rozbudujemy. Poprawimy ten skrypt, by od razu:
– dokonywał konfiguracji Agenta
– uruchamiał go
– dodawał do autostartu.
Edytowanie pliku tekstowego
Zanim przejdziemy głębiej, nauczmy się edytować pliki za pomocą Ansible. Zróbmy najpierw prosty skrypt, który nam utworzy zdalny plik tekstowy.
Stworzymy plik:
createicopy.yml
w folderze:
/root/agentz/
Nasz skrypcik będzie wyglądał następująco:
---
# dodanie pliku
- hosts: agentz
become: True
tasks:
- file:
path: /root/madafaka.conf
state: touch
owner: root
group: root
mode: 0600
Odpalamy:
ansible-playbook -i inventory.txt dodanielini.yml
Teraz wy edytuj ten plik.
Najprostszy playbook jaki można utworzyć to:
---
# dodanie tekstu w pliku
- hosts: agentz
become: True
tasks:
- lineinfile:
path: /root/madafaka.conf
line: 'Pierwszy kod'
Kod ten doda nam tekst w pliku 'Pierwszy kod’
Ćwiczonko!
Zrób drugi taki Playbook, ale zmień frazę. Jak odpalisz to zauważysz, ze nowy tekst został dodany pod starym.

Może zróbmy teraz tak, by zamieniał wcześniejszy tekst na nowy. Przejdźmy do działania.
Robimy playbook zmianalini.yml
Wygląda następująco:
---
# zamiana tekstu w pliku
- hosts: agentz
become: True
tasks:
- lineinfile:
path: /root/madafaka.conf
regexp: 'Pierwszy kod abx'
line: 'Podmianka'
Najważniejsza zmiana to parametr regexp w kodzie. Wyszukuje on fragment w pliku tekstowym i zamienia na to co chcemy. W tym przypadku na „Podmianka”.
Odpalamy:
ansible-playbook -i inventory.txt zmianalini.yml
Na razie idzie gładko. Podnieśmy poprzeczkę i zróbmy tak, by nasz skrypt zamieniał kilka linii w tekście na raz i dodawał coś nowego.
Robimy playbook 2naraz.yml Treść wraz z komentarzami objaśniającymi:
---
# 2 taski zmiany pliku
- hosts: agentz
become: True
tasks:
# 1 task: podmiana tekstu
- lineinfile:
path: /root/madafaka.conf
regexp: 'Podmianka'
line: '3 zadanie'
# 2 task: dodanie kolejnej lini tekstu
- lineinfile:
path: /root/madafaka.conf
line: 'jeszcze tu daj '
I odpal:
ansible-playbook -i inventory.txt 2naraz.yml
Fakty
Skoro to już mamy zaliczone to teraz fajnie było gdyby taki skrypt dodawał w tekście jakąś konkretną zmienną. Np. adres IP lub hostname maszyny.
Zanim jednak do tego przejdziemy, pora nauczyć się trochę na temat zmiennych i faktów.
Fakty to zbiór informacji jakie zbiera ansible z hosta.
Odpal polecenie:
ansible target1 -i inventory.txt -m setup
i scrolluj
Setup wyświetla liste wszystkich faktów.
Dużo tego. Prawda? Dlatego warto sobie ułatwić i wyszukać to co nas konkretnie interesuje. Zrobisz to za pomocą parametru „filter”.
Np.:
ansible target1 -i inventory.txt -m setup -a 'filter=ansible_hostname*'
wyświetli nam nazwę hosta
Fakt jako zmienna
Skoro mamy nazwę hosta to można by go użyć jako zmienną.
Zmienne rejestrujemy za pomocą var.
Zrób plik pierwszazmienna.yml
Nasz kod wygląda następująco:
---
# nauka użycia zmiennej
- hosts: agentz
become: True
tasks:
- name: Odpal zmienną
command: df -h
register: dyski
- debug: var=dyski
Odpal:
ansible-playbook -i inventory.txt pierwszazmienna.yml
Co to robi? Przede wszystkim za pomocą „register” rejestrujesz zmienną o nazwie „dyski” z poleceniem zawartym w linii „command”.
Debug natomiast służy do wyświetlania komunikatów. W tym wypadku wyświetla wynik zmiennej.
Ok, znamy zmienne i fakty. To teraz jak je użyć, by wpleść ich wynik do pliku tekstowego?
Ważne jest teraz to, by teraz „oczyścić” wynik naszego kodu. Tworzymy nowy playbook:
pokahostname.yml
I nasz skrypt skryptu:
---
# hostname jako zmienna
- hosts: agentz
become: True
tasks:
- name: Pokaż hostname
command: hostname
register: nazwa
- debug: msg="{{ nazwa.stdout }}"
Co to robi? Przypisuje polecenie „hostname” do zmiennej „nazwa”, a następnie zwraca wynik w linii debug:msg
Mamy już bardziej „oczyszczony” wynik. Teraz jak zapisać ten wynik w pliku tekstowym?
Połączmy polecenia, których się nauczyliśmy. Zrób playbook odjazdtotalny.yml
A w nim taki skrypt:
#zmienna "nazwa" wskakuje do pliku madafaka.conf
- hosts: agentz
become: True
tasks:
- name: Pokaż hostname
command: hostname
register: nazwa
- debug: msg="{{ nazwa.stdout }}"
- lineinfile:
path: /root/madafaka.conf
line: "{{ nazwa.stdout }}"
Co to nam robi? Pierwszy task, rejestruje zmienną „nazwa”. Drugi wyświetla zmienną. To drugie jest zbędne, ale dla treningu warto przećwiczyć. W przyszłości eliminuj nadmiarowy kod.
Widzisz tu, ze wystarczyło skopiować playbooki pokahostname.yml i dodanielini.yml i cała robota. I trzeci task, czyli dodanie do pliku wyniku zmiennej.
Edycja w działaniu, czyli konfiguracja aplikacji
Dobra! Teraz zróbmy skrypt, który zmieni nam konfiguracje Zabbix Agenta.
Musimy zmodyfikować poniższe parametry:
EnableRemoteCommands=0
Server=192.168.1.1 //Adres serwera Zabbix
Hostname=Serwerek//Nazwa monitorowanego serwera
ListenPort=10051 //Port nasłuchowy)
StartAgents=5
Konfiguracja Zabbix Agent jest w tym pliku:
/etc/zabbix/zabbix_agentd.conf
Upraszczając, nasz skrypt powinien modyfikować te wszystkie linie.
Stwórzmy plik agentconfig.yaml
Na początek dodajmy pierwsze zadanie dodające EnableRemoteCommands
---
# edycja pliku konfiguracyjnego Zabbix Agenta
- hosts: agentz
become: True
tasks:
- lineinfile:
path: /etc/zabbix/zabbix_agentd.conf
insertbefore: '### Option: LogRemoteCommands'
line: 'EnableRemoteCommands=0'
Dodajmy teraz kolejne zadania z kolejnymi liniami
Wykorzystamy teraz moduły ansible do edycji plików. Szczegóły znajdziesz w dokumentacji:
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html
Na początek zróbmy sobie prosty skrypt, który podmieni nam jedną z tych wartości. Zabierzmy się za EnableRemoteCommands=0
W „świeżym pliku” (takim po nowej instalacji) siedzi pod postacią:
# EnableRemoteCommands=0
# oznacza komentarz. Co oznacza, że parametr nie działa. Musimy zatem wyrzucić z pliku #
Zrobimy to za pomocą takiego skryptu:
---
- name: Edycja pliku
hosts: agentz
become: True
tasks:
- name: Zmiana danych
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# EnableRemoteCommands=0'
replace: 'EnableRemoteCommands=0'
backup: yes
Zapisuję skrypt jako editconf.yml i wykonuję:
ansible-playbook -i inventory.txt editconf.yml
Sprawdź czy wartości się zmieniły.
Na razie jest łatwo, prawda? W dalszej kolejności poprawimy skrypt, by:
– edytował pozostałe elementy konfiguracji Agenta
– uruchamiał go Zabbix Agent
– dodawał Zabbix Agent autostartu.
Dalsza edycja pliku konfiguracyjnego
Generalnie, sprawa jest prosta. Wystarczy dodać nowe „taski”, by podmieniały kolejne kawałki pliku konfiguracyjnego. Np. tu dodajemy podmianę IP:
---
- name: Edycja pliku
hosts: agentz
become: True
tasks:
- name: Zmiana Remote
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# EnableRemoteCommands=0'
replace: 'EnableRemoteCommands=0'
backup: yes
- name: Zmiana IP
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Server=127.0.0.1'
replace: 'Server=192.168.0.100'
backup: yes
I jeszcze kolejne zadania:
---
- name: Edycja pliku
hosts: agentz
become: True
tasks:
- name: Zmiana Remote
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# EnableRemoteCommands=0'
replace: 'EnableRemoteCommands=0'
backup: yes
- name: Zmiana IP
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Server=127.0.0.1'
replace: 'Server=192.168.0.100'
backup: yes
- name: Zmiana Portu
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# ListenPort=10050'
replace: 'ListenPort=10051'
backup: yes
- name: Zmiana StartAgents
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# StartAgents=3'
replace: 'StartAgents=5'
backup: yes
Rejestrowanie zmiennej z faktów
Teraz pozostaje trudniejsze zadanie. Musimy dodać do pliku konfiguracyjnego informację o hostname. To co możemy wykorzystać to poznane wcześniej rejestrowanie zmiennej z wykorzystaniem filtru „hostname”. Samo zadanie wyglądać będzie tak:
tasks:
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Dodanie hostname
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Hostname=Zabbix server'
replace: 'Hostname={{ nazwa.stdout }}'
Najpierw mamy zadanie, które zarejestruje nam zmienną hostname odpowiadającą maszynie zdalnej. To na niej będzie wykonywane zadanie. Następnie wykonujemy ponownie „replace” z wykorzystaniem tej zmiennej. Podmieniamy 'Hostname=Zabbix server’ na 'Hostname={{ nazwa.stdout }}’, czyli Hostname = wynik polecenia hostname.
Naturalnie, połączymy to wszystko w jeden skrypt:
—
– name: Edycja pliku
hosts: agentz
become: True
tasks:
– name: Zmiana Remote
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# EnableRemoteCommands=0′
replace: 'EnableRemoteCommands=0′
backup: yes
– name: Zmiana IP
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Server=127.0.0.1′
replace: 'Server=192.168.0.100′
backup: yes
– name: Zmiana Portu
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# ListenPort=10050′
replace: 'ListenPort=10051′
backup: yes
– name: Zmiana StartAgents
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# StartAgents=3′
replace: 'StartAgents=5′
backup: yes
– name: Zarejestruj hostname
command: hostname
register: nazwa
– name: Dodanie hostname
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Hostname=Zabbix server’
replace: 'Hostname={{ nazwa.stdout }}’
Automatyczne zarządzanie usługami
Teraz zmodyfikujmy skrypt, by:
– uruchamiał go Zabbix Agent
– dodawał Zabbix Agent autostartu.
– odblokowywał port Zabbix agent
Za uruchomienie i dodanie do autostartu możemy wykorzystać proste polecenie:
– name: start zabbix-agent
service: name=zabbix-agent state=started enabled=yes
Za odblokowanie portów odpowiada moduł firewalld. Więcej znajdziesz tu:
https://docs.ansible.com/ansible/latest/collections/ansible/posix/firewalld_module.html
Nam wystarczy prosty task otwierający port 10051:
---
# odblokowanie portu
- hosts: agentz
become: True
tasks:
- name: odblokowanie portu
ansible.posix.firewalld:
port: 10051/tcp
permanent: yes
state: enabled
Oczywiście, warto uwzględnić dodatkowe zadanie przeładowujące firewalla. Zrobimy to poprzez dodanie zadania name: przeładuj firewall:
---
# odblokowanie portu
- hosts: agentz
become: True
tasks:
- name: odblokowanie portu
ansible.posix.firewalld:
port: 10051/tcp
permanent: yes
state: enabled
- name: przeładuj firewall
systemd:
name: ansible.posix.firewalld:
state: reloaded
Połączmy teraz duży skrypt z tymi dwoma ostatnimi w całość.
Wygląda to tak:
---
# konfiguracja agenta, start, dodanie do autostartu usługi i odblokowania portów
- name: Edycja pliku
hosts: agentz
become: True
tasks:
- name: Zmiana Remote
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# EnableRemoteCommands=0'
replace: 'EnableRemoteCommands=0'
backup: yes
- name: Zmiana IP
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Server=127.0.0.1'
replace: 'Server=192.168.0.100'
backup: yes
- name: Zmiana Portu
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# ListenPort=10050'
replace: 'ListenPort=10051'
backup: yes
- name: Zmiana StartAgents
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# StartAgents=3'
replace: 'StartAgents=5'
backup: yes
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Dodanie hostname
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Hostname=Zabbix server'
replace: 'Hostname={{ nazwa.stdout }}'
- name: start zabbix-agent
service: name=zabbix-agent state=started enabled=yes
- name: odblokowanie portu
ansible.posix.firewalld:
port: 10051/tcp
permanent: yes
state: enabled
- name: przeładuj firewall
systemd:
name: firewalld
state: reloaded
Przetestuj na świeżym pliku konfiguracyjnym czy wszystko działa.
Dodaję jeszcze instalacje agenta:
---
# instalacja agenta, konfiguracja agenta, start, dodanie do autostartu usługi i odblokowania portów
- name: Edycja pliku
hosts: agentz
become: True
tasks:
- name: Instalacja Zabbix Agent
yum: name="http://repo.zabbix.com/zabbix/7.4/stable/alma/10/x86_64/zabbix-agent2-7.4.2-release1.el10.x86_64.rpm"
- name: Zmiana IP
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Server=127.0.0.1'
replace: 'Server=192.168.0.100'
backup: yes
- name: Zmiana Portu
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# ListenPort=10050'
replace: 'ListenPort=10051'
backup: yes
- name: Zmiana StartAgents
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# StartAgents=3'
replace: 'StartAgents=5'
backup: yes
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Dodanie hostname
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Hostname=Zabbix server'
replace: 'Hostname={{ nazwa.stdout }}'
- name: start zabbix-agent
service: name=zabbix-agent state=started enabled=yes
- name: odblokowanie portu
ansible.posix.firewalld:
port: 10051/tcp
permanent: yes
state: enabled
- name: przeładuj firewall
systemd:
name: firewalld
state: reloaded
Restart Serwera
To co jeszcze warto rozważyć to dodanie do skryptu zadanie restartu maszyny na koniec. Osobiście, wolę, by maszyna po instalacji Zabbix Agenta została zrestartowana. Eliminuje to wszelkie problemy i błędy. Dodam zatem takie polecenie:
---
# restart maszyny
- hosts: agentz
become: True
tasks:
- name: Restart
reboot:
Całość zatem będzie wyglądać następująco:
---
# instalacja agenta, konfiguracja agenta, start, dodanie do autostartu usługi, odblokowania portów i restart
- name: Edycja pliku
hosts: agentz
become: True
tasks:
- name: Instalacja Zabbix Agent
yum: name="http://repo.zabbix.com/zabbix/7.4/stable/alma/10/x86_64/zabbix-agent2-7.4.2-release1.el10.x86_64.rpm"
- name: Zmiana IP
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Server=127.0.0.1'
replace: 'Server=192.168.0.100'
backup: yes
- name: Zmiana Portu
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# ListenPort=10050'
replace: 'ListenPort=10051'
backup: yes
- name: Zmiana StartAgents
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: '# StartAgents=3'
replace: 'StartAgents=5'
backup: yes
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Dodanie hostname
replace:
path: /etc/zabbix/zabbix_agentd.conf
regexp: 'Hostname=Zabbix server'
replace: 'Hostname={{ nazwa.stdout }}'
- name: start zabbix-agent
service: name=zabbix-agent state=started enabled=yes
- name: odblokowanie portu
ansible.posix.firewalld:
port: 10051/tcp
permanent: yes
state: enabled
- name: przeładuj firewall
systemd:
name: firewalld
state: reloaded
- name: Restart
reboot:
Jinja Template
Kolejna sprawa to tego typu wykonany skrypt nie jest idealny. Przykładowo, zamiast używać podmiany tekstu w pliku można by użyć szablony Jinja. Czemu? Głównie dlatego, ze w przypadku gdyby pojawiła się aktualizacja zmieniająca fragmenty pliku konfiguracyjnego to ten skrypt mógłby przestać działać.
Zróbmy plik 3_zasobyIT.yml
---
- hosts: agentz
vars:
aplikacja: "SuperERP"
serweryDB: 3
DB_Engine: "Oracle"
CPU: '4 vCPU'
Memory: "4096 mb"
Dysk: "2 TB"
tasks:
- name: Konfiguracja pliku
template:
src: /root/agentz/ 4_config.cfg.j2
dest: /usr/lib/zabbix/alertscripts/
To co tu użyliśmy to moduł Ansible zwany „template”. Jest to potężne narzędzie. Szczegóły znajdziesz tu:
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_templating.html
Bardzo ważny jest ten fragment:
src: /root/agentz/4_config.cfg.j2
To pokazuje ścieżkę do pliku, który będziemy edytować.
Natomiast to:
dest: /usr/lib/zabbix/alertscripts/
Pokazuje gdzie ma plik po edycji wylądować.
Nasz plik 4_config.cfg.j2 wygląda następująco:
## To jest plik konfiuracyjny maszyny wirtualnej.
Typ = {{ aplikacja }}
Bazy Danych = {{ serweryDB }}
Typ Bazy = {{ DB_Engine }}
Processor = {{ CPU }}
Available Memory = {{ Memory }}
Przestrzeń Dyskowa = {{ Dysk }}
IP Serwer = {{ Adres_IP }}
Enable = Yes
Jest to MEGAuproszczony plik konfiguracyjny maszyny wirtualnej wykorzystanej przez naszą aplikację. Zdaję sobie sprawę, ze nie jest on najpiękniejszy, jednak w tym wypadku zależy mi, by był dla Ciebie jak najbardziej zrozumiały. A nie chcę bawić się w przykłady w stylu grupowanie postaci z Disneya jak to ma w zwyczaju robić większość trenerów od Ansible
Odpalamy playbooka:
ansible-playbook -i inventory.txt 3_zasobyIT.yml
Zajrzyj na zdalną maszynę. Powinieneś znaleźć plik /usr/lib/zabbix/alertscripts/4_config.cfg.j2
Który będzie wyglądach następująco:

Konfiguracja pliku za pomocą modułu Template
Pewnie się domyślasz co będzie dalej
Teraz dokonamy konfiguracji pliku konfiguracyjnego Zabbix Agent za pomocą template
Umieścimy teraz szablon w postaci pliku zabbix_agentd.conf
Podmienimy w nim wartości, które wcześniej edytowaliśmy na:
Server={{ adresIP }}
ListenPort={{ ListenPort }}
StartAgents={{ StartAgents }}
Hostname={{ hostname }}
Teraz zróbmy playbooka, który zamieni te wartości na właściwe. Tworzymy plik 5_template_zabagent.yml o takiej treści:
---
- hosts: agentz
vars:
adresIP: "192.168.0.100"
ListenPort: 10051
StartAgents: 5
hostname: target1
tasks:
- name: Konfiguracja pliku
template:
src: /root/agentz/zabbix_agentd.conf
dest: /usr/lib/zabbix/alertscripts/
Oczywiście, to nie zrobi nam zadania w 100%. Jak widzisz hostname jest przypisany ręcznie na target1. Trzeba to poprawić za pomocą specjalnej zmiennej, którą poznałeś już wcześniej.
Wygląda to tak:
---
- hosts: agentz
tasks:
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Konfiguracja pliku
template:
src: /root/agentz/zabbix_agentd.conf
dest: /usr/lib/zabbix/alertscripts/
vars:
adresIP: "192.168.0.100"
ListenPort: 10051
StartAgents: 5
hostname: "{{ nazwa.stdout }}"
Dodaliśmy tu:
- name: Zarejestruj hostname
command: hostname
i tu:
hostname: "{{ nazwa.stdout }}"
Zmienne
Variable, czyli zmienne służą do przechowywania informacji o każdym hoście i uzupełnienie inventory
Przykład. Masz taki Playbook:
name: Dodanie adresu DNS
hosts: agentz
tasks:
- lineinfile:
path: /etc/resolv.conf
line: 'nameserver 192.168.0.100'
Zamiast dodawać w linii Line adresu serwera możesz dodać Variable w następujący sposób:
vars:
dns: 192.168.0.100
A następnie dać odwołanie do variable za pomocą {{ dns }}. Ostateczny wynik będzie wyglądać następująco:
name: Dodanie adresu DNS
hosts: agentz
vars:
dns: 192.168.0.100
tasks:
- lineinfile:
path: /etc/resolv.conf
line: 'nameserver {{ dns }}'
Loops – Pętle
Gdybyś miał za zadanie uruchomić większą liczbę modułów to możesz, zamiast wypisać wszystkich zadań w playbooku po kolei jak tu:
name: Instalacja Oprogramowania
hosts: agentz
tasks:
- yum: name= sos state=present
- yum: name= httpd state=present
- yum: name= mysql state=present
zrobić pętle wykorzystując ‘{{ item }}’. Wygląda to następująco:
name: Instalacja Oprogramowania
hosts: agentz
tasks:
- yum: name='{{ item }}' state=present
with_items:
- sos
- httpd
- mysql
Pętla
A gdybyśmy chcieli wykorzystać wspominaną wcześniej „Pętlę” w naszym Playbooku?
By była jasność. To co za chwilę pokażę, nie jest optymalnym sposobem tego typu modyfikacji. Zdecydowanie lepiej byłoby w dalszym ciągu korzystać z modułu Template. Chcę jednak byś w tym momencie zrozumiał działanie pętli.
Wróćmy do skryptu:
---
- hosts: agentz
tasks:
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Konfiguracja pliku
template:
src: /root/agentz/zabbix_agentd.conf
dest: /usr/lib/zabbix/alertscripts/
vars:
adresIP: "192.168.0.100"
ListenPort: 10051
StartAgents: 5
hostname: "{{ nazwa.stdout }}"
Dodajmy nieduży fragment (- name: Dodanie Userparameter do line: 'UserParameter=extra,ps aux | wc -l’ :
---
- hosts: agentz
tasks:
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Konfiguracja pliku
template:
src: /root/agentz/zabbix_agentd.conf
dest: /usr/lib/zabbix/alertscripts/
- name: Dodanie Userparameter
lineinfile:
path: /usr/lib/zabbix/alertscripts/zabbix_agentd.conf
line: 'UserParameter=extra,ps aux | wc -l’
vars:
adresIP: "192.168.0.100"
ListenPort: 10051
StartAgents: 5
hostname: "{{ nazwa.stdout }}"
Po dodaniu takiego fragmentu na koniec zadania „template” Ansibe wykona jeszcze jedno zadanie. Doda UserParameter na samym końcu pliku konfiguracyjnego Zabbixa. Nie będę teraz dokładnie tłumaczył co to jest. Omawiałem to niejednokrotnie na moim newsletterze lub w rozszerzonej wersji w ramach Kursu Zabbix mojego autorstwa.
Dodam, że jest to swego rodzaju skrypt, który możemy zdefiniować i monitorować wg własnego uznania.
Co jednak gdybyśmy chcieli na dużej liczbie Agentów dodać pewną liczbę Userparameter? Wykorzystajmy pętlę:
---
- hosts: agentz
tasks:
- name: Zarejestruj hostname
command: hostname
register: nazwa
- name: Konfiguracja pliku
template:
src: /root/agentz/zabbix_agentd.conf
dest: /usr/lib/zabbix/alertscripts/
- name: Pętla Dodanie Userparameter
lineinfile:
path: /usr/lib/zabbix/alertscripts/zabbix_agentd.conf
line: "{{ item }}"
with_items:
- 'UserParameter=extra,ps aux | wc -l'
- 'UserParameter=extra,cat /etc/passwd | wc -l'
vars:
adresIP: "192.168.0.100"
ListenPort: 10051
StartAgents: 5
hostname: "{{ nazwa.stdout }}"
Działanie tego powyżej jest proste.
Najpierw definiujemy:
lineinfile:
path: /usr/lib/zabbix/alertscripts/zabbix_agentd.conf
line: "{{ item }}"
Jest to stara i dobrze znana już Ci metoda na dodanie tekstu do pliku.
Tylko tu jest taka różnica, że dodawany tekst jest definiowany „{{ item }}”
Jest to pętla, której koleje zadania (items) definiowane są w tym miejscu:
- 'UserParameter=extra,ps aux | wc -l'
- 'UserParameter=extra,cat /etc/passwd | wc -l'
Jak już ostatnie zadanie zostanie wykonane to pętla zostanie zakończona. Naturalnie, możesz w ten sposób dodać kolejne zadania.
Szyfrowanie
Przejdźmy do bardzo ważnego aspektu. Szyfrowanie i bezpieczeństwo.
Przecież Ansible do komunikacji używa otwartego pliku z hasłami! Szaleństwo prawda? Pora się tym zając i zabezpieczyć połączenie.
Przejdźmy do (jak to zwykłem nazywać) schronu. Omówimy funkcję:
Ansible-vault
Jest to wewnętrzne narzędzie Ansible, które pozwala nam zaszyfrować plik inventory.
Szyfrujesz taki plik za pomocą komendy:
ansible-vault encrypt inventory.txt
Ewentualnie, możesz utworzyć nowy, już zaszyfrowany plik:
ansible-vault secret inventory_nowy.txt
Oczywiście inventory.txt to twój plik inwentaryzacyjny. Pojawi się prośba o podanie hasła:

Moje hasło to: Samolot5
Gdy teraz zajrzysz do pliku to ujrzysz coś takiego:

Teraz, aby skorzystać z takiego pliku w playbooku, musisz użyć zmiennej var_files i odwołać się w nim do pliku inwentaryzacyjnego.
Natomiast, podczas uruchamiania plybooka musisz użyć komendy:
--ask-vault-pass
Np.:
ansible-playbook 8_skrypcik.yml --ask-vault-pass -i inventory.txt
--ask-vault-pass
pokazuje, że chcesz użyć zaszyfrowanego pliku z inventory
-i to naturalnie wskazanie zaszyfrowanego pliku
Optymalizacja
Od razu dodam, że przedstawione opcje optymalizacji nie są jedynymi. Istnieje jeszcze spora liczba zależności, które ostatecznie wpływają na to jak płynnie wykonywane są polecenia przez Ansible. Wliczając w to parametry samego serwera Ansible i zdalnych hostów.
Jeżeli interesuje Cię bardziej zaawansowane podejście to zapraszam na mój Kurs Ansible:
https://asdevops.pl/kurs-ansible
Pipelining to opcja, która jest domyślnie wyłaczona w Ansible. Aby to zmienić musisz wy edytować plik /etc/ansible/ansible.cfg
I zmienić w tej sekcji

pipelining na True:

Jest jednak jeszcze lepsza opcja. Tztw Mitogen. Jest to plugin dla Ansible.
Znajdziesz go w tym miejscu:
https://mitogen.networkgenomics.com/ansible_detailed.html
Instalacja wtyczki opisana jest w tym miejscu:
https://mitogen.networkgenomics.com/ansible_detailed.html#installation
Polecam jeżeli wykonujesz skomplikowane zadania z pomocą Ansible. Znacząco podnosi szybkość wykonywanych skryptów.
Kurs Ansible i Automatyzacja IT
Gratulacje! Dotarłeś do końca. Oczywiście, tylko tego podręcznika. Naturalnie, Ansible i Automatyzacja IT jest tak rozległym zagadnieniem, że nie da się przekazać wszystkiego co bym chciał w ramach darmowego ebooka.
Dlatego mam dla Ciebie coś jeszcze. Jeżeli chcesz się jeszcze lepiej nauczyć się Ansible to zapraszam Cię na mój kurs:
Ansible i Automatyzacja IT
Wiedza zawarta w tym podręczniku to zaledwie wycinek tego co znajdziesz w pełnym kursie. Jesteś zainteresowany? W takim razie zobacz czego nauczysz się podczas kursu.
https://asdevops.pl/end-kurs-ansible/#section-1
Bezpłatne warsztaty: NMAP – Skanowanie Urządzeń i Portów w Sieci
Dowiedz się, jak wykrywać urządzenia w sieci, skanować porty i identyfikować usługi przy użyciu narzędzia NMAP. Poznasz podstawy skanowania, analizę wyników oraz praktyczne zastosowania w audycie bezpieczeństwa i testach penetracyjnych.
Środa, 18 marca o 14:00
