• Jp chevron_right

      Ansible local facts on Windows nodes

      pubsub.slavino.sk / jpmens.net · Thursday, 27 October, 2022 - 22:00 · 2 minutes

    Here I am again with Ansible ’s local facts , but this time on Windows nodes, where the local facts behave differently.

    Local fact files on Unix/Linux must be named *.fact irrespective of whether they contain INI or JSON or whether they are executable programs which emit JSON, and they are searched for in a default fact_path which is typically /etc/ansible/facts.d (or /usr/local/etc/ansible/facts.d on BSD systems).

    There’s no default fact directory for Windows nodes, but we specify one with the fact_path parameter to the setup module or in an ansible.cfg file:

    [defaults]nocows=1fact_path=c:/users/r1/facts

    That directory must exist and it MUST contain PowerShell ( *.ps1 ) files which output objects which will be formatted as JSON by Ansible . Here’s an example containing a static object:

    @{username='janej'lat=48.856826lon=2.292713}

    When Ansible’s setup module runs, we obtain the following fact from the Windows node:

    "ansible_os_family":"Windows","ansible_osm":{"lat":48.856826,"lon":2.292713,"username":"janej"}

    Note that Ansible places these objects alongside other Ansible facts, whereas on Unix, if I have a JSON file /etc/ansible/facts.d/osm.fact , Ansible returns osm nested under ansible_local :

    "ansible_os_family":"Darwin","ansible_local":{"osm":{"lat":48.856826,"lon":2.292713,"username":"janej"}}

    dynamic

    On Unix/Linux *.fact files may be executable and return JSON, so I install my program as /etc/ansible/facts.d/hungry.fact

    $/etc/ansible/facts.d/hungry.fact
    {"id":4,"meal":"dinner","dish":"tikka masala"}
    

    The utility is executed during setup and the result is:

    "ansible_local":{"hungry":{"dish":"tikka masala","id":4,"meal":"dinner"},"osm":{"lat":48.856826,"lon":2.292713,"username":"janej"}}

    On Windows nodes fact files MUST be *.ps1 so I figure out^W^W google how to invoke a program from a PowerShell script and produce this masterpiece in a file called currybeer.ps1 :

    Invoke-Expression"& `"C:\Users\r1\facts\hungry.exe`"  /run /exit /SilentMode"

    Sadly, that doesn’t do what I thought it would: the PowerShell script is returning a string:

    "ansible_currybeer":"{\"id\":4,\"meal\":\"dinner\",\"dish\":\"tikka masala\"}"

    A bit more figuring out later, I add | ConvertFrom-Json to the .ps1 script, and Ansible correctly interprets its output:

    "ansible_currybeer":{"dish":"tikka masala","id":4,"meal":"dinner"},"ansible_osm":{"lat":48.856826,"lon":2.292713,"username":"janej"},

    I can now use these facts like any others:

    -hosts:wingather_facts:truetasks:-debug:msg="{{ ansible_currybeer.dish }} for {{ ansible_currybeer.meal }}"

    and look forward to this evening:

    TASK [debug] *************************
    ok: [192.168.1.163] => {
        "msg": "tikka masala for dinner"
    }
    

    I don’t know why Ansible nests local facts differently on Windows nodes, and I don’t see an advantage in doing so.

    And if you need inspiration, we’re collecting ideas for using local facts


    Značky: #Network

    • wifi_tethering open_in_new

      This post is public

      jpmens.net /2022/10/28/ansible-local-facts-on-windows/