Pereiti prie pagrindinio turinio

Kaip sukurti pirmąjį Ansible playbook

Šioje pamokoje parodysime, kaip sukurti ir paleisti pirmąjį Ansible playbook, kad galėtumėte automatizuoti užduotis keliuose serveriuose.

0. Įvadas į Ansible playbook

Pamokoje Darbo su Ansible pradžia paaiškinome darbo su Ansible pagrindus: kaip sukurti Ansible inventory, nuotoliniu būdu prisijungti prie kitų serverių ir vykdyti juose komandas.

Pavyzdžiui, šią komandą galite paleisti norėdami patikrinti disko užimtumą konkrečiuose serveriuose:

ansible all -i inventory.ini -a "df -h"

Pavienėms komandoms tai puikiai tinka, bet sudėtingesnėms užduotims jau nelabai. Tarkime, reikia atnaujinti galimų paketų sąrašą, įdiegti Nginx, jį paleisti ir įjungti automatinį paleidimą:

sudo apt update
sudo apt install nginx
sudo systemctl start nginx
sudo systemctl enable nginx

Kartoti šias komandas rankiniu būdu keliuose serveriuose vėl ir vėl yra nepatogu ir užima daug laiko, ypač kai serverių daug. Būtent tokiems atvejams ir sukurti Ansible playbook.

Playbook yra scenarijus, tiksliai nurodantis, ką Ansible turi daryti: įdiegti paketus, sukurti naudotojus, nukopijuoti failus ar paleisti tarnybą iš naujo. Iš esmės tai paprastas užduočių sąrašas, todėl playbook greitai perskaitomas ir lengvai redaguojamas.

Keli užduočių, kurias su playbook galima vykdyti keliuose serveriuose vienu metu, pavyzdžiai:

  • programinės įrangos diegimas;

  • failų ir katalogų kūrimas;

  • tarnybų konfigūravimas;

  • sistemos naudotojų valdymas.

0.1 Kaip veikia Ansible playbook

Playbook yra failas, parašytas YAML formatu. YAML yra tekstinis formatas, naudojamas konfigūracijos failams kurti.

Playbook paprastai sudaro trys pagrindiniai elementai:

  • Hostai (hosts): serveriai, kuriuose bus vykdomos užduotys.

  • Užduotys (tasks): veiksmai, kuriuos reikia atlikti valdomuose hostuose.

  • Moduliai (modules): kodas arba vykdomieji failai, kuriuos Ansible naudoja konkretiems veiksmams valdomuose hostuose atlikti, pavyzdžiui, paketams diegti ar failams kopijuoti.

Daugiau informacijos apie Ansible sąvokas rasite čia.

Ansible užduotis vykdo tokia tvarka, kokia jos išvardytos playbook. Tą patį playbook galite paleisti kelis kartus. Ansible automatiškai patikrina, ar prašomi pakeitimai jau pritaikyti, ir pakartotinai nevykdo užduočių, kurios jau atliktos.

0.2 Reikalavimai

Prieš tęsdami ir pradėdami kurti pirmąjį playbook, įsitikinkite, kad atlikote ankstesnę pamoką:

Jau turėtumėte turėti:

  • valdymo serverį su įdiegtu Ansible;

  • vieną ar kelis valdomus VPS;

  • SSH prieigą prie valdomų serverių;

  • ankstesnėje pamokoje sukurtą inventory failą;

  • naudotoją su sudo teisėmis valdomuose serveriuose.

Toliau naudosime tą patį pavyzdį kaip ankstesnėje pamokoje:

Serveris

IP adresas

SSH naudotojas

Ubuntu

192.0.2.10

adminuser

AlmaLinux

192.0.2.20

adminuser

Mūsų pavyzdyje inventory failas inventory.ini atrodo taip:

[ubuntu]
ubuntu1 ansible_host=192.0.2.10 ansible_user=adminuser

[alma]
alma1 ansible_host=192.0.2.20 ansible_user=adminuser

[linux:children]
ubuntu
alma

IP adresus ir naudotojo vardą (mūsų pavyzdyje adminuser) pakeiskite savo VPS duomenimis.

1. Ansible katalogo paruošimas

Pirmiausia prisijunkite per SSH prie valdymo serverio (serverio su Ansible).

Pereikite į katalogą ansible-lab (sukurtą ankstesnėje pamokoje):

cd ~/ansible-lab

Patikrinkite katalogo failus:

ls -l

Turėtumėte matyti inventory failą:

inventory.ini

Taip pat patikrinkite, ar Ansible gali prisijungti prie valdomų serverių:

ansible all -i inventory.ini -m ping

