013 Tags and custom groups
Extending example 010 Clone basejails and create inventory.
Use case
Use the property notes to create tags:
Add the property
notes: "vmm={{ inventory_hostname }}"
In the inventory plugin:
compose the variable
iocage_tagscreate groups
vmm_*from the attributeiocage_tags.vmm
Tree
shell> tree .
.
├── ansible.cfg
├── hosts
│ ├── 02_iocage.yml
│ └── 04_iocage.yml
├── host_vars
│ ├── iocage_02
│ │ └── iocage.yml
│ └── iocage_04
│ └── iocage.yml
├── iocage.ini
├── pb-all.yml
├── pb-ansible-client.yml
├── pb-iocage-base.yml
├── pb-iocage-clone.yml
└── pb-test.yml
Synopsis
At two managed nodes:
iocage_02
iocage_04
In the playbook
pb-iocage-base.yml, use the module vbotka.freebsd.iocage to:create basejail
ansible_client
In the playbook
pb-iocage-clone.yml, use the module vbotka.freebsd.iocage to:clone 3 jails from the basejail
ansible_client
In the playbooks:
pb-all.yml
pb-ansible-client.yml
pb-test.yml
use the inventory plugin vbotka.freebsd.iocage to:
create the inventory groups and compose variables
create the dictionary
iocage_tagsfromiocage_properties.notesdisplay hosts, composed variables, and groups
comment on hosts potentially overriding each other silently.
Requirements
root privilege in the managed nodes
activated binary iocage
fetched releases.
ansible.cfg
[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false
host_key_checking = 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
Inventory hosts
Enable get_properties: true to create the dictionary iocage_properties. Then, the dictionary
iocage_tags can be created from iocage_properties.notes
plugin: vbotka.freebsd.iocage
host: 10.1.0.73
user: admin
env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
get_properties: True
compose:
ansible_host: iocage_ip4
release: iocage_release | split('-') | first
iocage_tags: dict(iocage_properties.notes | regex_findall('(\w+)=([\w\-]+)'))
groups:
test_02: inventory_hostname.startswith('test')
keyed_groups:
- prefix: distro_02
key: iocage_release
- prefix: state_02
key: iocage_state
- prefix: vmm
key: iocage_tags.vmm
plugin: vbotka.freebsd.iocage
host: 10.1.0.29
user: admin
get_properties: True
compose:
ansible_host: iocage_ip4
release: iocage_release | split('-') | first
iocage_tags: dict(iocage_properties.notes | regex_findall('(\w+)=([\w\-]+)'))
groups:
test_04: inventory_hostname.startswith('test')
keyed_groups:
- prefix: distro_04
key: iocage_release
- prefix: state_04
key: iocage_state
- prefix: vmm
key: iocage_tags.vmm
Note
The structure of the notes is up to you. If you change it, fit the declaration of
iocage_tags in the inventory.
host_vars
properties:
notes: "vmm={{ inventory_hostname }}"
basejails:
- name: ansible_client
release: 14.3-RELEASE
properties:
ip4_addr: 'em0|10.1.0.199/24'
clones:
- name: test_111
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.111/24'
- name: test_112
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.112/24'
- name: test_113
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.113/24'
iocage_env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
properties:
vnet: 'on'
defaultrouter: 10.1.0.10
notes: "vmm={{ inventory_hostname }}"
basejails:
- name: ansible_client
release: 15.0-RELEASE
properties:
ip4_addr: 'vnet0|10.1.0.198/24'
clones:
- name: test_131
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.131/24'
- name: test_132
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.132/24'
- name: test_133
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.133/24'
Playbook pb-iocage-base.yml
- hosts: iocage
environment: "{{ iocage_env | d({}) }}"
tasks:
- name: Create basejail
register: out
vbotka.freebsd.iocage:
state: basejail
name: "{{ item.name }}"
release: "{{ item.release }}"
properties: "{{ [properties, item.properties] | combine }}"
loop: "{{ basejails }}"
loop_control:
label: "{{ item.name }} {{ item.release }}"
- name: Debug
when: debug | d(false) | bool
ansible.builtin.debug:
var: out
- name: Display lists of bases, plugins, templates, and jails.
ansible.builtin.debug:
msg: |-
releases: {{ ansible_facts.iocage_releases }}
plugins: {{ ansible_facts.iocage_plugins.keys() | list }}
templates: {{ ansible_facts.iocage_templates.keys() | list }}
jails: {{ ansible_facts.iocage_jails.keys() | list }}
Playbook output - Create basejails
(env) > ansible-playbook pb-iocage-base.yml -i iocage.ini
PLAY [iocage] ******************************************************************
TASK [Create basejail] *********************************************************
changed: [iocage_04] => (item=ansible_client 15.0-RELEASE)
changed: [iocage_02] => (item=ansible_client 14.3-RELEASE)
TASK [Display lists of bases, plugins, templates, and jails.] ******************
ok: [iocage_02] =>
msg: |-
releases: ['14.2-RELEASE', '14.3-RELEASE']
plugins: []
templates: []
jails: ['ansible_client']
ok: [iocage_04] =>
msg: |-
releases: ['14.3-RELEASE', '15.0-RELEASE']
plugins: []
templates: ['ansible_client_apache', 'ansible_client_pull']
jails: ['ansible_client']
PLAY RECAP *********************************************************************
iocage_02 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
iocage_04 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Playbook pb-iocage-clone.yml
- hosts: iocage
environment: "{{ iocage_env | d({}) }}"
tasks:
- name: Clone from basejail
register: out
vbotka.freebsd.iocage:
state: cloned
clone_from: "{{ item.clone_from }}"
name: "{{ item.name }}"
properties: "{{ [properties, item.properties] | combine }}"
loop: "{{ clones }}"
loop_control:
label: "{{ item.name }} {{ item.clone_from }}"
- name: Debug
when: debug | d(false) | bool
ansible.builtin.debug:
var: out
- name: Display lists of bases, plugins, templates, and jails.
ansible.builtin.debug:
msg: |-
releases: {{ ansible_facts.iocage_releases }}
plugins: {{ ansible_facts.iocage_plugins.keys() | list }}
templates: {{ ansible_facts.iocage_templates.keys() | list }}
jails: {{ ansible_facts.iocage_jails.keys() | list }}
Playbook output - Clone jails
(env) > ansible-playbook pb-iocage-clone.yml -i iocage.ini
PLAY [iocage] ******************************************************************
TASK [Clone from basejail] *****************************************************
changed: [iocage_04] => (item=test_131 ansible_client)
changed: [iocage_04] => (item=test_132 ansible_client)
changed: [iocage_04] => (item=test_133 ansible_client)
changed: [iocage_02] => (item=test_111 ansible_client)
changed: [iocage_02] => (item=test_112 ansible_client)
changed: [iocage_02] => (item=test_113 ansible_client)
TASK [Display lists of bases, plugins, templates, and jails.] ******************
ok: [iocage_04] =>
msg: |-
releases: ['14.3-RELEASE', '15.0-RELEASE']
plugins: []
templates: ['ansible_client_apache', 'ansible_client_pull']
jails: ['ansible_client', 'test_131', 'test_132', 'test_133']
ok: [iocage_02] =>
msg: |-
releases: ['14.2-RELEASE', '14.3-RELEASE']
plugins: []
templates: []
jails: ['ansible_client', 'test_111', 'test_112', 'test_113']
PLAY RECAP *********************************************************************
iocage_02 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
iocage_04 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Playbook pb-all.yml
- hosts: all
tasks:
- debug:
msg: |
inventory_hostname: {{ inventory_hostname }}
ansible_host: {{ ansible_host }}
release: {{ release }}
iocage_tags: {{ iocage_tags }}
- debug:
msg: |
groups:
{{ groups | to_yaml(indent=2) | indent(2) }}
run_once: true
Playbook output - Display variables and groups
(env) > ansible-playbook pb-all.yml -i hosts
PLAY [all] *********************************************************************
TASK [debug] *******************************************************************
ok: [ansible_client] =>
msg: |-
inventory_hostname: ansible_client
ansible_host: 10.1.0.198
release: 15.0
iocage_tags: {'vmm': 'iocage_04'}
ok: [test_111] =>
msg: |-
inventory_hostname: test_111
ansible_host: 10.1.0.111
release: 14.3
iocage_tags: {'vmm': 'iocage_02'}
ok: [test_112] =>
msg: |-
inventory_hostname: test_112
ansible_host: 10.1.0.112
release: 14.3
iocage_tags: {'vmm': 'iocage_02'}
ok: [test_113] =>
msg: |-
inventory_hostname: test_113
ansible_host: 10.1.0.113
release: 14.3
iocage_tags: {'vmm': 'iocage_02'}
ok: [test_131] =>
msg: |-
inventory_hostname: test_131
ansible_host: 10.1.0.131
release: 15.0
iocage_tags: {'vmm': 'iocage_04'}
ok: [test_132] =>
msg: |-
inventory_hostname: test_132
ansible_host: 10.1.0.132
release: 15.0
iocage_tags: {'vmm': 'iocage_04'}
ok: [test_133] =>
msg: |-
inventory_hostname: test_133
ansible_host: 10.1.0.133
release: 15.0
iocage_tags: {'vmm': 'iocage_04'}
TASK [debug] *******************************************************************
ok: [ansible_client] =>
msg: |-
groups:
all: [ansible_client, test_111, test_112, test_113, test_131, test_132, test_133]
distro_02_14_3_RELEASE_p8: [ansible_client, test_111, test_112, test_113]
distro_04_15_0_RELEASE_p3: [ansible_client, test_131, test_132, test_133]
state_02_down: [ansible_client, test_111, test_112, test_113]
state_04_down: [ansible_client, test_131, test_132, test_133]
test_02: [test_111, test_112, test_113]
test_04: [test_131, test_132, test_133]
ungrouped: []
vmm_iocage_02: [ansible_client, test_111, test_112, test_113]
vmm_iocage_04: [ansible_client, test_131, test_132, test_133]
PLAY RECAP *********************************************************************
ansible_client : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_111 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_112 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_113 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_131 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_132 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_133 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Note
The inventory files in the directory
hostsare evaluated in alphabetical order.The jail
ansible_clientfromiocage_02overrides the one fromiocage_01See the special variable groups
Playbook pb-ansible-client.yml
- hosts: ansible_client
tasks:
- debug:
msg: |
inventory_hostname: {{ inventory_hostname }}
ansible_host: {{ ansible_host }}
release: {{ release }}
iocage_tags:
{{ iocage_tags | to_nice_yaml(indent=2) | indent(2) }}
group_names:
{{ group_names | to_nice_yaml(indent=2) | indent(2) }}
Playbook output - Display iocage_tags and group_names
(env) > ansible-playbook pb-ansible-client.yml -i hosts
PLAY [ansible_client] **********************************************************
TASK [debug] *******************************************************************
ok: [ansible_client] =>
msg: |-
inventory_hostname: ansible_client
ansible_host: 10.1.0.198
release: 15.0
iocage_tags:
vmm: iocage_04
group_names:
- distro_02_14_3_RELEASE_p8
- distro_04_15_0_RELEASE_p3
- state_02_down
- state_04_down
- vmm_iocage_02
- vmm_iocage_04
PLAY RECAP *********************************************************************
ansible_client : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Note
The structure of the inventory hosts and groups is flat. The jail
ansible-clientis the same in all groups.See the special variable group_names
Warning
There are no internal checks of the hosts overriding each other. The consistency is up to you.
Playbook pb-test.yml
- hosts: all
tasks:
- debug:
msg: "{{ inventory_hostname }} running at {{ iocage_tags.vmm | d('UNDEFINED') }}"
Playbook output - Display all jails
(env) > ansible-playbook pb-test.yml -i hosts
PLAY [all] *********************************************************************
TASK [debug] *******************************************************************
ok: [ansible_client] =>
msg: ansible_client running at iocage_04
ok: [test_111] =>
msg: test_111 running at iocage_02
ok: [test_112] =>
msg: test_112 running at iocage_02
ok: [test_113] =>
msg: test_113 running at iocage_02
ok: [test_131] =>
msg: test_131 running at iocage_04
ok: [test_132] =>
msg: test_132 running at iocage_04
ok: [test_133] =>
msg: test_133 running at iocage_04
PLAY RECAP *********************************************************************
ansible_client : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_111 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_112 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_113 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_131 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_132 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_133 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0