030 Create custom facts
Extending example 020 Get inventory aliases from notes.
Use case
Create custom facts to provide a dictionary of iocage datasets lists. Use the filter vbotka.freebsd.iocage to parse them.
Tree
shell> tree .
.
├── ansible.cfg
├── iocage.ini
├── pb-iocage.yml
└── pb-test.yml
Synopsis
At two managed nodes:
iocage_02
iocage_04
In the playbook
pb-iocage.ymluse the role vbotka.freebsd.iocage to:create custom facts scripts.
In the playbook
pb-test.yml:get the custom facts
use the filter vbotka.freebsd.iocage to parse the custom facts
create the inventory group
testand compose variablesdisplay the hosts and composed variables in the group
testdisplay all groups.
Requirements
root privilege in the managed nodes
jails created in previous examples.
Notes
Jails at iocage_02
[iocage_02]# iocage list -l
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | 24ceb6f1 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | 29712c80 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | b65059d4 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | d58e1d10 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | fba6f241 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
Jails at iocage_04
[iocage_04]# iocage list -l
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | 026a1357 | off | down | jail | 15.0-RELEASE-p3 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | ff5a1f63 | off | down | jail | 15.0-RELEASE-p3 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
ansible.cfg
[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false
[connection]
pipelining = true
Inventory iocage.ini
iocage_02 ansible_host=10.1.0.73
iocage_04 ansible_host=10.1.0.29
[iocage]
iocage_02
iocage_04
[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent
Playbook pb-iocage.yml
- name: Role vbotka.freebsd.iocage
hosts: iocage
gather_facts: true
roles:
- vbotka.freebsd.iocage
Playbook output - Display versions
(env) > ansible-playbook pb-iocage.yml -i iocage.ini \
-t freebsd_iocage_debug \
-e freebsd_iocage_debug=true \
| grep version
freebsd_iocage_role_version: 1.2.0
ansible_facts.distribution_major_version: 14
ansible_facts.distribution_version: 14.2
ansible_facts.python_version: 3.11.12
freebsd_iocage_role_version: 1.2.0
ansible_facts.distribution_major_version: 15
ansible_facts.distribution_version: 15.0
ansible_facts.python_version: 3.11.14
Playbook output - Create custom fact scripts
(env) > ansible-playbook pb-iocage.yml -i iocage.ini \
-t freebsd_iocage_facts \
-e freebsd_iocage_facts=true
PLAY [Role vbotka.freebsd.iocage] **********************************************
TASK [Gathering Facts] *********************************************************
ok: [iocage_04]
ok: [iocage_02]
TASK [vbotka.freebsd.iocage : Facts: create directory /etc/ansible/facts.d] ****
ok: [iocage_04]
ok: [iocage_02]
TASK [vbotka.freebsd.iocage : Facts: copy scipts to /etc/ansible/facts.d] ******
ok: [iocage_04] => (item=iocage.fact)
ok: [iocage_02] => (item=iocage.fact)
PLAY RECAP *********************************************************************
iocage_02 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
iocage_04 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Display custom fact script
[iocage_02]# cat /etc/ansible/facts.d/iocage.fact
#!/usr/local/bin/python
import json
import os
from subprocess import Popen, PIPE
data = {}
my_env = os.environ.copy()
my_env.update({'CRYPTOGRAPHY_OPENSSL_NO_LEGACY': '1'})
cmds = {'jails': ['--long'],
'plugins': ['--plugins'],
'releases': ['--release', '--header'],
'templates': ['--template', '--long']
}
cmd = ['iocage', 'list']
for list, attrs in cmds.items():
my_cmd = cmd + attrs
p = Popen(my_cmd, stdout=PIPE, stderr=PIPE, env=my_env)
stdout, stderr = p.communicate()
data[list] = stdout.decode("utf-8")
json_formatted_str = json.dumps(data, indent=2)
print(json_formatted_str)
Playbook pb-test.yml
- name: Get custom facts
hosts: iocage
tasks:
- name: Get custom facts
ansible.builtin.setup:
filter: ansible_local
- name: Debug
ansible.builtin.debug:
var: ansible_local.iocage
- name: Debug
ansible.builtin.debug:
var: ansible_local.iocage | vbotka.freebsd.iocage
Playbook output - Display custom facts
(env) > ansible-playbook pb-test.yml -i iocage.ini
PLAY [Get custom facts] ********************************************************
TASK [Get custom facts] ********************************************************
ok: [iocage_04]
ok: [iocage_02]
TASK [Debug] *******************************************************************
ok: [iocage_02] =>
ansible_local.iocage:
jails: |-
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | 24ceb6f1 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | 29712c80 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | b65059d4 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | d58e1d10 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | fba6f241 | off | down | jail | 14.3-RELEASE-p8 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
plugins: |-
+-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | PORTAL | DOC_URL |
+=====+======+======+=======+======+=========+=====+=====+==========+========+=========+
+-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
releases: |-
14.2-RELEASE
14.3-RELEASE
templates: |-
+------+----------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+================+======+=======+==========+=================+====================+=====+==========+==========+
| None | ansible_client | off | down | template | 14.3-RELEASE-p8 | DHCP (not running) | - | - | no |
+------+----------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
ok: [iocage_04] =>
ansible_local.iocage:
jails: |-
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | 026a1357 | off | down | jail | 15.0-RELEASE-p3 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | ff5a1f63 | off | down | jail | 15.0-RELEASE-p3 | DHCP (not running) | - | ansible_client | no |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
plugins: |-
+-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | PORTAL | DOC_URL |
+=====+======+======+=======+======+=========+=====+=====+==========+========+=========+
+-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
releases: |-
14.3-RELEASE
15.0-RELEASE
templates: |-
+------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+=======================+======+=======+==========+=================+====================+=====+==========+==========+
| None | ansible_client | off | down | template | 15.0-RELEASE-p3 | DHCP (not running) | - | - | no |
+------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
| None | ansible_client_apache | off | down | template | 15.0-RELEASE-p3 | DHCP (not running) | - | - | no |
+------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
| None | ansible_client_pull | off | down | template | 15.0-RELEASE-p3 | DHCP (not running) | - | - | no |
+------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
TASK [Debug] *******************************************************************
ok: [iocage_04] =>
ansible_local.iocage | vbotka.freebsd.iocage:
jails:
026a1357:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 15.0-RELEASE-p3
state: down
template: ansible_client
type: jail
ff5a1f63:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 15.0-RELEASE-p3
state: down
template: ansible_client
type: jail
plugins: {}
releases:
- 14.3-RELEASE
- 15.0-RELEASE
templates:
ansible_client:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 15.0-RELEASE-p3
state: down
template: '-'
type: template
ansible_client_apache:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 15.0-RELEASE-p3
state: down
template: '-'
type: template
ansible_client_pull:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 15.0-RELEASE-p3
state: down
template: '-'
type: template
ok: [iocage_02] =>
ansible_local.iocage | vbotka.freebsd.iocage:
jails:
24ceb6f1:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
29712c80:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
b65059d4:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
d58e1d10:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
fba6f241:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 14.3-RELEASE-p8
state: down
template: ansible_client
type: jail
plugins: {}
releases:
- 14.2-RELEASE
- 14.3-RELEASE
templates:
ansible_client:
basejail: 'no'
boot: 'off'
ip4: '-'
ip4_dict:
ip4: []
msg: DHCP (not running)
ip6: '-'
jid: None
release: 14.3-RELEASE-p8
state: down
template: '-'
type: template
PLAY RECAP *********************************************************************
iocage_02 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
iocage_04 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0