Abu serveriai turi grąžinti:

"ping": "pong"

Jei viskas teisingai, galite kurti pirmąjį playbook.

2. Pirmojo Ansible playbook sukūrimas

Sukursime playbook, kuris atliks šias užduotis:

  • Įdiegs nginx paketą valdomuose serveriuose.

  • Paleis Nginx tarnybą ir įjungs jos automatinį paleidimą po serverio perkrovimo.

  • Sukurs tekstinį failą su pasirinktu pranešimu.

Sukurkite naują playbook failą:

nano first-playbook.yml

Įklijuokite šį turinį:

---
- name: Install and configure Nginx
hosts: linux
become: true

tasks:
- name: Update APT cache and install Nginx (Ubuntu/Debian)
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
cache_valid_time: 3600
when: ansible_facts['os_family'] == "Debian"

- name: Update DNF cache and install Nginx (AlmaLinux/Rocky)
ansible.builtin.dnf:
name: nginx
state: present
update_cache: true
when: ansible_facts['os_family'] == "RedHat"

- name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true

Išsaugokite pakeitimus ir išeikite.

Svarbu. YAML jautrus atitraukimams (indentation), todėl įsitikinkite, kad visi jūsų playbook atitraukimai tiksliai atitinka mūsų pavyzdį. Visada naudokite tarpus, o ne tabuliavimo simbolius.

3. Playbook struktūros paaiškinimas

3.1 Playbook pavadinimas

- name: Prepare Linux servers

name veikia kaip veiksmų rinkinio antraštė. Jis padeda suprasti, ką tiksliai daro Ansible. Pavadinimą galite pasirinkti bet kokį.

3.2 Tiksliniai serveriai

hosts: linux

hosts nurodo serverius, kuriuose turi būti vykdomos užduotys. Mūsų pavyzdyje tai grupė linux, kurią sudaro ir Ubuntu, ir Alma serveriai. Vadinasi, žemiau nurodytos užduotys bus vykdomos šios grupės serveriuose.

Galite nurodyti ir kitas grupes, pavyzdžiui, ubuntu:

hosts: ubuntu

Tokiu atveju playbook užduotys bus vykdomos tik Ubuntu serveriuose.

Jei užduotis norite vykdyti tik Alma serveriuose:

hosts: alma

Taip pat galite nurodyti visus inventory faile esančius serverius:

hosts: all

3.3 Root teisės

become: true

Kartais konkrečioms operacijoms atlikti reikalingos root teisės. become: true leidžia operacijas vykdyti su sudo.

Playbook become atitinka parametrą -b, kurį naudojome ankstesnės pamokos komandose.

3.4 Užduotys

tasks:

tasks sekcijoje surašyti veiksmai, kuriuos Ansible turi atlikti valdomuose hostuose. Kiekviena užduotis turi ją apibūdinantį pavadinimą (name).

Mūsų pavyzdyje yra trys užduotys.

Pirma užduotis: Update APT cache and install Nginx (Ubuntu/Debian)

    - name: Update APT cache and install Nginx (Ubuntu/Debian)
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
cache_valid_time: 3600
when: ansible_facts['os_family'] == "Debian"

Ši užduotis atnaujina APT paketų sąrašą ir įdiegia Nginx Ubuntu bei Debian serveriuose.

ansible.builtin.package leidžia pasirinkti tinkamą paketų tvarkyklę pagal operacinę sistemą. Mūsų atveju naudojame ansible.builtin.apt – modulį, skirtą programinei įrangai valdyti Debian ir Ubuntu sistemose. Su juo galima atnaujinti paketus, įdiegti ar pašalinti programas arba patikrinti jų būseną.

  • name: nginx nurodo paketą, su kuriuo dirbama. Mūsų atveju tai Nginx. Paprastai tariant, dirbsime su Nginx.

  • state: present patikrina Nginx būseną valdomuose serveriuose. Jei Nginx jau įdiegtas, playbook jo pakartotinai diegti nebandys.

  • update_cache: true atnaujina galimų apt paketų sąrašą.

  • cache_valid_time: 3600 atnaujina galimų apt paketų sąrašą, jei jis senesnis nei 3600 sekundžių (1 valanda).

  • when yra sąlyga, nurodanti, kada užduotis turi būti vykdoma. Šiuo atveju sąlyga yra ansible_facts['os_family'] == "Debian". Tai reiškia, kad užduotis bus vykdoma tik Debian pagrindu veikiančiose sistemose (įskaitant Ubuntu).

Antra užduotis: Update DNF cache and install Nginx (AlmaLinux/Rocky)

    - name: Update DNF cache and install Nginx (AlmaLinux/Rocky)
