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.