202 Create iocage templates. Clone DHCP jails.
Extending example 200 Create iocage templates. Clone jails..
Use case
Create iocage templates for Ansible clients. Get the IP addresses by DHCP. Create the
dhclient-exit-hooks. For example, the below hook
shell> cat /zroot/iocage/templates/ansible_client/root/etc/dhclient-exit-hooks
case "$reason" in
"BOUND"|"REBIND"|"REBOOT"|"RENEW")
echo $new_ip_address > /var/db/dhclient-hook.address.$interface
;;
esac
creates files. For example,
shell> cat /zroot/iocage/jails/test_131/root/var/db/dhclient-hook.address.epair0b
10.1.0.130
Read the files created by the hooks and use the IP addresses to compose the variable
ansible_host
shell> cat hosts/01_iocage.yml
plugin: vbotka.freebsd.iocage
...
hooks_results:
- /var/db/dhclient-hook.address.epair0b
compose:
ansible_host: iocage_hooks.0
In the below declaration, the variable ansible_host defaults to iocage_ip4 if the hook is
not available
compose:
ansible_host: (iocage_hooks.0 == '-') | ternary(iocage_ip4, iocage_hooks.0)
Tree
shell> tree .
.
├── ansible.cfg
├── files
│ ├── pk_admins.txt
│ └── pkgs.json
├── hosts
│ ├── 02_iocage.yml
│ ├── 04_iocage.yml
│ └── 99_constructed.yml
├── host_vars
│ ├── iocage_02
│ │ └── iocage.yml
│ └── iocage_04
│ └── iocage.yml
├── iocage.ini
└── pb-test.yml
Synopsis
At two iocage hosts:
iocage_02
iocage_04
In the playbook vbotka.freebsd.pb_iocage_template.yml, use the modules:
vbotka.freebsd.iocageto create, start, stop, and convert jails to templates.vbotka.freebsd.iocageexec to create a user and set .ssh ownership.community.general.sysrcto configure /etc/rc.confansible.posix.authorized_keyto configure public keys.ansible.builtin.lineinfileto configure /usr/local/etc/sudoersconfigure
dhclient hooks
In the playbook vbotka.freebsd.pb_iocage_ansible_clients.yml, use the module vbotka.freebsd.iocage to:
create jails from the Ansible client templates
start all jails
optionally, display the lists of jails.
At all created jails:
In the playbook
pb-test.yml:connect created jails
display basic jails’ configuration.
Requirements
root privilege in the managed nodes
activated
iocagefetched releases.
Notes
The option
hooks_resultsexpects thepoolnameof a jail to be mounted to/poolname. For example, if you activate the poolzrootthis plugin expects to find thehooks_resultsitems in the path/zroot/iocage/jails/<name>/root. If you mount thepoolnameto a different path the easiest remedy is to create a symlink.
See also
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
files
{
"pkgs": [
"python311",
"sudo"
]
}
host_vars
freebsd_iocage_pool: zroot
freebsd_iocage_pool_mount: /zroot
freebsd_iocage_mount: /zroot/iocage
templates:
ansible_client:
release: 14.3-RELEASE
properties:
bpf: 1
dhcp: 1
vnet: 1
dhclient: "{{ act_dhclient | dict2items }}"
rcconf: "{{ act_rcconf | dict2items }}"
pkglist: /tmp/ansible/ansible_client/pkgs.json
# ansible client template defaults
act_user: admin
act_pk: pk_admins.txt
act_sudo: true
act_rcconf:
iocage_enable: "YES"
sshd_enable: "YES"
act_dhclient:
dhclient-exit-hooks: |
case "$reason" in
"BOUND"|"REBIND"|"REBOOT"|"RENEW")
echo $new_ip_address > /var/db/dhclient-hook.address.$interface
;;
esac
clones:
test_111: {clone_from: ansible_client}
test_112: {clone_from: ansible_client}
test_113: {clone_from: ansible_client}
start: "{{ clones.keys() }}"
swarms: {}
# clones default properties
properties:
bpf: 1
dhcp: 1
vnet: 1
notes: "vmm={{ inventory_hostname }}"
iocage_env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
freebsd_iocage_pool: iocage
freebsd_iocage_pool_mount: /iocage
freebsd_iocage_mount: /iocage/iocage
templates:
ansible_client:
release: 15.0-RELEASE
properties:
bpf: 1
dhcp: 1
vnet: 1
dhclient: "{{ act_dhclient | dict2items }}"
rcconf: "{{ act_rcconf | dict2items }}"
pkglist: /tmp/ansible/ansible_client/pkgs.json
# ansible client template defaults
act_user: admin
act_pk: pk_admins.txt
act_sudo: true
act_rcconf:
iocage_enable: "YES"
sshd_enable: "YES"
act_dhclient:
dhclient-exit-hooks: |
case "$reason" in
"BOUND"|"REBIND"|"REBOOT"|"RENEW")
echo $new_ip_address > /var/db/dhclient-hook.address.$interface
;;
esac
clones:
test_131: {clone_from: ansible_client}
test_132: {clone_from: ansible_client}
test_133: {clone_from: ansible_client}
start: "{{ clones.keys() }}"
swarms: {}
# clones default properties
properties:
bpf: 1
dhcp: 1
vnet: 1
notes: "vmm={{ inventory_hostname }}"
Hint
The minimal required hook is
act_dhclient:
dhclient-exit-hooks: |
case "$reason" in
"BOUND"|"REBIND"|"REBOOT"|"RENEW")
echo $new_ip_address > /var/db/dhclient-hook.address.$interface
;;
esac
Note
The variables act_* are used to configure ansible_client template
The dhclient hooks
act_dhclientwill be created in/etc.The user
act_userwill be created in the template.The user
act_userwill serve as Ansibleremote_user.The file
act_pkprovides the public keys allowed to ssh toact_userin the jail.
Warning
The user
act_usermust exist on theiocagehost. Otherwise, the moduleansible.posix.authorized_keywill crash. Seeplaybooks/pb_iocage_template/pk.ymlThe file
files/pk_admins.txtwas sanitized. Fit the public keys to your needsshell> cat files/pk_admins.txt ssh-rsa <sanitized> admin@controller
Playbook output - Create templates
(env) > ansible-playbook vbotka.freebsd.pb_iocage_template.yml -i iocage.ini
PLAY [Create Ansible client templates.] ****************************************
TASK [Setup: Get iocage list of templates.] ************************************
ok: [iocage_04]
ok: [iocage_02]
TASK [Setup: Set dictionary iocage_templates] **********************************
ok: [iocage_04]
ok: [iocage_02]
TASK [Pkglist: Create directories for pkglist files.] **************************
ok: [iocage_04] => (item=ansible_client /tmp/ansible/ansible_client/pkgs.json)
ok: [iocage_02] => (item=ansible_client /tmp/ansible/ansible_client/pkgs.json)
TASK [Pkglist: Copy pkglist files.] ********************************************
ok: [iocage_02] => (item=ansible_client /tmp/ansible/ansible_client/pkgs.json)
ok: [iocage_04] => (item=ansible_client /tmp/ansible/ansible_client/pkgs.json)
TASK [Create: Create templates.] ***********************************************
changed: [iocage_04] => (item=ansible_client 15.0-RELEASE)
changed: [iocage_02] => (item=ansible_client 14.3-RELEASE)
TASK [Start: Start jails.] *****************************************************
ok: [iocage_02]
ok: [iocage_04]
TASK [User: Create user.] ******************************************************
changed: [iocage_04] => (item=ansible_client admin)
changed: [iocage_02] => (item=ansible_client admin)
TASK [Pk: The keys are valid.] *************************************************
ok: [iocage_02] =>
changed: false
msg: All assertions passed
ok: [iocage_04] =>
changed: false
msg: All assertions passed
TASK [Pk: Configure public keys.] **********************************************
changed: [iocage_04] => (item=ansible_client admin)
changed: [iocage_02] => (item=ansible_client admin)
TASK [Pk: Chown .ssh] **********************************************************
ok: [iocage_04] => (item=ansible_client admin)
ok: [iocage_02] => (item=ansible_client admin)
TASK [Sudo: Configure sudo.] ***************************************************
changed: [iocage_04] => (item=ansible_client admin)
changed: [iocage_02] => (item=ansible_client admin)
TASK [Dhclient: Configure hooks.] **********************************************
changed: [iocage_04] => (item=ansible_client dhclient-exit-hooks)
changed: [iocage_02] => (item=ansible_client dhclient-exit-hooks)
TASK [Rcconf: Configure /etc/rc.conf] ******************************************
changed: [iocage_02] => (item=ansible_client iocage_enable YES)
changed: [iocage_04] => (item=ansible_client iocage_enable YES)
changed: [iocage_04] => (item=ansible_client sshd_enable YES)
changed: [iocage_02] => (item=ansible_client sshd_enable YES)
TASK [Stop: Stop jails.] *******************************************************
ok: [iocage_04]
ok: [iocage_02]
TASK [Template: Set template.] *************************************************
ok: [iocage_04] => (item=ansible_client)
ok: [iocage_02] => (item=ansible_client)
PLAY RECAP *********************************************************************
iocage_02 : ok=15 changed=6 unreachable=0 failed=0 skipped=27 rescued=0 ignored=0
iocage_04 : ok=15 changed=6 unreachable=0 failed=0 skipped=27 rescued=0 ignored=0
Templates at iocage_02
[iocage_02]# iocage list -lt
+------+----------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+================+======+=======+==========+=================+====================+=====+==========+==========+
| None | ansible_client | off | down | template | 14.3-RELEASE-p8 | DHCP (not running) | - | - | no |
+------+----------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
Templates at iocage_04
[iocage_04]# iocage list -lt
+------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
| 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 |
+------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
Playbook output - Clone and start jails
(env) > ansible-playbook vbotka.freebsd.pb_iocage_ansible_clients.yml -i iocage.ini
-t clone -e clone=true
PLAY [Create and start jails. Optionally stop and destroy jails.] **************
TASK [Create clones from template] *********************************************
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 [Start clones] ************************************************************
changed: [iocage_04]
changed: [iocage_02]
PLAY RECAP *********************************************************************
iocage_02 : ok=2 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
iocage_04 : ok=2 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Jails at iocage_02
[iocage_02]# iocage list -l
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+=====+==========+======+=======+======+=================+====================+=====+================+==========+
| 79 | test_111 | off | up | jail | 14.3-RELEASE-p8 | epair0b|10.1.0.174 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 80 | test_112 | off | up | jail | 14.3-RELEASE-p8 | epair0b|10.1.0.147 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 81 | test_113 | off | up | jail | 14.3-RELEASE-p8 | epair0b|10.1.0.231 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
Jails at iocage_04
[iocage_04]# iocage list -l
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+=====+==========+======+=======+======+=================+====================+=====+================+==========+
| 58 | test_131 | off | up | jail | 15.0-RELEASE-p3 | epair0b|10.1.0.224 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 60 | test_132 | off | up | jail | 15.0-RELEASE-p3 | epair0b|10.1.0.185 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 59 | test_133 | off | up | jail | 15.0-RELEASE-p3 | epair0b|10.1.0.225 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
Inventory hosts
plugin: vbotka.freebsd.iocage
host: 10.1.0.73
user: admin
env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
hooks_results:
- /var/db/dhclient-hook.address.epair0b
compose:
ansible_host: (iocage_hooks.0 == '-') | ternary(iocage_ip4, iocage_hooks.0)
groups:
test_02: inventory_hostname.startswith('test')
plugin: vbotka.freebsd.iocage
host: 10.1.0.29
user: admin
hooks_results:
- /var/db/dhclient-hook.address.epair0b
compose:
ansible_host: (iocage_hooks.0 == '-') | ternary(iocage_ip4, iocage_hooks.0)
groups:
test_01: inventory_hostname.startswith('test')
plugin: ansible.builtin.constructed
groups:
test: inventory_hostname.startswith('test')
Display inventory
(env) > ansible-inventory -i hosts --graph
@all:
|--@ungrouped:
|--@test_02:
| |--test_111
| |--test_112
| |--test_113
|--@test_01:
| |--test_131
| |--test_132
| |--test_133
|--@test:
| |--test_111
| |--test_112
| |--test_113
| |--test_131
| |--test_132
| |--test_133
Playbook pb-test.yml
- name: Connect to the group test.
hosts: test
gather_facts: false
remote_user: admin
vars:
ansible_python_interpreter: auto_silent
tasks:
- ansible.builtin.command: hostname
register: out_host
- ansible.builtin.debug:
msg: "ansible_host={{ ansible_host }} iocage_hooks={{ iocage_hooks }}"
Playbook output - Display list iocage_hooks
(env) > ansible-playbook pb-test.yml -i hosts
PLAY [Connect to the group test.] **********************************************
TASK [ansible.builtin.command] *************************************************
changed: [test_131]
changed: [test_132]
changed: [test_133]
changed: [test_111]
changed: [test_112]
changed: [test_113]
TASK [ansible.builtin.debug] ***************************************************
ok: [test_111] =>
msg: ansible_host=10.1.0.174 iocage_hooks=['10.1.0.174']
ok: [test_112] =>
msg: ansible_host=10.1.0.147 iocage_hooks=['10.1.0.147']
ok: [test_113] =>
msg: ansible_host=10.1.0.231 iocage_hooks=['10.1.0.231']
ok: [test_131] =>
msg: ansible_host=10.1.0.224 iocage_hooks=['10.1.0.224']
ok: [test_132] =>
msg: ansible_host=10.1.0.185 iocage_hooks=['10.1.0.185']
ok: [test_133] =>
msg: ansible_host=10.1.0.225 iocage_hooks=['10.1.0.225']
PLAY RECAP *********************************************************************
test_111 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_112 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_113 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_131 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_133 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Hint
The below command stops and destroys the cloned jails
ansible-playbook vbotka.freebsd.pb_iocage_ansible_clients.yml -i iocage.ini \
-t clone_destroy -e clone_destroy=true