ansible.builtin.dnf:
name: nginx
state: present
update_cache: true
when: ansible_facts['os_family'] == "RedHat"

Ši užduotis įdiegs Nginx AlmaLinux ir Rocky Linux sistemose. Principas panašus kaip ankstesnės užduoties.

ansible.builtin.dnf nurodo, kad naudosime DNF paketų tvarkyklę.

Visi kiti parametrai tokie patys. Skirtumas tas, kad čia nėra cache_valid_time: 3600. Tikrinti, ar paketų sąrašas pasenęs, nereikia, nes DNF tai patikrina pats.

when: sąlyga yra ansible_facts['os_family'] == "RedHat", nes ši užduotis bus vykdoma tik RedHat pagrindu veikiančiose sistemose (mūsų atveju AlmaLinux ir Rocky Linux).

Trečia užduotis: Start and enable Nginx

    - name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true

Ši užduotis paleis Nginx ir nustatys, kad jis automatiškai pasileistų po kiekvieno perkrovimo (enable).

  • ansible.builtin.service: modulis nurodo, kad dirbsime su tarnybomis.

  • name: vėl yra nginx.

  • state: started patikrina, ar Nginx tarnyba jau paleista.

  • enabled: true nustato, kad Nginx automatiškai pasileistų po serverio perkrovimo.

Jei Nginx jau veikia ir yra įjungtas automatinis paleidimas po kiekvieno perkrovimo, užduotis jo nekeičia.

Ši užduotis bus vykdoma ir Debian, ir RedHat pagrindu veikiančiose sistemose, todėl sąlygos when čia nėra.

4. Playbook patikra prieš paleidžiant

Visada verta prieš paleidžiant playbook patikrinti jo sintaksę.

Vykdykite šią komandą:

ansible-playbook -i inventory.ini first-playbook.yml --syntax-check

Jei sintaksė teisinga, pamatysite:

playbook: first-playbook.yml

Taip pat galite paleisti šią komandą ir pamatyti, kuriuos serverius playbook paveiks:

ansible-playbook -i inventory.ini first-playbook.yml --list-hosts

Turėtumėte pamatyti:

playbook: first-playbook.yml

play #1 (linux): Install and configure Nginx
pattern: ['linux']
hosts (2):
ubuntu1
alma1

Tai dar nieko nepakeis jūsų serveriuose.

5. Pirmojo playbook paleidimas

Dabar galime paleisti savo playbook.

Įveskite šią komandą (-K nereikia, jei jūsų naudotojui sudo slaptažodis nenustatytas):

ansible-playbook -i inventory.ini first-playbook.yml -K

Ansible vykdys užduotis visuose valdomuose serveriuose.

Turėtumėte pamatyti panašią išvestį:

PLAY [Install and configure Nginx] *****************************

TASK [Gathering Facts] ******************************************
ok: [ubuntu1]
ok: [alma1]

TASK [Update APT cache and install Nginx (Ubuntu/Debian)] *******
changed: [ubuntu1]
skipping: [alma1]

TASK [Update DNF cache and install Nginx (AlmaLinux/Rocky)] *****
skipping: [ubuntu1]
changed: [alma1]

TASK [Start and enable Nginx] **********************************
changed: [ubuntu1]
changed: [alma1]

PLAY RECAP *****************************************************
ubuntu1 : ok=3 changed=2 unreachable=0 failed=0 skipped=1
alma1 : ok=3 changed=2 unreachable=0 failed=0 skipped=1
  • ok reiškia, kad užduotis įvykdyta sėkmingai. Skaičius 3 reiškia, kad visos trys užduotys buvo įvykdytos be problemų.

  • changed reiškia, kad užduotis valdomame serveryje iš tikrųjų atliko pakeitimus. Mūsų atveju skaičius 2 reiškia, kad kiekviename serveryje pakeitimus atliko dvi užduotys.

  • unreachable reiškia, kad serveris buvo nepasiekiamas. Mūsų atveju visi serveriai veikia ir yra pasiekiami, todėl skaičius 0.

  • failed reiškia, kad užduotis susidūrė su klaida. Mūsų atveju visos užduotys įvykdytos sėkmingai, todėl skaičius taip pat 0.

  • skipped yra praleistų užduočių skaičius. Ansible praleidžia užduotį, jei ji netinka konkrečiam serveriui. Mūsų atveju Ansible praleidžia APT užduotį RedHat serveriuose ir DNF užduotį Debian bei Ubuntu serveriuose.

6. Patikrinkite, ar playbook suveikė

