420 Role vbotka.freebsd.apache

Use case

Use iocage property host_hostname to create a jail. Use the role vbotka.freebsd.apache to configure Apache HTTP Server.

Tree

shell> tree .
.
├── ansible.cfg
├── hosts
│   ├── 04_iocage.yml
│   └── 99_constructed.yml
├── host_vars
│   ├── iocage_04
│   │   └── ansible-client-apache.yml
│   └── www-1
│       └── apache.yml
├── iocage.ini
└── pb-apache.yml

Synopsis

Requirements

Notes

  • iocage option --name provides “NAME instead of a UUID for the new jail”.

  • iocage property host_hostname provides “The hostname of the jail. Default: UUID”.

  • Make sure DHCP and dynamic DNS are configured so that host_hostname and --name resolve.

ansible.cfg

[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false
host_key_checking = false

[connection]
pipelining = true

Inventory iocage.ini

iocage_04 ansible_host=10.1.0.29

[iocage]
iocage_04

[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent

host_vars

host_vars/iocage_04/ansible-client-apache.yml
properties:
  notes: "vmm={{ inventory_hostname }} alias=www-1 class=http"
  bpf: 1
  dhcp: 1
  vnet: 1

clones_host_hostname:
  www-1:
    template: ansible_client_apache
host_vars/www-1/apache.yml
apache_install: false
apache_confd: false
apache_servername: www-1
apache_serveradmin: admin@www-1

apache_directory_blocks:
  - Directory: /usr/local/www/apache24/data/
    Includefile: usr-local-www-apache-data.conf
    Conf:
      - "DirectoryIndex index.html index.htm"
      - "Options Indexes FollowSymLinks"
      - "AllowOverride All"
      - "Require all granted"

Create and start jails

(env) > ansible-playbook vbotka.freebsd.pb_iocage_ansible_clients.yml \
                         -i iocage.ini \
                         -t clone_host_hostname -e clone_host_hostname=true \
                         -e debug=true -e debug2=true
PLAY [Create and start jails. Optionally stop and destroy jails.] **************

TASK [Get pool.] ***************************************************************
ok: [iocage_04]

TASK [Debug cmd_create debug=true] *********************************************
ok: [iocage_04] => (item=www-1 ansible_client_apache) => 
    msg: |-
        iocage create --short --template ansible_client_apache notes="vmm=iocage_04 alias=www-1 class=http" bpf=1 dhcp=1 vnet=1 host_hostname=www-1

TASK [Create clones host_hostname] *********************************************
changed: [iocage_04] => (item=www-1 ansible_client_apache)

TASK [Debug create clones host_hostname debug2=true] ***************************
ok: [iocage_04] => 
    out_create:
        changed: true
        msg: All items completed
        results:
        -   ansible_loop_var: item
            changed: true
            cmd:
            - iocage
            - create
            - --short
            - --template
            - ansible_client_apache
            - notes=vmm=iocage_04 alias=www-1 class=http
            - bpf=1
            - dhcp=1
            - vnet=1
            - host_hostname=www-1
            delta: '0:00:00.371485'
            end: '2026-02-25 00:03:13.688762'
            failed: false
            invocation:
                module_args:
                    _raw_params: null
                    _uses_shell: false
                    argv: null
                    chdir: null
                    cmd: |-
                        iocage create --short --template ansible_client_apache notes="vmm=iocage_04 alias=www-1 class=http" bpf=1 dhcp=1 vnet=1 host_hostname=www-1
                    creates: null
                    executable: null
                    expand_argument_vars: true
                    removes: null
                    stdin: null
                    stdin_add_newline: true
                    strip_empty_ends: true
            item:
                key: www-1
                value:
                    template: ansible_client_apache
            msg: ''
            rc: 0
            start: '2026-02-25 00:03:13.317277'
            stderr: ''
            stderr_lines: []
            stdout: c21bd13b successfully created!
            stdout_lines:
            - c21bd13b successfully created!
        skipped: false

TASK [Debug add fstab host_hostname debug2=true] *******************************
ok: [iocage_04] => 
    out_fstab:
        changed: false
        results: []
        skipped: true
        skipped_reason: No items in the list

TASK [Debug cmd_start debug=true] **********************************************
ok: [iocage_04] => 
    msg: |-
        iocage start c21bd13b

TASK [Start clones host_hostname] **********************************************
changed: [iocage_04]

TASK [Debug start clones host_hostname debug2=true] ****************************
ok: [iocage_04] => 
    out_start:
        changed: true
        cmd:
        - iocage
        - start
        - c21bd13b
        delta: '0:00:11.612697'
        end: '2026-02-25 00:03:25.725450'
        failed: false
        msg: ''
        rc: 0
        start: '2026-02-25 00:03:14.112753'
        stderr: No default gateway found for ipv6.
        stderr_lines:
        - No default gateway found for ipv6.
        stdout: |-
            * Starting c21bd13b
              + Started OK
              + Using devfs_ruleset: 1000 (iocage generated default)
              + Configuring VNET OK
              + Using IP options: vnet
              + Starting services OK
              + Executing poststart OK
              + DHCP Address: 10.1.0.233/24
        stdout_lines:
        - '* Starting c21bd13b'
        - '  + Started OK'
        - '  + Using devfs_ruleset: 1000 (iocage generated default)'
        - '  + Configuring VNET OK'
        - '  + Using IP options: vnet'
        - '  + Starting services OK'
        - '  + Executing poststart OK'
        - '  + DHCP Address: 10.1.0.233/24'

PLAY RECAP *********************************************************************
iocage_04                  : ok=8    changed=2    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   

Inventory hosts

The value of the iocage tag alias is used as the inventory alias. If the command iocage list is slow use the cache.

hosts/04_iocage.yml
plugin: vbotka.freebsd.iocage
host: 10.1.0.29
user: admin
cache: true
cache_plugin: ansible.builtin.jsonfile
cache_connection: /var/tmp/inventory_cache
cache_timeout: 3600
cache_prefix: iocage_04_
get_properties: true
inventory_hostname_tag: alias
hooks_results:
  - /var/db/dhclient-hook.address.epair0b
hosts/99_constructed.yml
plugin: ansible.builtin.constructed
compose:
  ansible_host: (iocage_hooks.0 == '-') | ternary(iocage_ip4, iocage_hooks.0)
  iocage_tags: dict(iocage_properties.notes | regex_findall('(\w+)=([\w\-]+)'))
  iocage_classes: iocage_properties.notes | regex_findall('class=(\w+)')
groups:
  www: "'http' in iocage_classes"
keyed_groups:
  - prefix: state
    key: iocage_state
  - prefix: vmm
    key: iocage_tags.vmm

Playbook pb-apache.yml

- name: Create Apache HTTP Server.
  hosts: www
  gather_facts: true
  remote_user: admin
  become: true

  roles:
    - vbotka.freebsd.apache

Playbook output - Create server

(env) > ansible-playbook pb-apache.yml -i hosts
PLAY [Create Apache HTTP Server.] **********************************************

TASK [Gathering Facts] *********************************************************
ok: [www-1]

TASK [Vars: Include OS vars.] **************************************************
included: vbotka.freebsd.lib for www-1

TASK [vbotka.freebsd.lib : Al_include_os_vars_path: Vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/apache/vars/defaults] ***
ok: [www-1]

TASK [vbotka.freebsd.apache : Httpd-conf: Configure parameters in /usr/local/etc/apache24/httpd.conf] ***
changed: [www-1] => (item={'regexp': 'ServerName', 'line': 'www-1'})
changed: [www-1] => (item={'regexp': 'ServerAdmin', 'line': 'admin@www-1'})
changed: [www-1] => (item={'regexp': 'ServerTokens', 'line': 'Prod'})

TASK [vbotka.freebsd.apache : Httpd-dirs: Configure directories in /usr/local/etc/apache24/Includes/] ***
changed: [www-1] => (item=/usr/local/www/apache24/data/)

TASK [vbotka.freebsd.apache : Rc-conf: Enable and Start Apache] ****************
changed: [www-1]

RUNNING HANDLER [vbotka.freebsd.apache : Enable and start vbotka.freebsd.apache] ***
changed: [www-1]

RUNNING HANDLER [vbotka.freebsd.apache : Reload vbotka.freebsd.apache] *********
ok: [www-1]

PLAY RECAP *********************************************************************
www-1                      : ok=8    changed=4    unreachable=0    failed=0    skipped=34   rescued=0    ignored=0   

Results

  • Test the configuration. Replace www-1 with an IP if it doesn’t resolve.

    (env) > ssh admin@www-1 sudo service apache24 configtest
    Performing sanity check on apache24 configuration:
    Syntax OK
    
  • Test the server is running

    (env) > ssh admin@www-1 sudo service apache24 status
    apache24 is running as pid 62481.
    
  • In a browser, open the page http://www-1/. The content should be

    It works!