Ha valamilyen kódra van szüksége a játékkönyvéhez, általában a következő lehetőségek közül választhat:
- Az Ansible modulja
- Egy jinja2 programozási nyelv próbál lenni a sablonhoz, és próbál program lenni
- Egy külső program, amelyet a
command
modullal futtat, és a kimenetét adatként használja (register: foobar
;foobar.stdout|from_json
). - Ugyanez a program rejtve van a
lookup
beépülő modulban a jinja2 számára.
Egyik sem ideális, ezért itt van egy másik (nem tökéletes, de bizonyos helyzetekben hasznos) módszer az Ansible kód írására. Ezt „egyedi tényeknek” hívják.
Egyedi tények
Ha van egy setup
modul, amely adatokat gyűjt a játékhoz (implicit vagy explicit módon a setup
modul feladatként történő meghívásával), további információkat gyűjthet.
Kétféle egyéni tény létezik: adat és kód. Az adatok csak egy fájlból kerülnek kiolvasásra, a kód végrehajtásra kerül, és a kimenet adatként kerül elfogadásra.
Mindkét tény a /etc/ansible/facts.d/
könyvtárban él a célgépen (nem vezérlőn!), mindkettő .fact
kiterjesztéssel rendelkezik (példa: /etc/ansible/facts.d/something.fact
). Ha ennek a fájlnak van végrehajtási engedélye, akkor ez egy kód, ha nincs végrehajtási engedélye, akkor adat. Mind a kód kimenete, mind az adattény tartalmának formátuma ugyanaz: a json. A tény összegyűjtése után a ténynévvel (a fájlnév a '.fact' előtt) kulcs alatt kerül tárolásra a ansible_local
-ban.
Példa
Adjunk hozzá egyéni tényeket. Az első tény azt mondja, hogy a foo
a bar
, a dinamikus tény pedig azt mondja, hogy a foobar
a foo
és bar
listája. Példánk szemléletesebbé tétele érdekében bemutatok egy színdarabot, amely konfigurálja ezeket a tényeket.
- hosts: all become: true tasks: - name: Create fact directory file: path: /etc/ansible/facts.d/ state: directory - name: Create a static custom fact foo copy: content: '"bar"' dest: /etc/ansible/facts.d/foo.fact - name: Create a dynamic custom fact foobar copy: dest: /etc/ansible/facts.d/foobar.fact mode: 0775 content: | #!/usr/bin/python3 import json def render_data(data): return json.dumps(data) arbitrary_data = {} arbitrary_data["foobar"] = [] arbitrary_data["foobar"].append("foo") if True: arbitrary_data["foobar"].append("bar") print(render_data(arbitrary_data["foobar"]))
Szándékosan túlterveztem foobar.fact
annak szemléltetésére, hogy a tények valós program is lehetnek. Függvények, egységtesztek stb. Bármilyen nyelven lehetnek. Aligha tudom elképzelni, hogy valaki fordítónyelveket használjon erre, de ez is működni fog, csak helyezze a bináris fájlt megfelelő helyre +x jelzővel.
Miután beállította az egyéni tényeket, minden ténygyűjtés változást eredményez. Egy egyszerű debug: var=ansible_local
kimenet így néz ki:
ok: [example] => { "ansible_local": { "foo": "bar", "foobar": [ "foo", "bar" ] } }
Hibák
Ha elrontja a programot vagy az engedélyeket, valami ilyesmit fog kapni:
ok: [example] => { "ansible_local": { "foo": { "foo": "bar" }, "foobar": "error loading fact - please check content" } }
Valójában az összegyűjtési hiba semmilyen módon nem töri meg a programot. Ha a programod csak segfaulttal hal meg, vagy hibakóddal lép ki, akkor a tény tartalma vagy „hiba…”, vagy csak egy üres szótár (pl. ha elgépelsz egy shebang sort).
Vita
Az egyéni tények fő előnye, hogy a telepítési folyamatban hajtják végre, anélkül, hogy foglalkoznának az Ansible bonyolultságával. A kód teszteléséhez nem kell végrehajtania az ansible-t. Ezenkívül (és ez nagy előny a command
-hoz képest) nincs szükség feldolgozásra az adatok stdoutból való kinyeréséhez.
A fő hátrány az, hogy a tényekben nem bukhatsz el, még akkor sem, ha akarod. Ha a tényfájl létezik, akkor lesz tény: üres szótár, hibaüzenet vagy egy megfelelő érték, amelyet visszaadott, de legalább lesz valami.
A kereséshez képest még egy enyhe előny a sebesség. Ott nincs lehetséges bootstrap, így 10 tény sokkal gyorsabban hajtódik végre, mint tíz feladat.
Ezenkívül a fő különbség a kereséssel az, hogy a tények összegyűjtése a távoli gépen történik, és a keresés helyileg, a vezérlő gazdagépén történik.
Végül az egyéni tények használatánál az a fő szempont, hogy tudjak megfelelő programot írni az egyéni tényekre. Ennek a programnak egységtesztjei lesznek, ezért nagyban ellensúlyozza a hibakeresési időt. Nagyon könnyű az egyéni tényeket manuálisan futtatni egy gazdagépen, és ez segíthet a hibakeresésben is.