Iš valdymo serverio vykdykite šią komandą:

ansible linux -i inventory.ini -a "systemctl is-active nginx"

Turėtumėte pamatyti:

ubuntu1 | CHANGED | rc=0 >>
active

alma1 | CHANGED | rc=0 >>
active

Abu valdomi serveriai turi pateikti tą patį rezultatą: active.

Patikrinkite, ar Nginx įjungtas automatiniam paleidimui po kiekvieno perkrovimo:

ansible linux -i inventory.ini -a "systemctl is-enabled nginx"

Abu serveriai turėtų grąžinti:

enabled

7. Playbook paleidimas dar kartą

Kaip minėjome anksčiau, jei reikiami nustatymai jau pritaikyti, Ansible jokių pakeitimų nedaro. Šis principas vadinamas idempotentiškumu (idempotency).

Dar kartą paleiskite tą patį playbook:

ansible-playbook -i inventory.ini first-playbook.yml -K

Šį kartą, jei valdomuose serveriuose nieko nepasikeitė, išvestis turėtų atrodyti taip:

TASK [Update APT cache and install Nginx (Ubuntu/Debian)] *******
ok: [ubuntu1]
skipping: [alma1]

TASK [Update DNF cache and install Nginx (AlmaLinux/Rocky)] *****
skipping: [ubuntu1]
ok: [alma1]

TASK [Start and enable Nginx] **********************************
ok: [ubuntu1]
ok: [alma1]

PLAY RECAP *****************************************************
ubuntu1 : ok=3 changed=0 unreachable=0 failed=0 skipped=1
alma1 : ok=3 changed=0 unreachable=0 failed=0 skipped=1

Šį kartą changed reikšmė bus:

changed=0

Tai reiškia, kad Ansible patikrino serverio konfigūraciją ir nenustatė, kad Nginx reikėtų iš naujo diegti, paleisti ar įjungti.

8. Playbook keitimas

Dabar atliksime nedidelį pakeitimą, kad pamatytume, kaip Ansible aptinka konfigūracijos skirtumus.

Šiame pavyzdyje pakeisime enabled parametrą.

Atidarykite playbook:

nano first-playbook.yml

Suraskite šią užduotį:

    - name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true

Pakeiskite ją šiuo turiniu:

    - name: Start Nginx without enabling it at boot
ansible.builtin.service:
name: nginx
state: started
enabled: false

Išsaugokite failą.

Dar kartą paleiskite playbook:

ansible-playbook -i inventory.ini first-playbook.yml -K

Dabar Ansible pastebės neatitikimą tarp Nginx paleidimo konfigūracijos serveryje ir tos, kuri nurodyta playbook.

Turėtumėte pamatyti:

TASK [Start Nginx without enabling it at boot]
changed: [ubuntu1]
changed: [alma1]

Taigi Ansible atnaujino tarnybos konfigūraciją abiejuose serveriuose. Nustatymas enabled: false sustabdo automatinį Nginx paleidimą po perkrovimo.

Tačiau vis dar turime:

state: started

Todėl Nginx toliau veikia.

Norėdami grąžinti pradinę konfigūraciją, vėl atidarykite playbook:

nano first-playbook.yml

Turinį pakeiskite atgal į:

    - name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true

Išsaugokite failą ir dar kartą paleiskite playbook:

ansible-playbook -i inventory.ini first-playbook.yml -K

Ansible vėl aptiks skirtumą ir įjungs automatinį Nginx paleidimą po kiekvieno perkrovimo.

Patikrinkite rezultatą:

ansible linux -i inventory.ini -a "systemctl is-enabled nginx"

Turėtumėte pamatyti:

enabled

Tai vienas pagrindinių Ansible playbook privalumų. Pakeičiate vieną failą, paleidžiate jį iš naujo, ir atnaujinami visi serveriai.

9. Playbook paleidimas konkrečiuose serveriuose

Jei užduotis reikia vykdyti tik konkrečiuose serveriuose, galite naudoti parametrą --limit. Jis apriboja užduočių vykdymą tik jūsų pasirinktais hostais.

Pavyzdžiui, playbook galite paleisti tik Ubuntu serveriuose:

ansible-playbook -i inventory.ini first-playbook.yml --limit ubuntu -K

Arba tik AlmaLinux serveriuose:

ansible-playbook -i inventory.ini first-playbook.yml --limit alma -K

Taip pat galite nurodyti atskirą serverį:

ansible-playbook -i inventory.ini first-playbook.yml --limit ubuntu1 -K

Šiuo atveju Ansible playbook vykdys tik serveryje ubuntu1.

