Davide, díky za další díl. Opět trochu (doufám) konstruktivní reflexe:
> bloky jsou definovány odsazením, sekce začíná znakem ‚-‘
Tak to v Ansible může být použito, ale jako popis Yaml by to pro někoho mohlo být trochu matoucí. Odsazení se používá pro mapovací typ (aka hashtable, asociativní pole) a znak "-" se v YAML používá tak, jak ho lidi přirozeně používají - jako odrážka, tj. znak uvozující položku seznamu. Např.
tasks:
- name: zajistuji instalaci httpd a git
yum: pkg={{ item }} state=installed
with_items:
- httpd
tak je vlastně (pseudo-python):
{tasks: [ {
name: ...,
yum: ...
with_items: [ httpd, ...]
}]}
Jinak jestli jsem dobře pochopil, Ansible je teda stejně jako Chef orientované "imperativně" - na vykonávání příkazů, které mají dostat server do nějakého stavu. U takového přístupu je pak problém v tom, že se musí explicitně myslet na idempotenci (co když skript spustím podruhé na už nastaveném serveru?) Jak to má Ansible ošéfované? Pokud např. v nějakém kroku chci odněkud někam zkopírovat soubor, jak zjišťuje, jestli už tam je a má správný obsah?
A jak je to s restartováním služeb? Salt umí detekovat, jestli se konfgurák služby změnil a jenom pokud ano, tak službu zrestartuje. Jak je to u Ansible?
Díky za případné odpovědi.
Nevím, jestli chápu správně dotaz. Když spustíš podruhé konfiguraci na stejný server, vypíše ti to které položky byly ok a které byly změněny. Plus je možné použít u ansible-playbook parametry --diff pro zobrazení změn a --check pro kontrolní běh, kdy se akce nevykonávají ale jen se ukazuje co by se změnilo a co je už nastaveno.
Mirku díky za otázky, rád doplním článek:
Ansible je více podobné Chef v tom, že se jde shora dolů jedna položka za druhou, nemá tam závislosti jako Puppet. Idempotenci zajištují jednotlivé moduly přímo, např. copy a template si nejprve ověří jestli tam ten soubor už není v té verzi, kterou mají nahrát. Takjtéž service modul, když má nastartovat/zastavit službu tak to nedělá pokud už služby běží/neběží apod.
Při druhém spuštění scénáře pak Ansible vypíše počet nezměněných věcí, změněných, ,chyb a nedostupných serverů. Idempotence ale není všude, i když je to logické - například u modulů command a shell, které přímo pouští příkazy to zajistit nejde. Ale v modulech kde to jde je to implentováno. Dobře napsaný scénář můžeš pouštět cronem a funguje to stejně jako u Puppetu s agenty na serverech.
V modulech command a shell je navíc možnost nastavit creates a nebo removes - pokud příkaz něco vytváří, nebo naopak maže tak při použití těchto parametrů už podruhé nepoběží.
Pro složitější rozhodování je možnost registrovat výsledek akce do proměnné a tu použít dále, například mám takto nastavování uživatelů pure-ftpd pomocí pure-db:
- name: Check if user already exists
shell: pure-pw show {{ name }} >/dev/null 2>/dev/null && echo "found" || echo "notfound"
register: found
- name: User do not exists, calling useradd
shell: (echo {{ password }}; echo {{ password }}) | pure-pw useradd {{ name }} -u {{ uid }} -g {{ gid }} -d {{ dir }} -m
when: found.stdout == "notfound"
Nejprve si pomocí shellu zjistím jestli uživatel už existuje a pak když ne, tak ho založím. Takhle můžeš zajistit idempotenci i u věcí co nemají přímo napsané moduly, nebo je to komplikovanější případ.
Když potřebuješ restartovat službu po změně konfigurace, tak použiješ notify, viz. příklad v "Scénáře a hry". Po nahrání konfigurace apache se provede notify: restart apache. Resp. provede se to na konci skupiny úkolů, takže je možné volat notify několikrát, ale provede se jen jednou. Ale musíš to exlicitně zmínit, neudělá se to "samo".
Ještě mě napadlo, pod minulým článkem ses myslím ptal, jestli je možno definovat hosty i jinak než po skupinách.
Dá se, místo souboru hosts použít tzv. inventory script. Zjednodušeně řečeno, když si tam dáš skript, který ti z databáze vytáhne seznam serverů a skupin a dá ti to v json, tak můžeš mít hosty definovány v databázi. Nebo v LDAP, nebo kdekoliv, podle toho kde máš uložená data o serverech (je možné předat i proměnné, např. IP adresu, lokaci, ...).
Více o inventory skriptech najdeš na:
http://www.ansibleworks.com/docs/api.html#external-inventory-scripts
a tady je praktická ukázka třeba jak to udělat s sqlite:
http://jpmens.net/2013/06/18/adapting-inventory-for-ansible/