Ansible: role a postupný deploy

David Karban 12. 9. 2013

Z předchozích dílů našeho seriálu o Ansible víme, jak je možné provádět ad-hoc příkazy a nebo jak vytvořit scénáře pro složitější konfiguraci. Dnes si ukážeme, jak pomocí rolí provést dekompozici celého nastavení a konfiguraci Ansible rozdělit na menší opakovaně použitelné logické částí.

Teorie

Role jsou v Ansible od verze 1.2. Jejich smyslem je popsat ucelenou jednotku konfigurace tak, aby byla opakovatelně použitelná. Podobají se například třídám z Puppetu (jen je nelze vnořovat). Standardně jsou uloženy v adresáři /etc/ansible/roles/. Adresářová struktura obsahuje:

  files/
  handlers/
  tasks/
  templates/
  vars/

Roli přiřadíte do scénáře v main.yml:

---
- hosts: webservers
  roles:
    - common
    - apache
    - {role: apache_vhost, vhost_domain=simplewebpage.com, vhost_dir=/var/www/simplewebpage.com/www}

Common a apache jsou zavolány bez parametrů. Apache_vhost je parametrizována, vytvoří apache vhost pro simplewebpage.com. Při přehrání Ansible hledá soubory tasks/main.yml, handlers/main.yml, vars/main.yml, pokud je najde, přidá je do hry. Moduly copy a script automaticky hledají soubory ve files/ a modul template v templates/, není potřeba uvádět cesty. Pojďme si to ukázat v praxi.

Praktická ukázka, role pro instalaci utilit

Při své práci mám pod správou několik instalací různých zákazníků. Abych si ulehčil převzetí správy u nového zákazníka, vytvořil jsem si roli common, s pomocí které nainstaluji na server základní utility, ssh klíč (i když bývá na server nahrán zákazníkem, toto mi umožní jej budoucnu snadno kdykoliv hromadně změnit) a zapnu si zobrazování syntaxe ve vim u root uživatele. V main.yml v tasks adresáři najdeme:

# /etc/ansible/roles/common/tasks/main.yml
---
- name: nahravam ssh klic
  authorized_key: user=root state=present key={{ item }}
  with_file:
    - public-keys/david.karban.pub

- name: ladim .vimrc
  lineinfile: dest=/root/.vimrc regexp=^syntax line="syntax on" create=yes

- name:  instaluji utility na RHEL systemy
  yum: name={{ item }} state=present
  with_items: common_packages
  when: ansible_os_family == "RedHat"

- name:  instaluji utility na Debian systemy
  apt: name={{ item }} state=present
  with_items: common_packages
  when: ansible_os_family == "Debian"

- name: instaluji dalsi utility na Debian systemy
  apt: name={{ item }} state=present
  with_items: common_debian_packages
  when: ansible_os_family == "Debian"

Je vidět, že jde o běžnou hru s jedním rozdílem, vše v main.yml je automaticky bráno jako task. Ve hře jsou dodány další modifikátory kroků, které jsem zatím nezmínil. With_files nahraje data ze souboru,v tomto případě můj veřejný SSH klíč. Zde pozor, jak jsem psal, že u role se automaticky berou relativní cesty, tak to skutečně platí jen pro moduly copy, script a template, v tomto případě se bere cesta relativně k playbooku (tedy k  /etc/ansible).

Další modul, lineinfile, umí změnit v cílovém souboru konkrétní řádek na základě regexp. výrazu, zde jej používám místo celého konfiguračního souboru, abych nepřemazal jiné zákaznické nastavení. V další části instaluji balíky, které obvykle používám, když je potřeba. Jejich seznam jsem uložil do proměnných, které jsou nadefinovány v adresáři vars, viz níže. Ansible nemá univerzální modul pro package, proto instaluji utility 2×, vždy s filtrem na druh distribuce, viz. sekce when. Fakt ansible_os_family obsahuje rodinu distribucí, tj. Debian platí i pro Ubuntu, Red Hat zase i pro CentOS a Scientific Linux. Samotná distribuce je ve faktu  ansible_distribution.

Pokračujme k nadefinovaným proměnným.

# /etc/ansible/roles/common/vars/main.yml
---
common_packages:
  - links
  - mc
  - strace

common_debian_packages:
  - htop

Ansible nemá podporu pro lokální proměnné, proměnné nadefinované v rámci rolí jsou na stejné úrovni, jako například proměnné nadefinované ve scénáři v sekci vars. Aby se daly role jednoduše opakovaně použít, doporučuje se mít u proměnných prefix jejich názvu, aby byly unikátní. Proto oba seznamy balíčků začínají common_.

Postupné nasazení aplikace a práce s monitoringem

S dobře popsanými rolemi je instalace nového serveru velmi jednoduchá, prostě přidáme jeho hostname do hosts souboru do vhodné skupiny. Ale co v případě, že provádíme deploy aplikace, jak nám Ansible pomůže zde? Pomocí delegace a postupného zpracování scénáře. Standardně se scénáře aplikují na skupiny serverů paralelně, pomocí klíčového slova serial si vynutíme jejich postupné zpracování:

---
- hosts: webservers
  serial: 1
  roles:
    - common
    - apache
    - {role: apache_vhost, vhost_domain=simplwebpage.com, vhost_dir=/var/www/simplewebpage.com/www}