ubuntu1 atitinka pavadinimą, kurį inventory faile nurodėte konkrečiam valdomam serveriui.

Tai patogu, kai konfigūracijos pakeitimus norite išbandyti viename serveryje, prieš pritaikydami juos kitiems savo infrastruktūros serveriams.

10. Trikčių šalinimas

10.1 YAML sintaksės klaidos

Jei gaunate šį klaidos pranešimą:

ERROR! We were unable to read either as JSON nor YAML

Tai reiškia, kad Ansible negalėjo nuskaityti playbook dėl YAML formato klaidos: neteisingų atitraukimų, trūkstamų dvitaškių ar kitų YAML formatavimo problemų. Patikrinkite playbook failą ir įsitikinkite, kad viskas teisinga.

10.2 UNREACHABLE

Jei matote:

fatal: [ubuntu1]: UNREACHABLE!

Tai reiškia, kad Ansible negali prisijungti prie valdomo serverio.

Tokiu atveju rankiniu būdu patikrinkite SSH ryšį:

Jei vykdant šią komandą prisijungti nepavyksta, patikrinkite SSH naudotojo vardą, serverio IP adresą, SSH prievadą, ugniasienės nustatymus ir autentifikacijos metodą.

Ryšį taip pat galite patikrinti paleisdami šią komandą:

ansible all -i inventory.ini -m ping

10.3 Nepavyksta gauti sudo slaptažodžio

Jei gaunate su sudo slaptažodžiu susijusią klaidą, įsitikinkite, kad turite sudo teises.

Pabandykite paleisti playbook su šia komanda:

ansible-playbook -i inventory.ini first-playbook.yml -K

Ansible paprašys įvesti sudo slaptažodį.

Jei vis tiek neveikia, prisijunkite prie valdomo serverio ir patikrinkite sudo ten:

sudo whoami

Jei viskas gerai, komanda turėtų grąžinti:

root

Priešingu atveju jūsų naudotojas neturi sudo teisių.

10.4 No hosts matched

Kita klaida:

[WARNING]: Could not match supplied host pattern

Dažniausiai tai reiškia, kad inventory faile nerastas konkretus serveris ar grupė.

Pavyzdžiui, jei jūsų playbook yra:

hosts: linux

Įsitikinkite, kad grupė linux taip pat yra inventory.ini faile.

Visus inventory failo hostus galite parodyti šia komanda:

ansible all -i inventory.ini --list-hosts

Įsitikinkite, kad komandą vykdote kataloge, kuriame yra inventory failas.

10.5 Nepavyksta įdiegti paketo

Jei Ansible gali prisijungti prie valdomo serverio, bet nepavyksta įdiegti programų, patikrinkite, ar paketas egzistuoja jūsų valdomo serverio sistemoje.

Vykdykite šias komandas:

Ubuntu:

sudo apt update
sudo apt install nginx -y

AlmaLinux:

sudo dnf install nginx -y

11. Naudingos Ansible playbook komandos

Dirbdami su Ansible playbook dažnai naudosite šias komandas:

Komanda

Aprašymas

ansible-playbook -i inventory.ini playbook.yml

Paleisti playbook

ansible-playbook -i inventory.ini playbook.yml -K

Paleisti playbook ir paprašyti sudo slaptažodžio

ansible-playbook -i inventory.ini playbook.yml --syntax-check

Patikrinti playbook sintaksę

ansible-playbook -i inventory.ini playbook.yml --check

Imituoti playbook užduotis nepritaikant pakeitimų

ansible-playbook -i inventory.ini playbook.yml --list-hosts

Parodyti tikslinius serverius

ansible-playbook -i inventory.ini playbook.yml --list-tasks

Parodyti playbook užduotis

ansible-playbook -i inventory.ini playbook.yml --limit ubuntu

Vykdyti tik konkrečioje grupėje (šiame pavyzdyje Ubuntu grupėje)

ansible-playbook -i inventory.ini playbook.yml -v

Rodyti išsamesnę vykdymo informaciją

12. Išvada

Šioje pamokoje išmokome tinkamai kurti Ansible playbook, tikrinti jų sintaksę, vykdyti užduotis keliuose valdomuose serveriuose, šalinti triktis ir keisti esamus playbook. Šiame pavyzdyje diegėme Nginx, tačiau lygiai taip pat galite automatizuoti Apache, MariaDB, Docker, PHP, ugniasienės ir daugelio kitų paslaugų diegimą bei konfigūravimą.

Daugiau informacijos rasite oficialioje Ansible Playbooks dokumentacijoje.

Ar gavote atsakymą į savo klausimą?