200 Create iocage templates. Clone jails.
Use case
Create iocage templates for Ansible clients. Clone jails.
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 managed nodes:
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 tasks to create a user and set .ssh ownership.ansible.posix.authorized_keyto configure public keys.community.general.sysrcto configure /etc/rc.confansible.builtin.lineinfileto configure /usr/local/etc/sudoers
In the playbook vbotka.freebsd.pb_iocage_ansible_clients.yml, use the module vbotka.freebsd.iocage to:
create jails from the iocage 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 configuration of the jails.
Requirements
root privilege in the managed nodes
activated
iocagefetched releases.
Notes
The playbook vbotka.freebsd.pb_iocage_template.yml expects to find the file
pkgs.jsonin the directoryfiles. See the tasksplaybooks/pb_iocage_template_pkglist.ymland pb_iocage_template.
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: 'on'
dhcp: 'on'
vnet: 'on'
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: {}
clones:
test_111:
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.111/24'
test_112:
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.112/24'
test_113:
clone_from: ansible_client
properties:
ip4_addr: 'em0|10.1.0.113/24'
# clones default properties
properties:
notes: "vmm={{ inventory_hostname }}"
start: "{{ clones.keys() }}"
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: 'on'
dhcp: 'on'
vnet: 'on'
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: {}
clones:
test_131:
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.131/24'
test_132:
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.132/24'
test_133:
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.133/24'
# clones default properties
properties:
bpf: 'on'
notes: "vmm={{ inventory_hostname }}"
start: "{{ clones.keys() }}"
Note
The variables act_* are used to configure the template
The user
act_userwill be created in the template.The user
act_userwill serve as Ansibleremote_userThe file
act_pkprovides the public keys allowed to ssh toact_userin a 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_04] => (item=ansible_client /tmp/ansible/ansible_client/pkgs.json)
ok: [iocage_02] => (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_04]
ok: [iocage_02]
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 [Rcconf: Configure /etc/rc.conf] ******************************************
changed: [iocage_04] => (item=ansible_client iocage_enable YES)
changed: [iocage_02] => (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=14 changed=5 unreachable=0 failed=0 skipped=28 rescued=0 ignored=0
iocage_04 : ok=14 changed=5 unreachable=0 failed=0 skipped=28 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
Playbook output - List jails
(env) > ansible-playbook vbotka.freebsd.pb_iocage_ansible_clients.yml \
-i iocage.ini \
-t list \
-e debug=true
PLAY [Create and start jails. Optionally stop and destroy jails.] **************
TASK [Get iocage facts] ********************************************************
ok: [iocage_04]
ok: [iocage_02]
TASK [Display iocage_jails keys debug=true] ************************************
ok: [iocage_02] =>
ansible_facts.iocage_jails.keys():
- test_111
- test_112
- test_113
ok: [iocage_04] =>
ansible_facts.iocage_jails.keys():
- test_131
- test_132
- test_133
PLAY RECAP *********************************************************************
iocage_02 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
iocage_04 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Jails at iocage_02
[iocage_02]# iocage list -l
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+=====+==========+======+=======+======+=================+===================+=====+================+==========+
| 74 | test_111 | off | up | jail | 14.3-RELEASE-p8 | em0|10.1.0.111/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| 75 | test_112 | off | up | jail | 14.3-RELEASE-p8 | em0|10.1.0.112/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| 76 | test_113 | off | up | jail | 14.3-RELEASE-p8 | em0|10.1.0.113/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
Jails at iocage_04
[iocage_04]# iocage list -l
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+=====+==========+======+=======+======+=================+=====================+=====+================+==========+
| 53 | test_131 | off | up | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.131/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| 54 | test_132 | off | up | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.132/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| 55 | test_133 | off | up | jail | 15.0-RELEASE-p3 | vnet0|10.1.0.133/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
Inventory hosts
plugin: vbotka.freebsd.iocage
host: 10.1.0.73
user: admin
get_properties: true
env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
compose:
ansible_host: iocage_ip4
groups:
test_02: inventory_hostname.startswith('test')
plugin: vbotka.freebsd.iocage
host: 10.1.0.29
user: admin
get_properties: true
compose:
ansible_host: iocage_ip4
groups:
test_04: 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_04:
| |--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
remote_user: admin
gather_facts: true
vars:
ansible_python_interpreter: auto_silent
tasks:
- ansible.builtin.command: hostname
register: out_host
- ansible.builtin.debug:
msg: >
{{ out_host.stdout }}
{{ iocage_properties.host_hostuuid }}
{{ iocage_properties.hostid }}
{{ ansible_facts.discovered_interpreter_python }}
- ansible.builtin.command: whoami
register: out_user
- ansible.builtin.command: whoami
register: out_root
become: true
- ansible.builtin.debug:
msg: >
{{ out_host.stdout }}
{{ out_user.stdout }}
{{ out_root.stdout }}
Playbook output - Display test vars
(env) > ansible-playbook pb-test.yml -i hosts
PLAY [Connect to the group test.] **********************************************
TASK [Gathering Facts] *********************************************************
ok: [test_113]
ok: [test_112]
ok: [test_111]
ok: [test_133]
[ERROR]: Task failed: Failed to connect to the host via ssh: ssh: connect to host 10.1.0.132 port 22: Connection timed out
Task failed.
<<< caused by >>>
Failed to connect to the host via ssh: ssh: connect to host 10.1.0.132 port 22: Connection timed out
fatal: [test_132]: UNREACHABLE! =>
changed: false
msg: 'Task failed: Failed to connect to the host via ssh: ssh: connect to host 10.1.0.132
port 22: Connection timed out'
unreachable: true
[ERROR]: Task failed: Failed to connect to the host via ssh: ssh: connect to host 10.1.0.131 port 22: Connection timed out
Task failed.
<<< caused by >>>
Failed to connect to the host via ssh: ssh: connect to host 10.1.0.131 port 22: Connection timed out
fatal: [test_131]: UNREACHABLE! =>
changed: false
msg: 'Task failed: Failed to connect to the host via ssh: ssh: connect to host 10.1.0.131
port 22: Connection timed out'
unreachable: true
TASK [ansible.builtin.command] *************************************************
changed: [test_133]
changed: [test_113]
changed: [test_111]
changed: [test_112]
TASK [ansible.builtin.debug] ***************************************************
ok: [test_111] =>
msg: |-
test-111 test_111 ea2ba7d1-4fcd-f13f-82e4-8b32c0a03403 /usr/local/bin/python3.11
ok: [test_112] =>
msg: |-
test-112 test_112 ea2ba7d1-4fcd-f13f-82e4-8b32c0a03403 /usr/local/bin/python3.11
ok: [test_113] =>
msg: |-
test-113 test_113 ea2ba7d1-4fcd-f13f-82e4-8b32c0a03403 /usr/local/bin/python3.11
ok: [test_133] =>
msg: |-
test-133 test_133 d6add9ad-8b6e-4316-a226-345a60532b41 /usr/local/bin/python3.11
TASK [ansible.builtin.command] *************************************************
changed: [test_133]
changed: [test_111]
changed: [test_112]
changed: [test_113]
TASK [ansible.builtin.command] *************************************************
changed: [test_133]
changed: [test_111]
changed: [test_112]
changed: [test_113]
TASK [ansible.builtin.debug] ***************************************************
ok: [test_111] =>
msg: |-
test-111 admin root
ok: [test_112] =>
msg: |-
test-112 admin root
ok: [test_113] =>
msg: |-
test-113 admin root
ok: [test_133] =>
msg: |-
test-133 admin root
PLAY RECAP *********************************************************************
test_111 : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_112 : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_113 : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_131 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
test_132 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
test_133 : ok=6 changed=3 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