Hodnota u atributu serial určuje kolik serverů ze skupiny najednou se má přehrávat. V tomto případě jde jeden po druhém. Abychom odstínili návštěvníky stránek od serverů, na kterých se zrvona provádí deploy, deaktivujeme jej na tu dobu z load balanceru (v tomto případě z haproxy) a z nagiosu, použijeme  delegate_to:

- hosts: webservers
  serial: 1

  # Ukoly ke spusteni pred provedením update aplikace
  pre_tasks:
  - name: vypinam nagios alert pro web na serveru
    nagios: action=disable_alerts host={{ ansible_hostname }} services=webserver
    delegate_to: "{{ item }}"
    with_items: groups.monitoring

  - name: deaktivuji server v haproxy
    shell: echo "disable server myapplb/{{ ansible_hostname }}" | socat stdio /var/lib/haproxy/stats
    delegate_to: "{{ item }}"
    with_items: groups.lbservers
  roles:
    .
    .
    .

  # Ukoly po provedeni update aplikace
  post_tasks:
  - name: Aktivuji server v haproxy
    shell: echo "enable server myapplb/{{ ansible_hostname }}" | socat stdio /var/lib/haproxy/stats
    delegate_to: "{{ item }}"
    with_items: groups.lbservers

  - name: zapinam nagios alerty pro web na serveru
    nagios: action=enable_alerts host={{ ansible_hostname }} services=webserver
    delegate_to: "{{ item }}"
    with_items: groups.monitoring

Úkoly vypnutí/zapnutí nagiosu a deaktivace/aktivace serveru v haproxy provádějí na všech monitoring serverech (definováni v hosts souboru jako skupina monitoring) a na všech load balancerech (skupina lbservers). Pre_tasks a post_tasks  se provádějí na začátku, resp. konci scénáře před hlavní sekci tasks.

Protože není potřeba při každé změně konfigurace na serverech provádět i deploy, je v tomhle případě výhodné mít jej v samostatném scénáří. Ukázka takového skriptu je na GitHubu Ansible. Ukázku nastavení skupiny serverů, vč. haproxy a monitoringu najdete tamtéž.

widgety

Závěrem, aneb mé důvody pro Ansible

Vždy, když to lze, snažím se konfiguraci přenést do her a scénářů, abych ji mohl příště aplikovat jen dodáním role k serveru. Ptáte se jak je to odlišné od Puppet a Chef? Je to flexibilnější. Při své práci mám pod správou více druhů instalací u různých zákazníků. V Ansible pro ně mám jak individuální konfiguraci, tak specifické konfigurace jen pro ně. Proto jsem si vytvořil adresář customers, co zákazník to podadresář. Role, které mají všichni zákazníci stejně (základní utility, nastavení httpd.conf, nastavení ntp) mám v /etc/ansible/roles/  a do customers je jen symlinkuji.

Když takto přebírám správu serverů u nového zákazníka, tak příprava prostředí je jen dodání adres do hosts souborů. U zákazníka nemám nainstalován žádný dodatečný software, který by mu zabíral systémové prostředky. Ačkoliv bych mohl dosáhnout dost podobného s Puppetem, musel bych mít všechny manifesty v jednom stromu konfigurace a musel bych mít všude nainstalován Puppet agent. Pro mě zbytečně komplikované.

Našli jste v článku chybu?
Vitalia.cz: 5 důvodů, proč jet na výlov rybníka

5 důvodů, proč jet na výlov rybníka

DigiZone.cz: Další programatické formáty

Další programatické formáty

DigiZone.cz: Světový pohár v přímém přenosu na ČT

Světový pohár v přímém přenosu na ČT

DigiZone.cz: Digi Slovakia zařazuje stanice SPI

Digi Slovakia zařazuje stanice SPI

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

Lupa.cz: Patička e-mailu závazná jako vlastnoruční podpis?

Patička e-mailu závazná jako vlastnoruční podpis?

Měšec.cz: „Ukradli“ jsme peníze z bezkontaktních karet

„Ukradli“ jsme peníze z bezkontaktních karet

Vitalia.cz: Tradiční čínská medicína a rakovina

Tradiční čínská medicína a rakovina

Root.cz: Hořící telefon Samsung Note 7 zapálil auto

Hořící telefon Samsung Note 7 zapálil auto

DigiZone.cz: Technisat připravuje trojici DAB

Technisat připravuje trojici DAB

DigiZone.cz: Sat novinky: NASA Ultra HD (4K)

Sat novinky: NASA Ultra HD (4K)

Vitalia.cz: Tesco nabízí desítky tun jídla zdarma

Tesco nabízí desítky tun jídla zdarma

Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

Blíží se konec Wi-Fi sítí bez hesla?

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019

Lupa.cz: Jak levné procesory změnily svět?

Jak levné procesory změnily svět?

DigiZone.cz: Nova opět stahuje „milionáře“

Nova opět stahuje „milionáře“

Vitalia.cz: Jak Ondra o astma přišel

Jak Ondra o astma přišel

Root.cz: Podívejte se na shořelé Samsung Note 7

Podívejte se na shořelé Samsung Note 7

Podnikatel.cz: Letáky? Lidi zuří, ale ony stále fungují

Letáky? Lidi zuří, ale ony stále fungují

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...