205 Create Ansible client templates v2

Extending example 202 Create Ansible client templates and clone DHCP Ansible client jails.

Use case

Create template ansible_client at 3 iocage hosts.

Tree

shell> tree .
.
├── ansible.cfg
├── files
│   └── pk_admins.txt
├── host_vars
│   ├── iocage_01
│   │   └── iocage.yml
│   ├── iocage_02
│   │   └── iocage.yml
│   └── iocage_03
│       └── iocage.yml
├── iocage-hosts.ini
├── pb-iocage-template -> ../../../../playbooks/pb-iocage-template
└── pb-iocage-template.yml -> ../../../../playbooks/pb-iocage-template.yml

Synopsis

  • On two iocage hosts:

    • iocage_01

    • iocage_02

    • iocage_03

    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

    • configure dhclient hooks.

Requirements

Configuration ansible.cfg

[defaults]
gathering = explicit
callback_result_format = 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"

templates:
  ansible_client:
    release: 13.4-RELEASE
    properties:
      ip4_addr: 'vnet0|10.1.0.198/24'
    dhclient: "{{ act_dhclient | dict2items }}"
    rcconf: "{{ act_rcconf | dict2items }}"

# ansible client template defaults
act_pkg:
  - security/sudo
  - lang/python39
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

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"

templates:
  ansible_client:
    release: 14.1-RELEASE
    properties:
      ip4_addr: 'em0|10.1.0.199/24'
    dhclient: "{{ act_dhclient | dict2items }}"
    rcconf: "{{ act_rcconf | dict2items }}"

# ansible client template defaults
act_pkg:
  - security/sudo
  - lang/python311
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

host_vars/iocage_03/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"

templates:
  ansible_client:
    release: 14.2-RELEASE
    properties:
      ip4_addr: 'ue0|10.1.0.197/24'
    dhclient: "{{ act_dhclient | dict2items }}"
    rcconf: "{{ act_rcconf | dict2items }}"

# ansible client template defaults
act_pkg:
  - security/sudo
  - lang/python311
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

Warning

  • The user act_user must exist on the iocage host. Otherwise, the module ansible.posix.authorized_key will crash. See pb-iocage-template/pk.yml

  • The file files/pk_admins.txt was sanitized. Fit the public keys to your needs

    shell> cat files/pk_admins.txt
    ssh-rsa <sanitized> admin@controller
    

Inventory iocage-hosts.ini

iocage_01 ansible_host=10.1.0.18
iocage_02 ansible_host=10.1.0.73
iocage_03 ansible_host=10.1.0.17

[iocage]
iocage_01
iocage_02
iocage_03

[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]
      ansible.builtin.import_tasks: pb-iocage-template/setup.yml

    - name: Create jails
      tags: create
      ansible.builtin.import_tasks: pb-iocage-template/create.yml

    - name: Start jails
      tags: start
      ansible.builtin.import_tasks: pb-iocage-template/start.yml

    - name: Install packages
      when: act_pkg | length > 0
      tags: pkg
      ansible.builtin.import_tasks: pb-iocage-template/pkg.yml

    - name: Create user
      when: act_user | length > 0
      tags: user
      ansible.builtin.import_tasks: pb-iocage-template/user.yml

    - name: Configure public keys
      when: act_pk | length > 0
      tags: pk
      ansible.builtin.import_tasks: pb-iocage-template/pk.yml

    - name: Configure sudo
      when: act_sudo | bool
      tags: sudo
      ansible.builtin.import_tasks: pb-iocage-template/sudo.yml

    - name: Configure dhclient
      when: act_dhclient | length > 0
      tags: dhclient
      ansible.builtin.import_tasks: pb-iocage-template/dhclient.yml

    - name: Configure /etc/rc.conf
      when: act_rcconf | length > 0
      tags: rcconf
      ansible.builtin.import_tasks: pb-iocage-template/rc_conf.yml

    - name: Stop jails
      tags: stop
      ansible.builtin.import_tasks: pb-iocage-template/stop.yml

    - name: Convert jails to templates
      tags: template
      ansible.builtin.import_tasks: pb-iocage-template/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       |
+------+----------------+------+-------+----------+-----------------+-------------------+-----+----------+----------+

List templates at iocage_03

[iocage_03]# iocage list -lt
+------+----------------+------+-------+----------+--------------+-------------------+-----+----------+----------+
| JID  |      NAME      | BOOT | STATE |   TYPE   |   RELEASE    |        IP4        | IP6 | TEMPLATE | BASEJAIL |
+======+================+======+=======+==========+==============+===================+=====+==========+==========+
| None | ansible_client | off  | down  | template | 14.2-RELEASE | ue0|10.1.0.197/24 | -   | -        | no       |
+------+----------------+------+-------+----------+--------------+-------------------+-----+----------+----------+