524 iocage template ansible-init
Use case
Create iocage template ansible-init. Configure firstboot service ansible_init that
runs ansible-pull and uses the repo ansible-conf-init. Configure the repo ansible-conf-init
to pull the jails’ configuration from the repo ansible-conf-test. Create jails from the
template. Use the hostname to select the configuration. Run ansible-pull asynchronously.
Tree
shell > tree .
.
├── ansible.cfg
├── files
│ ├── hello-world.txt
│ ├── pkgs.json
│ └── project-hosts.yml
├── group_vars
│ └── all
│ ├── project-hosts.yml
│ └── project.yml
├── hosts
│ └── 05_iocage.yml
├── host_vars
│ └── iocage_05
│ └── template.yml
├── iocage.ini
└── pb-iocage-template.yml
Synopsis
At a managed node:
Use the role vbotka.freebsd.iocage_template to create the template
ansible-initIn the playbook vbotka.freebsd.pb_iocage_project_create_from_templates.yml create jails from the template.
Wait for ansible-pull to configure the jails and display the test files.
Requirements
Note
See the option
firstboot_sentinelin man rc.confSee the example 523 iocage template ansible-repos
See the
Troubleshootingsection in 526 Log server and clients (ansible_init)
ansible.cfg
[defaults]
callback_result_format = yaml
deprecation_warnings = false
display_skipped_hosts = false
gathering = explicit
interpreter_python = auto_silent
log_path = /var/log/ansible.log
[connection]
pipelining = true
Inventory iocage.ini
iocage_05
[iocage]
iocage_05
[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent
hosts
plugin: vbotka.freebsd.iocage
host: iocage_05
user: admin
sudo: true
get_properties: true
inventory_hostname_tag: alias
compose:
iocage_tags: dict(iocage_properties.notes | regex_findall('(\w+)=([\w\-]+)'))
iocage_classes: iocage_properties.notes | regex_findall('(?<=class=)[\w\-]+|(?<=,)[\w\-]+')
# connection plugin vbotka.freebsd.jailexec
ansible_connection: "'vbotka.freebsd.jailexec'"
ansible_jail_host: dict(iocage_properties.notes | regex_findall('(\w+)=([\w\-]+)')).vmm | d('none')
ansible_jail_name: iocage_jid
ansible_jail_privilege_escalation: "'sudo'"
# ansible options
ansible_python_interpreter: "'auto_silent'"
groups:
pull_init: iocage_classes is contains('init')
keyed_groups:
- prefix: state
key: iocage_state
- prefix: vmm
key: iocage_tags.vmm
group_vars
project_hosts:
iocage_05:
defaultrouter: 172.16.99.1
log_server: 172.16.99.10
# repositories
repos: 172.16.99.21
repos_devel: 172.16.99.22
# plugins
ansible_pull_syslogng_server: 172.16.99.31
project:
foo:
vmm: iocage_05
template: ansible-init
class: [test]
bar:
vmm: iocage_05
template: ansible-init
class: [test]
properties:
ip4: disable
ip6: disable
ip6_addr: none
bpf: 1
dhcp: 1
vnet: 1
boot: 1
vmm_groups: "{{ dict(project | dict2items | groupby('value.vmm')) }}"
vmm: "{{ dict(vmm_groups.keys() | zip(vmm_groups.values() | map('items2dict'))) }}"
host_vars
fit_templates:
ansible-init:
release: 15.0-RELEASE
pkglist: /tmp/ansible/ansible_init/pkgs.json
cron: "{{ fit_cron | dict2items }}"
files: "{{ fit_files | dict2items }}"
file_lines: "{{ fit_file_lines | dict2items }}"
firstboot: "{{ fit_firstboot | dict2items }}"
rcconf: "{{ fit_rcconf | dict2items }}"
properties:
ip4: disable
ip6: disable
ip6_addr: none
bpf: 1
dhcp: 1
vnet: 1
notes: '"class=init alias=ansible_init"'
fit_firstboot:
ansible_init:
content: |
#!/bin/sh
#
# PROVIDE: ansible_init
# REQUIRE: FILESYSTEMS NETWORKING
# KEYWORD: firstboot
. /etc/rc.subr
name="ansible_init"
desc="Firstboot ansible-pull initialization"
rcvar="ansible_init_enable"
# Default configuration settings
: ${ansible_init_enable:="NO"}
: ${ansible_init_host:="http://localhost"}
: ${ansible_init_repo:="ansible-conf-init"}
: ${ansible_init_dest:="/root"}
: ${ansible_init_vars:="/root/ansible-vars"}
: ${ansible_init_playbook:="pb-init.yml"}
# Define the command to run
command="/usr/local/bin/ansible-pull"
# Pass the environment variables
ansible_init_env="\
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin \
LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8"
# Construct the arguments
load_rc_config $name
command_args="\
-i hosts \
-U ${ansible_init_host}/${ansible_init_repo} \
-d ${ansible_init_dest}/${ansible_init_repo} \
-e 'ai_vars=${ansible_init_vars}' \
-e 'ai_pull_mode=true' \
${ansible_init_playbook}"
run_rc_command "$1"
fit_rcconf:
ansible_init_enable: "YES"
ansible_init_host: "git://{{ project_hosts[inventory_hostname]['repos'] }}"
fit_cron:
/etc/cron.d/at:
- name: Run atrun execution daemon in 1 minute intervals.
minute: '*/1'
hour: '*'
day: '*'
month: '*'
weekday: '*'
user: root
job: /usr/libexec/atrun
exclusive: true
fit_files:
/root/ansible-vars:
- project-hosts.yml
- hello-world.txt
fit_file_lines:
/root/.profile:
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
fit_file_options:
/root/ansible-vars:
owner: root
group: wheel
mode: '0750'
/root/.profile:
assignment_operator: '='
owner: root
group: wheel
mode: '0644'
files
Hello World!
{
"pkgs": [
"py311-ansible",
"git"
]
}
project_hosts:
defaultrouter: 172.16.99.1
log_server: 172.16.99.10
# repositories
repos: 172.16.99.21
repos_devel: 172.16.99.22
# plugins
ansible_pull_syslogng_server: 172.16.99.31
Playbook pb-iocage-template.yml
---
- name: Create iocage templates.
hosts: iocage
roles:
- vbotka.freebsd.iocage_template
Playbook output - Create iocage templates
(env) > ansible-playbook pb-iocage-template.yml -i iocage.ini
PLAY [Create iocage templates.] ************************************************
TASK [vbotka.freebsd.iocage_template : Setup: Get iocage list of templates.] ***
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Setup: Get activated pool.] *************
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Pkglist: Create directories for pkglist files.] ***
ok: [iocage_05] => (item=ansible-init /tmp/ansible/ansible_init)
TASK [vbotka.freebsd.iocage_template : Pkglist: Copy pkglist files.] ***********
ok: [iocage_05] => (item=ansible-init /tmp/ansible/ansible_init/pkgs.json)
TASK [vbotka.freebsd.iocage_template : Create: Get iocage list of jails.] ******
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Create: Create jails.] ******************
ok: [iocage_05] => (item=ansible-init 15.0-RELEASE)
TASK [vbotka.freebsd.iocage_template : Start: Get iocage list of jails.] *******
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Start: Start jails.] ********************
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Files: Copy files.] *********************
included: /scratch/collections/ansible_collections/vbotka/freebsd/roles/iocage_template/tasks/fn/files.yml for iocage_05 => (item=ansible-init)
TASK [vbotka.freebsd.iocage_template : Fn/files: Create directory.] ************
changed: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Fn/files: Copy files.] ******************
changed: [iocage_05] => (item=project-hosts.yml)
changed: [iocage_05] => (item=hello-world.txt)
TASK [vbotka.freebsd.iocage_template : Lines: Configure lines in files.] *******
included: /scratch/collections/ansible_collections/vbotka/freebsd/roles/iocage_template/tasks/fn/file_lines.yml for iocage_05 => (item=ansible-init)
TASK [vbotka.freebsd.iocage_template : Fn/file_lines: Configure lines in files.] ***
changed: [iocage_05] => (item=ansible-init /root/.profile LANG=en_US.UTF-8)
changed: [iocage_05] => (item=ansible-init /root/.profile LC_ALL=en_US.UTF-8)
TASK [vbotka.freebsd.iocage_template : Firstboot: Create scripts.] *************
changed: [iocage_05] => (item=ansible-init ansible_init)
TASK [vbotka.freebsd.iocage_template : Firstboot: Touch /firstboot.] ***********
changed: [iocage_05] => (item=ansible-init)
TASK [vbotka.freebsd.iocage_template : Cron: Configure cron files.] ************
included: /scratch/collections/ansible_collections/vbotka/freebsd/roles/iocage_template/tasks/fn/cron.yml for iocage_05 => (item=ansible-init)
TASK [vbotka.freebsd.iocage_template : Fn/cron: Remove exclusive jobs from cron files.] ***
changed: [iocage_05] => (item=ansible-init /usr/libexec/atrun)
TASK [vbotka.freebsd.iocage_template : Fn/cron: Configure cron files.] *********
changed: [iocage_05] => (item=ansible-init Run atrun execution daemon in 1 minute intervals.)
TASK [vbotka.freebsd.iocage_template : Rcconf: Configure /etc/rc.conf] *********
changed: [iocage_05] => (item=ansible-init ansible_init_enable YES)
changed: [iocage_05] => (item=ansible-init ansible_init_host git://172.16.99.21)
TASK [vbotka.freebsd.iocage_template : Stop: Get iocage list of jails.] ********
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Stop: Stop jails.] **********************
ok: [iocage_05]
TASK [vbotka.freebsd.iocage_template : Template: Set template.] ****************
ok: [iocage_05] => (item=ansible-init)
PLAY RECAP *********************************************************************
iocage_05 : ok=22 changed=8 unreachable=0 failed=0 skipped=30 rescued=0 ignored=0
List templates
shell > ssh admin@iocage_05 sudo iocage list -lt
+------+-------------------------+------+-------+----------+--------------+-----------------------+-----+----------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+=========================+======+=======+==========+==============+=======================+=====+==========+==========+
| None | ansible-init | off | down | template | 15.0-RELEASE | DHCP (not running) | - | - | no |
+------+-------------------------+------+-------+----------+--------------+-----------------------+-----+----------+----------+
| None | ansible-repos | off | down | template | 15.0-RELEASE | DHCP (not running) | - | - | no |
+------+-------------------------+------+-------+----------+--------------+-----------------------+-----+----------+----------+
| None | ansible-syslogng-client | off | down | template | 15.0-RELEASE | DHCP (not running) | - | - | no |
+------+-------------------------+------+-------+----------+--------------+-----------------------+-----+----------+----------+
| None | ansible-syslogng-server | off | down | template | 15.0-RELEASE | vnet0|172.16.99.41/24 | - | - | no |
+------+-------------------------+------+-------+----------+--------------+-----------------------+-----+----------+----------+
Playbook output - Create project jails from iocage templates
(env) > ansible-playbook vbotka.freebsd.pb_iocage_project_create_from_templates.yml -i iocage.ini -i hosts
PLAY [Create and start project jails from iocage templates.] *******************
TASK [Setup: Get activated pool.] **********************************************
ok: [iocage_05]
TASK [Create: Create jails.] ***************************************************
ok: [iocage_05] => (item=foo)
ok: [iocage_05] => (item=bar)
TASK [Properties: Set properties.] *********************************************
ok: [iocage_05] => (item=foo)
ok: [iocage_05] => (item=bar)
TASK [Start: Start jails.] *****************************************************
ok: [iocage_05]
PLAY RECAP *********************************************************************
iocage_05 : ok=4 changed=0 unreachable=0 failed=0 skipped=9 rescued=0 ignored=0
Inventory graph
shell > ansible-inventory -i hosts --graph
@all:
|--@ungrouped:
|--@state_down:
| |--ansible-pull-syslogng-client
| |--ansible-pull-syslogng-server
| |--ansible-pull-test
|--@state_up:
| |--bar
| |--foo
| |--repos
| |--repos_devel
|--@vmm_iocage_05:
| |--bar
| |--foo
| |--repos
| |--repos_devel
List jails
shell > ssh admin@iocage_05 sudo iocage list -l
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
+======+==============================+======+=======+==========+==============+=======================+=====+===============+==========+
| None | ansible-pull-syslogng-client | off | down | pluginv2 | 15.0-RELEASE | DHCP (not running) | - | - | yes |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| None | ansible-pull-syslogng-server | off | down | pluginv2 | 15.0-RELEASE | vnet0|172.16.99.31/24 | - | - | yes |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| None | ansible-pull-test | off | down | pluginv2 | 15.0-RELEASE | DHCP (not running) | - | - | yes |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| 13 | bar | on | up | jail | 15.0-RELEASE | epair0b|172.16.99.103 | - | ansible-init | no |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| 12 | foo | on | up | jail | 15.0-RELEASE | epair0b|172.16.99.196 | - | ansible-init | no |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| 6 | repos | on | up | jail | 15.0-RELEASE | vnet0|172.16.99.21/24 | - | ansible-repos | no |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
| 7 | repos-devel | on | up | jail | 15.0-RELEASE | vnet0|172.16.99.22/24 | - | ansible-repos | no |
+------+------------------------------+------+-------+----------+--------------+-----------------------+-----+---------------+----------+
Display the test files
shell > ssh admin@iocage_05 sudo iocage exec foo "cat /tmp/ansible-hello-world.txt"
[ansible-test] Hello world!
shell > ssh admin@iocage_05 sudo iocage exec bar "cat /tmp/ansible-hello-world.txt"
[ansible-test] Hello world!