-
Notifications
You must be signed in to change notification settings - Fork 2
appconfig
Templates are used in many systems, especially at scale, because it is the way to deploy the same application with subtle changes. Overlord includes a template system thanks to the Mako template engine. You can create a metadata that includes the template and with an appConfig deployment you can specify simple parameters, effectively creating something like a configuration, or in this case an appConfig.
metadata.yml:
kind: metadata
datacenters:
main:
entrypoint: !ENV '${ENTRYPOINT}'
access_token: !ENV '${TOKEN}'
deployIn:
labels:
- vm-only
metadata:
ts_auth_key: !ENV '${TS_AUTH_KEY}'
resolv.conf: |
nameserver 1.1.1.1
nameserver 1.0.0.1
timezone: !ENV '${TIMEZONE}'
loader.conf: |
nvme_load="YES"
if_bridge_load="YES"
bridgestp_load="YES"
if_wg_load="YES"
kern.racct.enable=1
ssh_key: !ENV '${SSH_KEY}'
sshd_config: |
# Ports
Port 22
# Authentication
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitRootLogin prohibit-password
PrintMotd no
# Forwarding
X11Forwarding no
AllowAgentForwarding yes
# Connection checks
ClientAliveCountMax 3
ClientAliveInterval 15
# Compression
Compression no
# Limits
LoginGraceTime 40
# Public keys
AuthorizedKeysFile /etc/ssh/authorized_keys
# SFTP
Subsystem sftp internal-sftp
sysctl.conf: |
# A bit of hardening
security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.see_jail_proc=0
kern.randompid=1
# Allow packet filtering in if_bridge(4)
net.link.bridge.pfil_member=1
net.link.bridge.pfil_bridge=1
pkg.conf: |
FreeBSD: {
url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
enabled: yes
}
appVM.appConfig: |
<%page args="appvm_use_pkgbase='0'"/>
kind: 'vmJail'
vmName: ${appName}
makejail: 'gh+DtxdF/vm-makejail'
template:
loader: 'bhyveload'
cpu: '${ncpu}'
memory: '${memory}'
network0_type: 'virtio-net'
network0_switch: 'public'
wired_memory: 'YES'
diskLayout:
driver: 'nvme'
size: '${disk}'
from:
% if appvm_use_pkgbase == "0":
type: 'components'
components:
- base.txz
- kernel.txz
osArch: amd64
osVersion: '${fbsdver}'
% else:
type: 'appjailImage'
entrypoint: 'gh+AppJail-makejails/pkgbase'
imageName: 'pkgbase'
imageArch: 'amd64'
imageTag: '${fbsdver}'
% endif
disk:
scheme: 'gpt'
partitions:
- type: 'freebsd-boot'
size: '512k'
alignment: '1m'
- type: 'freebsd-swap'
size: '${swap}'
alignment: '1m'
- type: 'freebsd-ufs'
alignment: '1m'
format:
flags: '-Uj'
bootcode:
bootcode: '/boot/pmbr'
partcode: '/boot/gptboot'
index: 1
fstab:
- device: '/dev/nda0p3'
mountpoint: '/'
type: 'ufs'
options: 'rw,sync'
dump: 1
pass: 1
- device: '/dev/nda0p2'
mountpoint: 'none'
type: 'swap'
options: 'sw'
dump: 0
pass: 0
script-environment:
- HOSTNAME: '${hostname}'
script: |
<%text filter="n">
set -xe
set -o pipefail
. "/metadata/environment"
sysrc -f /mnt/etc/rc.conf ifconfig_vtnet0="inet 192.168.8.2/24"
sysrc -f /mnt/etc/rc.conf defaultrouter="192.168.8.1"
sysrc -f /mnt/etc/rc.conf fsck_y_enable="YES"
sysrc -f /mnt/etc/rc.conf clear_tmp_enable="YES"
sysrc -f /mnt/etc/rc.conf dumpdev="NO"
sysrc -f /mnt/etc/rc.conf moused_nondefault_enable="NO"
sysrc -f /mnt/etc/rc.conf hostname="${HOSTNAME}"
if [ -f "/metadata/resolv.conf" ]; then
cp -a /metadata/resolv.conf /mnt/etc/resolv.conf
fi
if [ -f "/metadata/loader.conf" ]; then
cp /metadata/loader.conf /mnt/boot/loader.conf
fi
if [ -f "/metadata/zerotier_network" ]; then
pkg -c /mnt install -y zerotier
zerotier_network=`head -1 -- "/metadata/zerotier_network"`
cat << EOF > /mnt/etc/rc.local
while :; do
if ! /usr/local/bin/zerotier-cli join ${zerotier_network}; then
sleep 1
continue
fi
break
done
rm -f /etc/rc.local
EOF
sysrc -f /mnt/etc/rc.conf zerotier_enable="YES"
elif [ -f "/metadata/ts_auth_key" ]; then
pkg -c /mnt install -y tailscale
ts_auth_key=`head -1 -- "/metadata/ts_auth_key"`
echo "/usr/local/bin/tailscale up --accept-dns=false --auth-key=\"${ts_auth_key}\" && rm -f /etc/rc.local" > /mnt/etc/rc.local
sysrc -f /mnt/etc/rc.conf tailscaled_enable="YES"
fi
if [ -f "/metadata/timezone" ]; then
timezone=`head -1 -- "/metadata/timezone"`
ln -fs "/usr/share/zoneinfo/${timezone}" /mnt/etc/localtime
fi
if [ -f "/metadata/sshd_config" ]; then
sysrc -f /mnt/etc/rc.conf sshd_enable="YES"
cp /metadata/sshd_config /mnt/etc/ssh/sshd_config
fi
if [ -f "/metadata/ssh_key" ]; then
cp /metadata/ssh_key /mnt/etc/ssh/authorized_keys
fi
if [ -f "/metadata/sysctl.conf" ]; then
cp /metadata/sysctl.conf /mnt/etc/sysctl.conf
fi
if [ -f "/metadata/pkg.conf" ]; then
mkdir -p /mnt/usr/local/etc/pkg/repos
cp /metadata/pkg.conf /mnt/usr/local/etc/pkg/repos/Latest.conf
fi
</%text>
metadata:
- resolv.conf
- loader.conf
- timezone
- sshd_config
- ssh_key
- sysctl.conf
- pkg.conf
- ts_auth_keyapp-components.yml:
kind: appConfig
datacenters:
main:
entrypoint: !ENV '${ENTRYPOINT}'
access_token: !ENV '${TOKEN}'
deployIn:
labels:
- desktop
appName: 'vmtest001'
appFrom: 'appVM.appConfig'
appConfig:
ncpu: '2'
memory: '1G'
disk: '10G'
fbsdver: '14.2-RELEASE'
swap: '2G'
hostname: 'vmtest001'app-pkgbase.yml:
kind: appConfig
datacenters:
main:
entrypoint: !ENV '${ENTRYPOINT}'
access_token: !ENV '${TOKEN}'
deployIn:
labels:
- desktop
appName: 'vmtest002'
appFrom: 'appVM.appConfig'
appConfig:
ncpu: '2'
memory: '1G'
disk: '10G'
fbsdver: '14.2-full'
swap: '2G'
hostname: 'vmtest002'
appvm_use_pkgbase: '1'.env:
ENTRYPOINT=http://127.0.0.1:8888
TOKEN=<access token>
TS_AUTH_KEY=<tailscale auth key>
TIMEZONE=America/Caracas
SSH_KEY=<SSH public key>
The template has a few dozen lines but the appConfig is only a couple of lines and little effort to write such a thing is evident, but here's the point, you just focus on those subtle changes and nothing else.
Notice those subtle changes between each appConfig deployment. In the case of app-components.yml it is a deployment that uses FreeBSD components from the 14.2-RELEASE version and in the case of app-pkgbase.yml it uses an AppJail image tagged 14-full.
$ overlord apply -f metadata.yml
$ overlord apply -f app-components.yml
$ overlord apply -f app-pkgbase.yml
$ overlord get-info -f app-components.yml -t projects --filter-per-project
datacenter: http://127.0.0.1:8888
entrypoint: main
chain: None
labels:
- all
- desktop
- services
- vm-only
projects:
vmtest001:
state: DONE
last_log: 2025-05-02_20h35m10s
locked: False
services:
- {'name': 'vm', 'status': 0, 'jail': 'vmtest001'}
up:
operation: COMPLETED
output:
rc: 0
stdout: {'errlevel': 0, 'message': None, 'failed': []}
last_update: 1 minute and 50.25 seconds
job_id: 5
restarted: False
$ overlord get-info -f app-components.yml -t vm --filter-per-project
datacenter: http://127.0.0.1:8888
entrypoint: main
chain: None
labels:
- all
- desktop
- services
- vm-only
projects:
vmtest002:
virtual-machines:
operation: COMPLETED
output: |
md0 created
md0p1 added
md0p2 added
md0p3 added
/dev/md0p3: 8190.0MB (16773120 sectors) block size 32768, fragment size 4096
using 14 cylinder groups of 625.22MB, 20007 blks, 80128 inodes.
with soft updates
super-block backups (for fsck_ffs -b #) at:
192, 1280640, 2561088, 3841536, 5121984, 6402432, 7682880, 8963328, 10243776,
11524224, 12804672, 14085120, 15365568, 16646016
Using inode 4 in cg 0 for 67108864 byte journal
bootcode written to md0
partcode written to md0p1
ifconfig_vtnet0: -> inet 192.168.8.2/24
defaultrouter: NO -> 192.168.8.1
fsck_y_enable: NO -> YES
clear_tmp_enable: NO -> YES
dumpdev: NO -> NO
moused_nondefault_enable: YES -> NO
hostname: -> vmtest002
[vmtest002.appjail] Installing pkg-2.1.2...
[vmtest002.appjail] Extracting pkg-2.1.2: .......... done
Updating FreeBSD repository catalogue...
[vmtest002.appjail] Fetching data.pkg: .......... done
Processing entries: .......... done
FreeBSD repository update completed. 35977 packages processed.
Updating FreeBSD-base repository catalogue...
[vmtest002.appjail] Fetching data.pkg: ... done
Processing entries:
Processing entries............. done
FreeBSD-base repository update completed. 525 packages processed.
All repositories are up to date.
The following 2 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
ca_root_nss: 3.108 [FreeBSD]
tailscale: 1.82.5 [FreeBSD]
Number of packages to be installed: 2
The process will require 35 MiB more space.
11 MiB to be downloaded.
[vmtest002.appjail] [1/2] Fetching tailscale-1.82.5.pkg: .......... done
[vmtest002.appjail] [2/2] Fetching ca_root_nss-3.108.pkg: .......... done
Checking integrity... done (0 conflicting)
[vmtest002.appjail] [1/2] Installing ca_root_nss-3.108...
[vmtest002.appjail] [1/2] Extracting ca_root_nss-3.108: ....... done
[vmtest002.appjail] [2/2] Installing tailscale-1.82.5...
[vmtest002.appjail] [2/2] Extracting tailscale-1.82.5: ...... done
=====
Message from ca_root_nss-3.108:
--
FreeBSD does not, and can not warrant that the certification authorities
whose certificates are included in this package have in any way been
audited for trustworthiness or RFC 3647 compliance.
Assessment and verification of trust is the complete responsibility of
the system administrator.
This package installs symlinks to support root certificate discovery
for software that either uses other cryptographic libraries than
OpenSSL, or use OpenSSL but do not follow recommended practice.
If you prefer to do this manually, replace the following symlinks with
either an empty file or your site-local certificate bundle.
* /etc/ssl/cert.pem
* /usr/local/etc/ssl/cert.pem
* /usr/local/openssl/cert.pem
tailscaled_enable: -> YES
sshd_enable: NO -> YES
vm_list: -> vmtest002
Starting vmtest002
* found guest in /vm/vmtest002
* booting...
newfs: soft updates journaling set
[00:00:01] [ info ] [pkgbase] pkgbase (arch:amd64, tag:14-full): already up to date.
+ set -o pipefail
+ . /metadata/environment
+ export 'HOSTNAME=vmtest002'
+ sysrc -f /mnt/etc/rc.conf 'ifconfig_vtnet0=inet 192.168.8.2/24'
+ sysrc -f /mnt/etc/rc.conf 'defaultrouter=192.168.8.1'
+ sysrc -f /mnt/etc/rc.conf 'fsck_y_enable=YES'
+ sysrc -f /mnt/etc/rc.conf 'clear_tmp_enable=YES'
+ sysrc -f /mnt/etc/rc.conf 'dumpdev=NO'
+ sysrc -f /mnt/etc/rc.conf 'moused_nondefault_enable=NO'
+ sysrc -f /mnt/etc/rc.conf 'hostname=vmtest002'
+ [ -f /metadata/resolv.conf ]
+ cp -a /metadata/resolv.conf /mnt/etc/resolv.conf
+ [ -f /metadata/loader.conf ]
+ cp /metadata/loader.conf /mnt/boot/loader.conf
+ [ -f /metadata/zerotier_network ]
+ [ -f /metadata/ts_auth_key ]
+ pkg -c /mnt install -y tailscale
certctl: Scanning /usr/share/certs/untrusted for certificates...
certctl: Scanning /usr/share/certs/trusted for certificates...
certctl: Scanning /usr/local/share/certs for certificates...
+ head -1 -- /metadata/ts_auth_key
+ ts_auth_key=[REDACTED]
+ echo '/usr/local/bin/tailscale up --accept-dns=false --auth-key="[REDACTED]" && rm -f /etc/rc.local'
+ sysrc -f /mnt/etc/rc.conf 'tailscaled_enable=YES'
+ [ -f /metadata/timezone ]
+ head -1 -- /metadata/timezone
+ timezone=America/Caracas
+ ln -fs /usr/share/zoneinfo/America/Caracas /mnt/etc/localtime
+ [ -f /metadata/sshd_config ]
+ sysrc -f /mnt/etc/rc.conf 'sshd_enable=YES'
+ cp /metadata/sshd_config /mnt/etc/ssh/sshd_config
+ [ -f /metadata/ssh_key ]
+ cp /metadata/ssh_key /mnt/etc/ssh/authorized_keys
+ [ -f /metadata/sysctl.conf ]
+ cp /metadata/sysctl.conf /mnt/etc/sysctl.conf
+ [ -f /metadata/pkg.conf ]
+ mkdir -p /mnt/usr/local/etc/pkg/repos
+ cp /metadata/pkg.conf /mnt/usr/local/etc/pkg/repos/Latest.conf
last_update: 12 minutes and 34.79 seconds
job_id: 3
$ overlord get-info -f app-pkgbase.yml -t projects --filter-per-project
datacenter: http://127.0.0.1:8888
entrypoint: main
chain: None
labels:
- all
- desktop
- services
- vm-only
projects:
vmtest002:
state: DONE
last_log: 2025-05-02_20h23m33s
locked: False
services:
- {'name': 'vm', 'status': 0, 'jail': 'vmtest002'}
up:
operation: COMPLETED
output:
rc: 0
stdout: {'errlevel': 0, 'message': None, 'failed': []}
last_update: 13 minutes and 21.73 seconds
job_id: 3
restarted: False
$ overlord get-info -f app-pkgbase.yml -t vm --filter-per-project
datacenter: http://127.0.0.1:8888
entrypoint: main
chain: None
labels:
- all
- desktop
- services
- vm-only
projects:
vmtest002:
virtual-machines:
operation: COMPLETED
output: |
md0 created
md0p1 added
md0p2 added
md0p3 added
/dev/md0p3: 8190.0MB (16773120 sectors) block size 32768, fragment size 4096
using 14 cylinder groups of 625.22MB, 20007 blks, 80128 inodes.
with soft updates
super-block backups (for fsck_ffs -b #) at:
192, 1280640, 2561088, 3841536, 5121984, 6402432, 7682880, 8963328, 10243776,
11524224, 12804672, 14085120, 15365568, 16646016
Using inode 4 in cg 0 for 67108864 byte journal
bootcode written to md0
partcode written to md0p1
ifconfig_vtnet0: -> inet 192.168.8.2/24
defaultrouter: NO -> 192.168.8.1
fsck_y_enable: NO -> YES
clear_tmp_enable: NO -> YES
dumpdev: NO -> NO
moused_nondefault_enable: YES -> NO
hostname: -> vmtest002
[vmtest002.appjail] Installing pkg-2.1.2...
[vmtest002.appjail] Extracting pkg-2.1.2: .......... done
Updating FreeBSD repository catalogue...
[vmtest002.appjail] Fetching data.pkg: .......... done
Processing entries: .......... done
FreeBSD repository update completed. 35977 packages processed.
Updating FreeBSD-base repository catalogue...
[vmtest002.appjail] Fetching data.pkg: ... done
Processing entries:
Processing entries............. done
FreeBSD-base repository update completed. 525 packages processed.
All repositories are up to date.
The following 2 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
ca_root_nss: 3.108 [FreeBSD]
tailscale: 1.82.5 [FreeBSD]
Number of packages to be installed: 2
The process will require 35 MiB more space.
11 MiB to be downloaded.
[vmtest002.appjail] [1/2] Fetching tailscale-1.82.5.pkg: .......... done
[vmtest002.appjail] [2/2] Fetching ca_root_nss-3.108.pkg: .......... done
Checking integrity... done (0 conflicting)
[vmtest002.appjail] [1/2] Installing ca_root_nss-3.108...
[vmtest002.appjail] [1/2] Extracting ca_root_nss-3.108: ....... done
[vmtest002.appjail] [2/2] Installing tailscale-1.82.5...
[vmtest002.appjail] [2/2] Extracting tailscale-1.82.5: ...... done
=====
Message from ca_root_nss-3.108:
--
FreeBSD does not, and can not warrant that the certification authorities
whose certificates are included in this package have in any way been
audited for trustworthiness or RFC 3647 compliance.
Assessment and verification of trust is the complete responsibility of
the system administrator.
This package installs symlinks to support root certificate discovery
for software that either uses other cryptographic libraries than
OpenSSL, or use OpenSSL but do not follow recommended practice.
If you prefer to do this manually, replace the following symlinks with
either an empty file or your site-local certificate bundle.
* /etc/ssl/cert.pem
* /usr/local/etc/ssl/cert.pem
* /usr/local/openssl/cert.pem
tailscaled_enable: -> YES
sshd_enable: NO -> YES
vm_list: -> vmtest002
Starting vmtest002
* found guest in /vm/vmtest002
* booting...
newfs: soft updates journaling set
[00:00:01] [ info ] [pkgbase] pkgbase (arch:amd64, tag:14-full): already up to date.
+ set -o pipefail
+ . /metadata/environment
+ export 'HOSTNAME=vmtest002'
+ sysrc -f /mnt/etc/rc.conf 'ifconfig_vtnet0=inet 192.168.8.2/24'
+ sysrc -f /mnt/etc/rc.conf 'defaultrouter=192.168.8.1'
+ sysrc -f /mnt/etc/rc.conf 'fsck_y_enable=YES'
+ sysrc -f /mnt/etc/rc.conf 'clear_tmp_enable=YES'
+ sysrc -f /mnt/etc/rc.conf 'dumpdev=NO'
+ sysrc -f /mnt/etc/rc.conf 'moused_nondefault_enable=NO'
+ sysrc -f /mnt/etc/rc.conf 'hostname=vmtest002'
+ [ -f /metadata/resolv.conf ]
+ cp -a /metadata/resolv.conf /mnt/etc/resolv.conf
+ [ -f /metadata/loader.conf ]
+ cp /metadata/loader.conf /mnt/boot/loader.conf
+ [ -f /metadata/zerotier_network ]
+ [ -f /metadata/ts_auth_key ]
+ pkg -c /mnt install -y tailscale
certctl: Scanning /usr/share/certs/untrusted for certificates...
certctl: Scanning /usr/share/certs/trusted for certificates...
certctl: Scanning /usr/local/share/certs for certificates...
+ head -1 -- /metadata/ts_auth_key
+ ts_auth_key=[REDACTED]
+ echo '/usr/local/bin/tailscale up --accept-dns=false --auth-key="[REDACTED]" && rm -f /etc/rc.local'
+ sysrc -f /mnt/etc/rc.conf 'tailscaled_enable=YES'
+ [ -f /metadata/timezone ]
+ head -1 -- /metadata/timezone
+ timezone=America/Caracas
+ ln -fs /usr/share/zoneinfo/America/Caracas /mnt/etc/localtime
+ [ -f /metadata/sshd_config ]
+ sysrc -f /mnt/etc/rc.conf 'sshd_enable=YES'
+ cp /metadata/sshd_config /mnt/etc/ssh/sshd_config
+ [ -f /metadata/ssh_key ]
+ cp /metadata/ssh_key /mnt/etc/ssh/authorized_keys
+ [ -f /metadata/sysctl.conf ]
+ cp /metadata/sysctl.conf /mnt/etc/sysctl.conf
+ [ -f /metadata/pkg.conf ]
+ mkdir -p /mnt/usr/local/etc/pkg/repos
+ cp /metadata/pkg.conf /mnt/usr/local/etc/pkg/repos/Latest.conf
last_update: 10 minutes and 41.07 seconds
job_id: 3
$ tailscale status
...
100.103.230.7 vmtest001 [REDACTED]@ freebsd -
100.115.122.94 vmtest002 [REDACTED]@ freebsd -
$ ssh root@100.103.230.7 freebsd-version
The authenticity of host '100.103.230.7 (100.103.230.7)' can't be established.
ED25519 key fingerprint is SHA256:YcOzEGoc2Gcln6ovJ+ea/13zquuNOciGSMXKMdXfRgA.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '100.103.230.7' (ED25519) to the list of known hosts.
14.2-RELEASE
$ ssh root@100.115.122.94 freebsd-version
The authenticity of host '100.115.122.94 (100.115.122.94)' can't be established.
ED25519 key fingerprint is SHA256:2UW4e2O3hPCDZhTz1UwF323KvAeZuJPHvK1I7gRha+Y.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '100.115.122.94' (ED25519) to the list of known hosts.
14.2-RELEASEAn interesting fact about appConfig is that although you deploy the template in multiple chains, only the first matching one is used. Obviously, this is for redundancy in case a chain is down.