Restructured Documentation
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s

This commit is contained in:
2026-09-05 14:08:43 -06:00
parent c4bd235eba
commit 289769a601
281 changed files with 5403 additions and 3563 deletions
@@ -0,0 +1,220 @@
---
tags:
- Ansible
- AWX
- Kerberos
- Automation
---
## Purpose
Configure the AWX execution environment and workflow used to authenticate to domain-joined Windows targets with Kerberos. The AWX Operator deployment and Windows remote-management prerequisites must already be in place.
## Kerberos Implementation
You may find that you need to be able to run playbooks on domain-joined Windows devices using Kerberos. You need to go through some extra steps to set this up after you have successfully fully deployed AWX Operator into Kubernetes.
### Configure Windows Devices
You will need to prepare the Windows devices to allow them to be remotely controlled by Ansible playbooks. Run the following powershell script on all of the devices that will be managed by the Ansible AWX environment.
- [WinRM Prerequisite Setup Script](<../../Identity and Certificates/Windows/Enable WinRM over HTTPS.md>)
### Create an AWX Instance Group
At this point, we need to make an "Instance Group" for the AWX Execution Environments that will use both a Keytab file and custom DNS servers defined by configmap files created below. Reference information was found [here](https://github.com/kurokobo/awx-on-k3s/blob/main/tips/use-kerberos.md#create-container-group). This group allows for persistence across playbooks/templates, so that if you establish a Kerberos authentication in one playbook, it will persist through the entire job's workflow.
Create the following files in the `/awx` folder on the AWX Operator server you deployed earlier when setting up the Kubernetes Cluster and deploying AWX Operator into it so we can later mount them into the new Execution Environment we will be building.
=== "Custom DNS Records"
```yaml title="/awx/custom_dns_records.yml"
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-dns
namespace: awx
data:
custom-hosts: |
192.168.3.25 LAB-DC-01.bunny-lab.io LAB-DC-01
192.168.3.26 LAB-DC-02.bunny-lab.io LAB-DC-02
192.168.3.4 VIRT-NODE-01.bunny-lab.io VIRT-NODE-01
192.168.3.5 BUNNY-NODE-02.bunny-lab.io BUNNY-NODE-02
```
=== "Kerberos Keytab File"
```ini title="/awx/krb5.conf"
[libdefaults]
default_realm = BUNNY-LAB.IO
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
BUNNY-LAB.IO = {
kdc = 192.168.3.25
kdc = 192.168.3.26
admin_server = 192.168.3.25
}
[domain_realm]
192.168.3.25 = BUNNY-LAB.IO
192.168.3.26 = BUNNY-LAB.IO
.bunny-lab.io = BUNNY-LAB.IO
bunny-lab.io = BUNNY-LAB.IO
```
Then we apply these configmaps to the AWX namespace with the following commands:
```sh
cd /awx
kubectl -n awx create configmap awx-kerberos-config --from-file=/awx/krb5.conf
kubectl apply -f custom_dns_records.yml
```
- Open AWX UI and click on "**Instance Groups**" under the "**Administration**" section, then press "**Add > Add container group**".
- Enter a descriptive name as you like (e.g. `Kerberos`) and click the toggle "**Customize Pod Specification**".
- Put the following YAML string in "**Custom pod spec**" then press the "**Save**" button
```yaml title="Custom Pod Spec"
apiVersion: v1
kind: Pod
metadata:
namespace: awx
spec:
serviceAccountName: default
automountServiceAccountToken: false
initContainers:
- name: init-hosts
image: busybox
command:
- sh
- '-c'
- cat /etc/custom-dns/custom-hosts >> /etc/hosts
volumeMounts:
- name: custom-dns
mountPath: /etc/custom-dns
containers:
- image: quay.io/ansible/awx-ee:latest
name: worker
args:
- ansible-runner
- worker
- '--private-data-dir=/runner'
resources:
requests:
cpu: 250m
memory: 100Mi
volumeMounts:
- name: awx-kerberos-volume
mountPath: /etc/krb5.conf
subPath: krb5.conf
volumes:
- name: awx-kerberos-volume
configMap:
name: awx-kerberos-config
- name: custom-dns
configMap:
name: custom-dns
```
### Job Template and Inventory Examples
At this point, you need to adjust your exist Job Template(s) that need to communicate via Kerberos to domain-joined Windows devices to use the "Instance Group" of "**Kerberos**" while keeping the same Execution Environment you have been using up until this point. This will change the Execution Environment to include the Kerberos Keytab file in the EE at playbook runtime. When the playbook has completed running, (or if you are chain-loading multiple playbooks in a workflow job template), it will cease to exist. The kerberos keytab data will be regenerated at the next runtime.
Also add the following variables to the job template you have associated with the playbook below:
```yaml
---
kerberos_user: nicole.rappe@BUNNY-LAB.IO
kerberos_password: <DomainPassword>
```
You will want to ensure your inventory file is configured to use Kerberos Authentication as well, so the following example is a starting point:
```ini
virt-node-01 ansible_host=virt-node-01.bunny-lab.io
bunny-node-02 ansible_host=bunny-node-02.bunny-lab.io
[virtualizationHosts]
virt-node-01
bunny-node-02
[virtualizationHosts:vars]
ansible_connection=winrm
ansible_port=5986
ansible_winrm_transport=kerberos
ansible_winrm_scheme=https
ansible_winrm_server_cert_validation=ignore
#kerberos_user=nicole.rappe@BUNNY-LAB.IO #Optional, if you define this in the Job Template, it is not necessary here.
#kerberos_password=<DomainPassword> #Optional, if you define this in the Job Template, it is not necessary here.
```
!!! failure "Usage of Fully-Quality Domain Names"
It is **critical** that you define Kerberos-authenticated devices with fully qualified domain names. This is just something I found out from 4+ hours of troubleshooting. If the device is Linux or you are using NTLM authentication instead of Kerberos authentication, you can skip this warning. If you do not define the inventory using FQDNs, it will fail to run the commands against the targeted device(s).
In this example, the host is defined via FQDN: `virt-node-01 ansible_host=virt-node-01.bunny-lab.io`
### Kerberos Connection Playbook
At this point, you need a playbook that you can run in a Workflow Job Template (to keep things modular and simplified) to establish a connection to an Active Directory Domain Controller via Kerberos before running additional playbooks/templates against the actual devices.
You can visualize the connection workflow below:
```mermaid
graph LR
A[Update AWX Project] --> B[Update Project Inventory]
B --> C[Establish Kerberos Connection]
C --> D[Run Playbook against Windows Device]
```
The following playbook is an example pulled from https://git.bunny-lab.io
!!! note "Playbook Redundancies"
I have several areas where I could optimize this playbook and remove redundancies. I just have not had enough time to iterate through it deeply-enough to narrow down exact things I can remove, so for now, it will remain as-is, since it functions as-expected with the example below.
```yaml title="Establish_Kerberos_Connection.yml"
---
- name: Generate Kerberos Ticket to Communicate with Domain-Joined Windows Devices
hosts: localhost
vars:
kerberos_password: "{{ lookup('env', 'KERBEROS_PASSWORD') }}" # Alternatively, you can set this as an environment variable
# BE SURE TO PASS "kerberos_user: nicole.rappe@BUNNY-LAB.IO" and "kerberos_password: <domain_admin_password>" to the template variables when running this playbook in a template.
tasks:
- name: Generate the keytab file
ansible.builtin.shell: |
ktutil <<EOF
addent -password -p {{ kerberos_user }} -k 1 -e aes256-cts
{{ kerberos_password }}
wkt /tmp/krb5.keytab
quit
EOF
environment:
KRB5_CONFIG: /etc/krb5.conf
register: generate_keytab_result
- name: Ensure keytab file was generated successfully
fail:
msg: "Failed to generate keytab file"
when: generate_keytab_result.rc != 0
- name: Keytab successfully generated
ansible.builtin.debug:
msg: "Keytab successfully generated at /tmp/krb5.keytab"
when: generate_keytab_result.rc == 0
- name: Acquire Kerberos ticket using keytab
ansible.builtin.shell: |
kinit -kt /tmp/krb5.keytab {{ kerberos_user }}
environment:
KRB5_CONFIG: /etc/krb5.conf
register: kinit_result
- name: Ensure Kerberos ticket was acquired successfully
fail:
msg: "Failed to acquire Kerberos ticket"
when: kinit_result.rc != 0
- name: Kerberos ticket successfully acquired
ansible.builtin.debug:
msg: "Kerberos ticket successfully acquired for user {{ kerberos_user }}"
when: kinit_result.rc == 0
```
## Related Documentation
- [Related AWX Documentation](<../../../reference/Automation/AWX/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,79 @@
---
tags:
- Ansible
- AWX
- Gitea
- Automation
---
## Purpose
Once AWX is deployed, you will want to connect Gitea at https://git.bunny-lab.io. The reason for this is so we can pull in our playbooks, inventories, and templates automatically into AWX, making it more stateless overall and more resilient to potential failures of either AWX or the underlying Kubernetes Cluster hosting it.
## Obtain Gitea Token
You already have this documented in Vaultwarden's password notes for awx.bunny-lab.io, but in case it gets lost, go to the [Gitea Token Page](https://git.bunny-lab.io/user/settings/applications) to set up an application token with read-only access for AWX, with a descriptive name.
## Create Gitea Credentials
Before you make move on and make the project, you need to associate the Gitea token with an AWX "Credential". Navigate to **Resources > Credentials > Add**
| **Field** | **Value** |
| :--- | :--- |
| Credential Name | `git.bunny-lab.io` |
| Description | `Gitea` |
| Organization | `Default` *(Click the Magnifying Lens)* |
| Credential Type | `Source Control` |
| Username | `Gitea Username` *(e.g. `nicole`)* |
| Password | `<Gitea Token>` |
## Create an AWX Project
In order to link AWX to Gitea, you have to connect the two of them together with an AWX "Project". Navigate to **Resources > Projects > Add**
**Project Variables**:
| **Field** | **Value** |
| :--- | :--- |
| Project Name | `Bunny-Lab` |
| Description | `Homelab Environment` |
| Organization | `Default` |
| Execution Environment | `AWX EE (latest)` *(Click the Magnifying Lens)* |
| Source Control Type | `Git` |
**Gitea-specific Variables**:
| **Field** | **Value** |
| :--- | :--- |
| Source Control URL | `https://git.bunny-lab.io/GitOps/awx.bunny-lab.io.git` |
| Source Control Branch/Tag/Commit | `main` |
| Source Control Credential | `git.bunny-lab.io` *(Click the Magnifying Lens)* |
## Add Playbooks
AWX automatically imports any playbooks it finds from the project, and makes them available for templates operating within the same project-space. (e.g. "Bunny-Lab"). This means no special configuration is needed for the playbooks.
## Create an Inventory
You will want to associate an inventory with the Gitea project now. Navigate to **Resources > Inventories > Add**
| **Field** | **Value** |
| :--- | :--- |
| Inventory Name | `Homelab` |
| Description | `Homelab Inventory` |
| Organization | `Default` |
### Add Gitea Inventory Source
Now you will want to connect this inventory to the inventory file(s) hosted in the aforementioned Gitea repository. Navigate to **Resources > Inventories > Homelab > Sources > Add**
| **Field** | **Value** |
| :--- | :--- |
| Source Name | `git.bunny-lab.io` |
| Description | `Gitea` |
| Execution Environment | `AWX EE (latest)` *(Click the Magnifying Lens)* |
| Source | `Sourced from a Project` |
| Project | `Bunny-Lab` |
| Inventory File | `inventories/homelab.ini` |
!!! info "Overwriting Existing Inventory Data"
You want to make sure that the checkboxes for "**Overwrite**" and "**Overwrite Variables**" are checked. This ensures that if devices and/or group variables are removed from the inventory file in Gitea, they will also be removed from the inventory inside AWX.
## Webhooks
Optionally, set up webhooks in Gitea to trigger inventory updates in AWX upon changes in the repository. This section is not documented yet, but will eventually be documented.
## Related Documentation
- [Related AWX Documentation](<../../../reference/Automation/AWX/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,76 @@
---
tags:
- Ansible
- AWX
- Automation
---
## Purpose
This document records the procedure for repair upgrades beyond awx operator 2.10.0. Follow the environment assumptions and commands below.
## Upgrading from 2.10.0 to 2.19.1+
There is a known issue with upgrading / install AWX Operator beyond version 2.10.0, because of how the PostgreSQL database upgrades from 13.0 to 15.0, and has changed permissions. The following workflow will help get past that and adjust the permissions in such a way that allows the upgrade to proceed successfully. If this is a clean installation, you can also perform this step if the fresh install of 2.19.1 is not working yet. (It wont work out of the box because of this bug). `The developers of AWX seem to just not care about this issue, and have not implemented an official fix themselves at this time).
### Create a Temporary Pod to Adjust Permissions
We need to create a pod that will mount the PostgreSQL PVC, make changes to permissions, then destroy the v15.0 pod to have the AWX Operator automatically regenerate it.
```yaml title="/awx/temp-pod.yml"
apiVersion: v1
kind: Pod
metadata:
name: temp-pod
namespace: awx
spec:
containers:
- name: temp-container
image: busybox
command: ['sh', '-c', 'sleep 3600']
volumeMounts:
- mountPath: /var/lib/pgsql/data
name: postgres-data
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: postgres-15-awx-postgres-15-0
restartPolicy: Never
```
```sh
# Deploy Temporary Pod
kubectl apply -f /awx/temp-pod.yaml
# Open a Shell in the Temporary Pod
kubectl exec -it temp-pod -n awx -- sh
# Adjust Permissions of the PostgreSQL 15.0 Database Folder
chown -R 26:root /var/lib/pgsql/data
exit
# Delete the Temporary Pod
kubectl delete pod temp-pod -n awx
# Delete the Crashlooped PostgreSQL 15.0 Pod to Regenerate It
kubectl delete pod awx-postgres-15-0 -n awx
# Track the Migration
kubectl get pods -n awx
kubectl logs -n awx awx-postgres-15-0
```
!!! warning "Be Patient"
This upgrade may take a few minutes depending on the speed of the node it is running on. Be patient and wait until the output looks something similar to this:
```text
root@awx:/awx# kubectl get pods -n awx
NAME READY STATUS RESTARTS AGE
awx-migration-24.6.1-bh5vb 0/1 Completed 0 9m55s
awx-operator-controller-manager-745b55d94b-2dhvx 2/2 Running 0 25m
awx-postgres-15-0 1/1 Running 0 12m
awx-task-7946b46dd6-7z9jm 4/4 Running 0 10m
awx-web-9497647b4-s4gmj 3/3 Running 0 10m
```
If you see a migration pod, like seen in the above example, you can feel free to delete it with the following command: `kubectl delete pod awx-migration-24.6.1-bh5vb -n awx`.
## Related Documentation
- [Related AWX Documentation](<../../../reference/Automation/AWX/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,90 @@
---
tags:
- Gitea
- Docker
- GitOps
---
## Purpose
Configure the Docker-based Gitea runner and repository workflow described in the May 2025 GitOps experiment. The example synchronizes repository files into a bind-mounted destination and sends an ntfy notification.
!!! info "Dated Docker Runner Example"
This is the configuration from the May 2025 runner experiment. Its Docker execution model and destination mounts differ from the Zensical host-runner workflow.
## Deploy the Docker Runner
When it comes to deploying a runner, (*assuming you want to use a docker-based runner*) it has a few simple things that need to be configured, the `docker-compose.yml` and the `.env` files. These tell the runner to reach out to Gitea server to register the runner with the given repository that you generated a registration token on.
```yaml title="docker-compose.yml"
version: "3.8"
services:
app:
image: docker.io/gitea/act_runner:latest
environment:
CONFIG_FILE: /config.yaml
GITEA_INSTANCE_URL: "${INSTANCE_URL}"
GITEA_RUNNER_REGISTRATION_TOKEN: "${REGISTRATION_TOKEN}"
GITEA_RUNNER_NAME: "${RUNNER_NAME}"
GITEA_RUNNER_LABELS: "${RUNNER_NAME}" # This can be anything, and is referenced by the workflow task(s) later.
volumes:
- /srv/containers/gitea-runner-mkdocs/config.yaml:/config.yaml # You have to manually make this file before you start the container
- /srv/containers/material-mkdocs/docs/docs:/Gitops_Destination # This is where the repository data will be copied to
```
```sh title=".env"
INSTANCE_URL=https://git.bunny-lab.io
RUNNER_NAME=gitea-runner-mkdocs
REGISTRATION_TOKEN=<Generated Here: https://git.bunny-lab.io/bunny-lab/docs/settings/actions/runners>
```
### Creating the `config.yaml`
The oddball thing about the way that I configured the Gitea Act Runner was telling it to run the container in "host mode" which tells it to run the tasks / workflows directly on the container itself instead of spinning up an instanced container (referred to as "*Docker-in-Docker*"). This keeps things simpler, but requires us to add a line to the `config.yaml` located at `/srv/containers/gitea-runner-mkdocs/config.yaml`. You can use your preferred text editor to add the following to the file's contents. This tells the runner to use itself for the tasks instead of an instanced docker container.
```yaml title="/srv/containers/gitea-runner-mkdocs/config.yaml"
container_engine: ""
```
!!! info "Quick Config Command"
```sh
mkdir -p /srv/containers/gitea-runner-mkdocs
echo 'container_engine: ""' > "/srv/containers/gitea-runner-mkdocs/config.yaml"
```
### Runner Workflow Task Files
When it comes to telling the runner what to do and how to do it, you create what are called runner "**Workflows**". These files reside within `<RepoRoot>/.gitea/workflows` and are `.yaml` format. If you have any familiarity with Ansible, the similarities are staggaring. You can have multiple workflows for one repository, with different flows that fire-off on different runners. An example of the flow used to replace Git-Repo-Updater's functionality can be seen below.
In the workflow below, it spins up a runner within the Alpine Linux environment that the `docker.io/gitea/act_runner:latest` uses, then installs NodeJS, Git, and Rsync for the core functionality that mirrors Git-Repo-Updater:
```yaml title=".gitea/workflows/gitops-automatic-deployment.yml"
name: GitOps Automatic Deployment
on:
push:
branches: [ main ]
jobs:
GitOps Automatic Deployment:
runs-on: gitea-runner-mkdocs
steps:
- name: Install Node.js, git, rsync, and curl
run: |
apk add --no-cache nodejs npm git rsync curl
- name: Checkout Repository
uses: actions/checkout@v3
- name: Copy Repository Data to Production Server
run: |
rsync -a --delete --exclude='.git/' --exclude='.gitea/' . /Gitops_Destination/
- name: Notify via NTFY
run: |
curl -d "https://docs.bunny-lab.io - Workflow Completed" https://ntfy.bunny-lab.io/gitea-runners
```
!!! note "`runs-on` Variable"
In this example workflow file, we are targeting the previously-mentioned `gitea-runner-mkdocs` runner, which we gave that "label" in the docker-compose.yaml file's `GITEA_RUNNER_LABELS` variable. You can name these labels whatever you want, as a way of organizing which runners run which workflows associated with a repository when changes are made to the repository.
## Related Documentation
- [Related Gitea Workflows](<../../../reference/Automation/Gitea Configuration Delivery.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,147 @@
---
tags:
- Gitea
- Zensical
- GitOps
---
## Purpose
Install and register the host-based Gitea Actions runner that synchronizes this documentation repository into `/srv/zensical/docs`. The Zensical account, watchdog service, and destination directory must already exist from the Zensical deployment.
## Install the Host Runner
Now is time for the arguably most-important stage of deployment, which is setting up a [Gitea Act Runner](https://docs.gitea.com/usage/actions/act-runner). This is how document changes in a Gitea repository will propagate automatically into Zensical's `/srv/zensical/docs` folder.
```sh
# Install Dependencies
sudo apt install -y nodejs npm git rsync curl
# Create dedicated Gitea runner service account
sudo useradd --system --create-home --home /var/lib/gitea_runner --shell /usr/sbin/nologin gitearunner || true
# Allow the runner to write documentation changes
sudo usermod -aG zensical gitearunner
# Allow the runner to start and stop Zensical Watchdog Service
sudo tee /etc/sudoers.d/gitearunner-systemctl > /dev/null <<'EOF'
gitearunner ALL=NOPASSWD: /usr/bin/systemctl start zensical-watchdog.service, /usr/bin/systemctl stop zensical-watchdog.service
EOF
sudo chmod 440 /etc/sudoers.d/gitearunner-systemctl
sudo chown root:root /etc/sudoers.d/gitearunner-systemctl
sudo visudo -c
# Download Newest Gitea Runner Binary (https://gitea.com/gitea/act_runner/releases)
cd /tmp
wget https://gitea.com/gitea/act_runner/releases/download/v0.2.13/act_runner-0.2.13-linux-amd64
sudo install -m 0755 act_runner-0.2.13-linux-amd64 /usr/local/bin/gitea_runner
gitea_runner --version
# Generate Gitea Runner Configuration
sudo mkdir -p /etc/gitea_runner
sudo chown gitearunner:gitearunner /etc/gitea_runner
sudo -u gitearunner gitea_runner generate-config > /etc/gitea_runner/config.yaml
```
### Configure Registration Token
- Navigate to: "**<Gitea Repo> > Settings > Actions > Runners**"
- If you don't see this, it needs to be enabled. Navigate to: "**<Gitea Repo> > Settings > "Enable Repository Actions: Enabled" > Update Settings**"
- Click the "**Create New Runner**" button on the top-right of the page and copy the registration token somewhere temporarily.
- Navigate back to the GuestVM running Zensical and run the following commands.
```sh
# Start Token Registration Process
sudo -u gitearunner env HOME=/var/lib/gitea_runner /usr/local/bin/gitea_runner register --config /etc/gitea_runner/config.yaml
# Gitea Instance URL: https://git.bunny-lab.io
# Gitea Runner Token: <Gitea-Runner-Token>
# Runner Name: zensical-docs-runner
# Move Runner Config to Correct Location & Configure Permissions
sudo mv /tmp/.runner /var/lib/gitea_runner/.runner
sudo chown gitearunner:gitearunner /var/lib/gitea_runner/.runner
sudo chmod 600 /var/lib/gitea_runner/.runner
```
### Create Service
Now we need to configure the Gitea runner to start automatically via a service just like the Zensical Watchdog service.
```sh
# Create Gitea Runner Service
sudo tee /etc/systemd/system/gitea-runner.service > /dev/null <<'EOF'
[Unit]
Description=Gitea Actions Runner (gitea_runner)
After=network-online.target
Wants=network-online.target
[Service]
Environment=HOME=/var/lib/gitea_runner
User=gitearunner
Group=gitearunner
WorkingDirectory=/var/lib/gitea_runner
ExecStart=/usr/local/bin/gitea_runner daemon --config /etc/gitea_runner/config.yaml
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
EOF
# Remove Container-Based Configurations to Force Runner to Run in Host Mode
sudo sed -i \
'/^[[:space:]]*labels:/,/^[[:space:]]*cache:/{
/^[[:space:]]*labels:/c\ labels:\n - "zensical-host:host"
/^[[:space:]]*cache:/!d
}' \
/etc/gitea_runner/config.yaml
# Enable and Start the Service
sudo systemctl daemon-reload
sudo systemctl enable --now gitea-runner.service
```
### Repository Workflow
Place the following file into your documentation repository at the given location and this will enable the runner to execute when changes happen to the repository data.
```yaml title="gitea/workflows/automatic-deployment.yml"
name: Automatic Documentation Deployment
on:
push:
branches: [ main ]
jobs:
zensical_deploy:
name: Sync Docs to https://kb.bunny-lab.io
runs-on: zensical-host
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Stop Zensical Service
run: sudo /usr/bin/systemctl stop zensical-watchdog.service
- name: Sync repository into /srv/zensical/docs
run: |
rsync -rlD --delete \
--exclude='.git/' \
--exclude='.gitea/' \
--exclude='assets/' \
--exclude='schema/' \
--exclude='stylesheets/' \
--exclude='schema.json' \
--chmod=D2775,F664 \
. /srv/zensical/docs/
- name: Start Zensical Service
run: sudo /usr/bin/systemctl start zensical-watchdog.service
- name: Notify via NTFY
if: always()
run: |
curl -d "https://kb.bunny-lab.io - Zensical job status: ${{ job.status }}" https://ntfy.bunny-lab.io/gitea-runners
```
## Related Documentation
- [Zensical Deployment](<../../../deployments/automation/Documentation/Zensical.md>) — Prepare the service account, watchdog, and destination directory first.
- [Related Gitea Workflows](<../../../reference/Automation/Gitea Configuration Delivery.md>) — Find the connected deployments, procedures, and references for this subject.
+17
View File
@@ -0,0 +1,17 @@
---
tags:
- Automation
- Workflows
- Documentation
---
# Automation
## Purpose
Find workflows for automation. Follow the subject guide to choose the relevant environment and connect this material to the other document types.
## Includes
- AWX
- Gitea
## Follow the Subject
[Automation](<../../reference/Automation/index.md>) explains the relationships and offers starting points for the documented tasks.