optymalizacja ansible

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

Sprawdź szczegóły: https://asdevops.pl/warsztaty/

 

 

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:

http://repo.zabbix.com

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

Co można jeszcze zrobić? Zoptymalizować. Usuńmy to tworzenie backupu po każdej edycji pliku konfiguracyjnego. Następnie, warto pomyśleć o pętli.

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

Przy uruchomieniu pojawi się prośba o podanie hasła, które wykorzystałeś do zaszyfrowania pliku inwentaryzacyjnego.

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

Sprawdź szczegóły: https://asdevops.pl/warsztaty/

 

 

 

 

Darmowe warsztaty NMAP - Skanowanie Urządzeń i Portów W Sieci

X