014 Inventory cache

Extending example 010 Clone basejails and create inventory.

Use case

Enable and test inventory cache.

Tree

shell> tree .
.
├── ansible.cfg
├── iocage.yml
├── pb-cache-dump.yml
└── pb-vars-ip4.yml

Synopsis

At a managed node:

Requirements

ansible.cfg

[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false

[connection]
pipelining = true

Inventory iocage.yml

Enable cache

plugin: vbotka.freebsd.iocage
host: 10.1.0.73
user: admin
env:
  CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
get_properties: False
cache: True
cache_plugin: ansible.builtin.jsonfile
cache_connection: /var/tmp/inventory_cache
cache_timeout: 3600
cache_prefix: iocage_
strict: True
compose:
  ansible_host: iocage_ip4
  release: iocage_release | split('-') | first
  release_major: iocage_release | split('-') | first | split('.') | first
  release_minor: iocage_release | split('-') | first | split('.') | last
groups:
    test: inventory_hostname.startswith('test')
keyed_groups:
  - prefix: distro
    key: iocage_release
  - prefix: state
    key: iocage_state

Hint

If you do not configure cache_plugin, Ansible falls back to caching inventory with the fact cache plugin you configured. For example,

shell> grep fact_caching ansible.cfg
fact_caching = ansible.builtin.jsonfile
fact_caching_connection = /var/tmp/ansible_cache
fact_caching_timeout = 3600
fact_caching_prefix = ''

Playbook pb-vars-ip4.yml

pb-vars-ip4.yml
- hosts: all

  tasks:

    - debug:
        var: iocage_ip4

Playbook output - Clear cache

In this particular case, it takes 4s to create the dynamic inventory and construct the variables after the cache was cleared (flushed).

(env) > date +%r; \
        ANSIBLE_STDOUT_CALLBACK=community.general.timestamp \
        ansible-playbook pb-vars-ip4.yml -i iocage.yml -l test_113 --flush-cache
23:03:34

PLAY [all] ************************************************************ 23:03:37

TASK [debug] ********************************************************** 23:03:37
ok: [test_113] => 
    iocage_ip4: 10.1.0.113

PLAY RECAP ************************************************************ 23:03:37
test_113                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Playbook output - Cache enabled

If the cache is enabled, the inventory and variables are provided by the cache immediately

(env) > date +%r; \
        ANSIBLE_STDOUT_CALLBACK=community.general.timestamp \
        ansible-playbook pb-vars-ip4.yml -i iocage.yml -l test_113
23:03:37

PLAY [all] ************************************************************ 23:03:38

TASK [debug] ********************************************************** 23:03:38
ok: [test_113] => 
    iocage_ip4: 10.1.0.113

PLAY RECAP ************************************************************ 23:03:38
test_113                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Hint

Use the option –flush-cache to clear the cache.

Cache

Look at the cache. For example,

shell> cat /var/tmp/inventory_cache/iocage_vbotka.freebsd.iocage_a5393s_956f5
{
    "_meta": {
        "hostvars": {
            "ansible_client": {
                "iocage_basejail": "yes",
                "iocage_boot": "off",
                "iocage_ip4": "10.1.0.199",
                "iocage_ip4_dict": {
                    "ip4": [
                        {
                            "ifc": "em0",
                            "ip": "10.1.0.199",
                            "mask": "24"
                        }
                    ],
                    "msg": ""
                },
                "iocage_ip6": "-",
                "iocage_jid": "None",
                "iocage_release": "14.2-RELEASE-p3",
                "iocage_state": "down",
                "iocage_template": "-",
                "iocage_type": "jail"
            },
            "test_111": {
                "iocage_basejail": "yes",
                "iocage_boot": "off",
                "iocage_ip4": "10.1.0.111",
                "iocage_ip4_dict": {
                    "ip4": [
                        {
                            "ifc": "em0",
                            "ip": "10.1.0.111",
                            "mask": "24"
                        }
                    ],
                    "msg": ""
                },
                "iocage_ip6": "-",
                "iocage_jid": "None",
                "iocage_release": "14.2-RELEASE-p3",
                "iocage_state": "down",
                "iocage_template": "ansible_client",
                "iocage_type": "jail"
            },
            "test_112": {
                "iocage_basejail": "yes",
                "iocage_boot": "off",
                "iocage_ip4": "10.1.0.112",
                "iocage_ip4_dict": {
                    "ip4": [
                        {
                            "ifc": "em0",
                            "ip": "10.1.0.112",
                            "mask": "24"
                        }
                    ],
                    "msg": ""
                },
                "iocage_ip6": "-",
                "iocage_jid": "None",
                "iocage_release": "14.2-RELEASE-p3",
                "iocage_state": "down",
                "iocage_template": "ansible_client",
                "iocage_type": "jail"
            },
            "test_113": {
                "iocage_basejail": "yes",
                "iocage_boot": "off",
                "iocage_ip4": "10.1.0.113",
                "iocage_ip4_dict": {
                    "ip4": [
                        {
                            "ifc": "em0",
                            "ip": "10.1.0.113",
                            "mask": "24"
                        }
                    ],
                    "msg": ""
                },
                "iocage_ip6": "-",
                "iocage_jid": "None",
                "iocage_release": "14.2-RELEASE-p3",
                "iocage_state": "down",
                "iocage_template": "ansible_client",
                "iocage_type": "jail"
            }
        }
    }
}

The cache format has changed since Ansible 2.19. Use the below playbook to read the cache

pb-cache-dump.yml
- name: Dump cache.
  hosts: localhost

  vars:

    cache: "{{ lookup('file', cache_file) | from_yaml }}"

  tasks:

    - assert:
        that: cache_file is defined
        fail_msg: "[ERR] variable cache_file is not defined."
        quiet: true

    - debug:
        var: cache.__payload__ | from_yaml

For example,

shell> ansible-playbook pb-cache-dump.yml \
       -e cache_file=/var/tmp/inventory_cache/iocage_04_s1_vbotka.freebsd.iocage_kfb2392
PLAY [Dump cache.] *************************************************************

TASK [assert] ******************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] =>
    cache.__payload__ | from_yaml:
        _meta:
            hostvars:
                test_4:
                    iocage_basejail: 'no'
                    iocage_boot: 'off'
                    iocage_hooks:
                    - '-'
                    iocage_ip4: '-'
                    iocage_ip4_dict:
                        ip4: []
                        msg: '-'
                    iocage_ip6: '-'
                    iocage_jid: None
                    iocage_properties:
                        CONFIG_VERSION: '33'
    ...