Skip to content

Handlerid ja rollid

Siiamaani me oleme kasutanud lihtsustatud versiooni playbookist. Tegelikult on selle struktuur järgnev, toetades suurt hulka märksõnu veel:

- hosts: all
  user: root

  vars: # Siin saab defineerida muutujaid terve playbooki jaoks
    ...

  pre_tasks: # Saab defineerida käskusid mis jooksevad enne rolle
    ...

  roles: # Saab defineerida rolle
    ...

  tasks: # Seda juba kasutasime
    ... 

  post_tasks: # Jookseb pärast taske
    ...

  handlers: # Handlerid
    ...

Siin praktilises osas vaatame kuidas handlers ja roles töötab.

Handlerite kasutus

Hetkel, igal Ansible käivitamisel, tehakse nginx teenusele restarti. See on natukene halb idempotentsuse aspektist, ja muudab Ansible selliseks, mida ei saa igal hetkel jooksutada, sest põhjustab väikse hetke mil veebiserver pole kättesaadav.

Õnneks inimesed, kes Ansible kirjutasid, mõtlesid sellele, ja implementeerisid funktsionaalsuse handlers. Need lubavad käivitada ülesande viimase asjana ainult juhul, kui mõni teine ülesanne muutus (CHANGED staatus).

Handlerite alla läheb kirja tegevus, mida on vaja teha, samasuguse käsuna nagu ta oleks tasks all. Seejärel, tuleb öelda millised käsud peaksid "teavitama" handlerit, kui nad muutusid:

- name: Install NGINX
  apt:
    name: nginx
    state: present
  notify: Restart nginx # Teavita selle nimega handlerit
  when: ansible_distribution == "Debian"

Seejärel, kui see käsk läheb muutunud staatusesse, siis tehakse playbooki lõpus nginx-ile resa. Ühe playbooki jooksul võib mitu käsu teavitada sama handlerit, tulemus on sama - käivitatakse playbooki lõpus!

Complete

Muuda olemasolevat playbooki nii, et nginx resa tehakse handleriga.

LISAINFO
- hosts: all
  user: root

  tasks:
    - name: Install NGINX
      dnf:
        name: nginx
        state: present
      notify: Restart nginx
      when: ansible_distribution == "CentOS"

    - name: Install NGINX
      apt:
        name: nginx
        state: present
      notify: Restart nginx
      when: ansible_distribution == "Debian"

    - name: Copy HTML file
      template:
        src: index.html
        dest: /usr/share/nginx/html/index.html
        force: true
      notify: Restart nginx
      when: ansible_distribution == "CentOS"

    - name: Copy HTML file
      template:
        src: index.html
        dest: /var/www/html/index.html
        force: true
      notify: Restart nginx
      when: ansible_distribution == "Debian"

  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted

Verify

Kaks varianti kuidas kontrollida tuleks.

Esimene, sundides peale muutuse, näiteks muutes HTML templiidi faili, pannes kuskile midagi juurde. Siis Ansiblet jooksutades peaks nginx-ile restarti tehtama.

Teine variant, ilma muudatusteta Ansible käima pannes. Siis, kui ükski staatust ei muutu, ei tohiks nginx restarti toimuda.

Rollid

Playbookid üksinda on väga kasulikud, kuid kui soovida lisada uus, sarnaste käskudega playbook, teise projekti, siis peab hakkama kopeerima YAML failist YAML faili. See ei ole väga hea lahendus, ja läheb otseselt DRY printsiibi vastu.

Ansible lahendab selle probleemi rollidega - grupeering muutujatest, käskudest, failidest, templiitidest ja handleritest, mis on eraldatud "tükk" muust Ansiblest. Rollidest võib mõelda kui funktsioonidest mõnest teegis teistes programmeerimiskeeltes.

Rolle on ka hästi lihtne jagada, sest nad on iseseisvad, kasutades väga kindlat failistruktuuri, mis algab ühest kaustast.

Rollid käivad roles kausta oma nimega, ja näevad välja sellised:

roles/
    ntp/                  # rolli grupeering
        tasks/            #
            main.yml      #  <-- see nimi on kohustuslik, aga kõrval võib olla ka teisi
        handlers/         #
            main.yml      #  <-- see nimi on kohustuslik, siia käivad kõik handlerid sisse
        templates/        #  <-- failid "template" mooduli jaoks
            ntp.conf.tpl  #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- failid "copy" mooduli jaoks
        vars/             #
            main.yml      #  <-- nimi on kohustuslik, vajalikud muutujad
        defaults/         #
            main.yml      #  <-- nimi on kohustuslik, väiksema prioriteediga muutujad
        meta/             #
            main.yml      #  <-- nimi on kohustuslik, metaandmed rolli kohta

Nagu näha, siis siin on olemas sarnased struktuurid nagu me playbookis kasutasime, s.t. kõik olemasoleva funktsionaalsuse saaks siia teisendada.

Ja sellist rolli, kui see asuks roles/ kaustas, saaks kasutada nii:

- hosts: all
  user: root

  roles: 
    - ntp

  tasks:
    - name: Info
      debug:
        msg: "Rolli kasutuse playbook!"

Asi, mis jääb alguses segaseks, on see, et roles/ntp/tasks/main.yml faili läheb ainult käskude osa, sinna ei panda playbookiga seotud infot. Näiteks:

roles/ntp/tasks/main.yml
- name: Info
  debug:
    msg: "Mina jooksen rolli seest!"

Rolli kutsutakse ikkagi välja kasutades playbooki, kuhu jääb info milliste seadmete vastu jooksutada, mis kasutajaga, jms.

Complete

Nüüd tuleks võtta ette meie playbook, ja kirjutada nginx roll, mis teeb kõik eelnevad sammud. Selleks tuleb:

  • Teha õige failipuu
  • Liigutada käsud playbookist rolli tasks sisse.
  • Liigutada HTML templiit rolli templates kausta.
  • Liigutada handlerite käsud rolli handlers sisse.
  • Viidata playbookis uue rolli peale.

Peale seda võib playbooki käima panna.

LISAINFO
playbook.yml
- hosts: all
  user: root

  roles:
    - nginx
roles/nginx/tasks/main.yml
- name: Install NGINX
  dnf:
    name: nginx
    state: present
  notify: Restart nginx
  when: ansible_distribution == "CentOS"

- name: Install NGINX
  apt:
    name: nginx
    state: present
  notify: Restart nginx
  when: ansible_distribution == "Debian"

- name: Copy HTML file
  template:
    src: index.html
    dest: /usr/share/nginx/html/index.html
    force: true
  notify: Restart nginx
  when: ansible_distribution == "CentOS"

- name: Copy HTML file
  template:
    src: index.html
    dest: /var/www/html/index.html
    force: true
  notify: Restart nginx
  when: ansible_distribution == "Debian"
roles/nginx/handlers/main.yml
- name: Restart nginx
  service:
    name: nginx
    state: restarted

Verify

Playbooki käima pannes peaks playbook läbi jooksma samamoodi kui enne. Rolli käivitamise pärast eraldi rida ei teki, lihtsalt pannakse samad ülesanded käima.

Praktilise osa lõpp

Kui lõpetasite praktilise osa, siis võib kasutada ülejäänud aega sirutuspausina! Tubli töö!