030 Create Ansible client templates and clone Ansible client jails.¶
Tree¶
shell> tree .
.
├── ansible.cfg
├── files
│ └── pk_admins.txt
├── hosts
│ ├── 01_iocage.yml
│ ├── 02_iocage.yml
│ └── 03_constructed.yml
├── host_vars
│ ├── iocage_01
│ │ └── iocage.yml
│ └── iocage_02
│ └── iocage.yml
├── iocage-hosts.ini
├── pb-iocage-ansible-clients.yml
├── pb-iocage-template.yml
├── pb-test-01.yml
└── tasks
├── create.yml
├── pkg.yml
├── pk.yml
├── rc_conf.yml
├── setup.yml
├── start.yml
├── stop.yml
├── sudo.yml
├── template.yml
└── user.yml
Synopsis¶
On two iocage hosts:
iocage_01
iocage_02
In the playbook pb-iocage-template.yml, use the modules:
vbotka.freebsd.iocage to create, start, stop, and convert jails to templates.
vbotka.freebsd.iocage exec to create a user and set .ssh ownership.
community.general.pkgng to install packages.
ansible.posix.authorized_key to configure public keys.
ansible.builtin.lineinfile to configure /etc/rc.conf and /usr/local/etc/sudoers
In the playbook 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.
On all created jails:
In the playbook pb-test-01.yml:
connect created jails
display basic configuration of the jails.
Requirements¶
module vbotka.freebsd.iocage
inventory plugin vbotka.freebsd.iocage
root privilege on the iocage hosts
activated iocage
fetched releases
Notes¶
Configuration ansible.cfg¶
[defaults]
gathering = explicit
stdout_callback = yaml
[connection]
pipelining = true
host_vars/iocage_01/iocage.yml¶
ansible_python_interpreter: /usr/local/bin/python3.9
ansible_become_password: admin
freebsd_iocage_pool: pool2
freebsd_iocage_pool_mount: /mnt/pool2
freebsd_iocage_mount: "{{ freebsd_iocage_pool_mount }}/iocage"
properties:
vnet: 'on'
defaultrouter: 10.1.0.10
notes: "vmm={{ inventory_hostname }}"
jails:
- name: ansible_client
release: 13.4-RELEASE
properties:
ip4_addr: 'vnet0|10.1.0.198/24'
clones:
- name: test_101
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.101/24'
- name: test_102
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.102/24'
- name: test_103
clone_from: ansible_client
properties:
ip4_addr: 'vnet0|10.1.0.103/24'
start: [test_101, test_102, test_103]
# ansible client template
act_user: admin
act_pkg:
- security/sudo
- lang/python39
act_pk: pk_admins.txt
host_vars/iocage_02/iocage.yml¶
ansible_python_interpreter: /usr/local/bin/python3.11
freebsd_iocage_runner_env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
freebsd_iocage_pool: zroot
freebsd_iocage_pool_mount: /zroot
freebsd_iocage_mount: "{{ freebsd_iocage_pool_mount }}/iocage"
properties:
notes: "vmm={{ inventory_hostname }}"
jails:
- name: ansible_client
release: 14.1-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'
start: [test_111, test_112, test_113]
# ansible client template
act_user: admin
act_pkg:
- security/sudo
- lang/python311
act_pk: pk_admins.txt
Note
The user act_user will be created in the template.
The user act_user will serve as Ansible remote_user.
The file act_pk provides the public keys allowed to ssh to act_user.
Warning
The user act_user must exist on the iocage host. Otherwise, the module ansible.posix.authorized_key will crash. See tasks/pk.yml
Inventory iocage-hosts.ini¶
iocage_01 ansible_host=10.1.0.18
iocage_02 ansible_host=10.1.0.73
[iocage]
iocage_01
iocage_02
[iocage:vars]
ansible_user=admin
ansible_become=true
Playbook pb-iocage-template.yml¶
- name: Create Ansible client templates.
hosts: iocage
environment: "{{ freebsd_iocage_runner_env | d({}) }}"
vars:
debug: false
debug2: false
tasks:
- name: Setup
tags: [always, setup]
import_tasks: tasks/setup.yml
- name: Create jails
tags: create
import_tasks: tasks/create.yml
- name: Start jails
tags: start
import_tasks: tasks/start.yml
- name: Install packages
tags: pkg
import_tasks: tasks/pkg.yml
- name: Create user
tags: user
import_tasks: tasks/user.yml
- name: Configure public keys
tags: pk
import_tasks: tasks/pk.yml
- name: Configure sudo
tags: sudo
import_tasks: tasks/sudo.yml
- name: Configure /etc/rc.conf
tags: rc_conf
import_tasks: tasks/rc_conf.yml
- name: Stop jails
tags: stop
import_tasks: tasks/stop.yml
- name: Convert jails to templates
tags: template
import_tasks: tasks/template.yml
Playbook output¶
(env) > ansible-playbook pb-iocage-template.yml -i iocage-hosts.ini -e debug=true
...
List templates at iocage_01¶
[iocage_01]# iocage list -lt
+------+----------------+------+-------+----------+-----------------+---------------------+-----+----------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+================+======+=======+==========+=================+=====================+=====+==========+==========+
| None | ansible_client | off | down | template | 13.4-RELEASE-p2 | vnet0|10.1.0.198/24 | - | - | no |
+------+----------------+------+-------+----------+-----------------+---------------------+-----+----------+----------+
List 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.1-RELEASE-p6 | em0|10.1.0.199/24 | - | - | no |
+------+----------------+------+-------+----------+-----------------+-------------------+-----+----------+----------+
Playbook pb-iocage-ansible-clients.yml¶
- name: Create and start ansible clients.
hosts: iocage
environment: "{{ freebsd_iocage_runner_env | d({}) }}"
vars:
debug: false
debug2: false
destroy: false
tasks:
- name: Create and start jails
tags: create
block:
- name: Create jails from template
register: out
vbotka.freebsd.iocage:
state: cloned
clone_from: ansible_client
name: "{{ item.name }}"
properties: "{{ [properties, item.properties] | combine }}"
loop: "{{ clones }}"
loop_control:
label: "{{ item.name }} {{ item.clone_from }}"
- name: "Debug clone jails from template debug2={{ debug2 }}"
when: debug2 | bool
ansible.builtin.debug:
var: out
- name: Start jails
register: out
vbotka.freebsd.iocage:
state: started
name: "{{ item }}"
loop: "{{ start }}"
- name: "Debug start jails debug2={{ debug2 }}"
when: debug2 | bool
ansible.builtin.debug:
var: out
- name: Stop and destroy jails
when: destroy | bool
tags: destroy
block:
- name: Stop jails
register: out
vbotka.freebsd.iocage:
state: stopped
name: "{{ item.name }}"
loop: "{{ clones }}"
loop_control:
label: "{{ item.name }}"
- name: "Debug stop jails debug2={{ debug2 }}"
when: debug2 | bool
ansible.builtin.debug:
var: out
- name: Destroy jails
register: out
vbotka.freebsd.iocage:
state: absent
name: "{{ item.name }}"
loop: "{{ clones }}"
loop_control:
label: "{{ item.name }}"
- name: "Debug destroy jails debug2={{ debug2 }}"
when: debug2 | bool
ansible.builtin.debug:
var: out
- name: "Display jails dictionary debug2={{ debug2 }}"
when: debug2 | bool
ansible.builtin.debug:
var: iocage_jails
- name: "Display jails list debug={{ debug }}"
when: debug | bool
ansible.builtin.debug:
var: iocage_jails.keys()
Playbook output¶
(env) > ansible-playbook pb-iocage-ansible-clients.yml -i iocage-hosts.ini -e debug=true
PLAY [Create and start ansible clients.] *******************************************************
TASK [Create jails from template] **************************************************************
changed: [iocage_01] => (item=test_101 ansible_client)
changed: [iocage_01] => (item=test_102 ansible_client)
changed: [iocage_02] => (item=test_111 ansible_client)
changed: [iocage_01] => (item=test_103 ansible_client)
changed: [iocage_02] => (item=test_112 ansible_client)
changed: [iocage_02] => (item=test_113 ansible_client)
TASK [Debug clone jails from template debug2=False] ********************************************
skipping: [iocage_01]
skipping: [iocage_02]
TASK [Start jails] *****************************************************************************
changed: [iocage_01] => (item=test_101)
changed: [iocage_01] => (item=test_102)
changed: [iocage_02] => (item=test_111)
changed: [iocage_01] => (item=test_103)
changed: [iocage_02] => (item=test_112)
changed: [iocage_02] => (item=test_113)
TASK [Debug start jails debug2=False] **********************************************************
skipping: [iocage_01]
skipping: [iocage_02]
...
TASK [Display jails list debug=true] ***********************************************************
ok: [iocage_01] =>
iocage_jails.keys():
- test_101
- test_102
- test_103
ok: [iocage_02] =>
iocage_jails.keys():
- test_111
- test_112
- test_113
PLAY RECAP *************************************************************************************
iocage_01: ok=3 changed=2 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
iocage_02: ok=3 changed=2 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
List jails at iocage_01¶
[iocage_01]# iocage list -l
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+=====+==========+======+=======+======+=================+=====================+=====+================+==========+
| 134 | test_101 | off | up | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.101/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| 135 | test_102 | off | up | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.102/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| 136 | test_103 | off | up | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.103/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
List jails at iocage_02¶
[iocage_02]# iocage list -l
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+=====+==========+======+=======+======+=================+===================+=====+================+==========+
| 170 | test_111 | off | up | jail | 14.1-RELEASE-p6 | em0|10.1.0.111/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| 171 | test_112 | off | up | jail | 14.1-RELEASE-p6 | em0|10.1.0.112/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| 172 | test_113 | off | up | jail | 14.1-RELEASE-p6 | em0|10.1.0.113/24 | - | ansible_client | no |
+-----+----------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
Inventory hosts/01_iocage.yml¶
plugin: vbotka.freebsd.iocage
host: 10.1.0.18
user: admin
get_properties: true
env:
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
compose:
ansible_host: iocage_ip4
groups:
test_01: inventory_hostname.startswith('test')
Inventory hosts/02_iocage.yml¶
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')
Inventory hosts/03_constructed.yml¶
plugin: ansible.builtin.constructed
groups:
test: inventory_hostname.startswith('test')
Display inventory¶
(env) > ansible-inventory -i hosts --graph
@all:
|--@ungrouped:
|--@test_01:
| |--test_101
| |--test_102
| |--test_103
|--@test_02:
| |--test_111
| |--test_112
| |--test_113
|--@test:
| |--test_101
| |--test_102
| |--test_103
| |--test_111
| |--test_112
| |--test_113
Playbook pb-test-01.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 }}
{{ 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¶
(env) > ansible-playbook pb-test-01.yml -i hosts
PLAY [Connect to the group test.] *************************************************************
TASK [Gathering Facts] ************************************************************************
ok: [test_103]
ok: [test_101]
ok: [test_112]
ok: [test_102]
ok: [test_111]
ok: [test_113]
TASK [ansible.builtin.command] ****************************************************************
changed: [test_102]
changed: [test_103]
changed: [test_101]
changed: [test_112]
changed: [test_111]
changed: [test_113]
TASK [ansible.builtin.debug] ******************************************************************
ok: [test_101] =>
msg: |-
test-101 test_101 34333834-3734-5a43-3331-313342464631 /usr/local/bin/python3.9
ok: [test_102] =>
msg: |-
test-102 test_102 34333834-3734-5a43-3331-313342464631 /usr/local/bin/python3.9
ok: [test_103] =>
msg: |-
test-103 test_103 34333834-3734-5a43-3331-313342464631 /usr/local/bin/python3.9
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
TASK [ansible.builtin.command] ****************************************************************
changed: [test_101]
changed: [test_111]
changed: [test_112]
changed: [test_103]
changed: [test_102]
changed: [test_113]
TASK [ansible.builtin.command] ****************************************************************
changed: [test_101]
changed: [test_103]
changed: [test_102]
changed: [test_111]
changed: [test_112]
changed: [test_113]
TASK [ansible.builtin.debug] ******************************************************************
ok: [test_101] =>
msg: |-
test-101 admin root
ok: [test_102] =>
msg: |-
test-102 admin root
ok: [test_103] =>
msg: |-
test-103 admin root
ok: [test_111] =>
msg: |-
test-111 admin root
ok: [test_112] =>
msg: |-
test-112 admin root
ok: [test_113] =>
msg: |-
test-113 admin root
PLAY RECAP ************************************************************************************
test_101: ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_102: ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_103: ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
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