2026-06-09 20:45:08 +02:00
# AGENTS.md - A13Labs Infrastructure
## Repo Structure
- **`ansible/` ** — Playbooks, roles, inventory. Runs against bare-metal servers.
2026-07-12 16:28:45 -04:00
- **`.opencode/plans/` ** — Plans under execution
- **`implemented/` ** — Reports of implemented features
2026-06-09 20:45:08 +02:00
- **`terraform/` ** — IaC (OpenTofu for K8s app deployments + cloud provisioning).
- **`inventory/hosts` ** — Ansible inventory. All hosts and groups.
- **`requirements/` ** — pip requirements files: `ansible.txt` , `dev.txt` , `opentofu.txt` .
- **`sectool` ** — Secret manager (Bitwarden, configured in `sectool.json` ). Both root and `ansible/` have their own `sectool.json` + `sectool.env` .
## Key Facts
- **No `Makefile` , no `justfile` , no pre-commit config.** Commands are run directly.
- **All GitHub workflows are `.disabled` ** — CI is not active. Verification is local-only.
- **`ansible/ansible.cfg` ** points to `../inventory/hosts` (relative to `ansible/` dir). Always run playbooks from the `ansible/` directory, or use `-i` to override.
- **YAML linting:** `ansible-lint` config at `ansible/.ansible-lint` . `.yamllint.yml` at `ansible/.yamllint.yml` (120 char line warning).
- **No `.pre-commit-config.yaml` exists** — linting is manual or CI-only.
## Ansible
### Required Environment vars
```sh
export ANSIBLE_USER = provision
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY = YES # if on a MAC
```
### Running playbooks
2026-07-12 16:28:45 -04:00
**Note:** ```sectool` `` just need to be used when secrets must be injected to the environment, if the command does not requires secrets injection do not use ` ``sectool` ``
` ``
sh
2026-06-09 20:45:08 +02:00
cd ansible
sectool exec ansible-playbook -u $ANSIBLE_USER playbook_<name>.yml
` ``
### Role testing (Molecule + Podman - Linux Only)
` ``sh
cd ansible/roles/<role_name>
molecule test # create -> converge -> verify -> destroy
molecule converge # run converge only
molecule destroy # clean up
` ``
**Molecule gotchas:**
- Always run ` molecule` commands **from the role directory**, not from repo root.
- Molecule containers use ` podman` driver. No systemd by default — guard service tasks with ` when: ansible_service_mgr == "systemd"`.
- ` molecule/default/prepare.yml` must install python3 and sudo via ` raw:` before Ansible can run Python modules.
- ` provisioner.env.ANSIBLE_ROLES_PATH` should point up to the parent (e.g., ` ../../../`).
### Ansible-lint
` ``sh
ansible-lint # runs from repo root or ansible/
` ``
Excluded paths: ` .git/`, ` .github/`, ` tests/`. Warns on: ` line-length`, ` yaml[line-length]`, ` var-naming[no-role-prefix]`.
## Terraform / OpenTofu
### App deployments (K8s)
- ` terraform/apps/dev-01/` — dev Kubernetes cluster (microk8s)
- ` terraform/apps/prod-01/` — prod Kubernetes cluster (microk8s)
- Uses Kubernetes + TLS providers. ` provider.tf` sets ` insecure = true`.
### Cloud IaC
- ` terraform/iac/aws/` — AWS infrastructure
- ` terraform/iac/contabo/` — Contabo VPS
- ` terraform/iac/cloudns/` — DNS (cloudns)
- ` terraform/iac/scaleway/` — Scaleway infrastructure
2026-07-12 16:28:45 -04:00
### Running Terraform / OpenTofu
2026-06-09 20:45:08 +02:00
Each terraform directory has its own ` sectool.env`. Run ` sectool` to load secrets before ` tofu init/plan/apply`:
2026-07-12 16:28:45 -04:00
To validate plane (mandatory before apply)
2026-06-09 20:45:08 +02:00
` ``sh
2026-07-12 16:28:45 -04:00
sectool exec tofu plan
2026-06-09 20:45:08 +02:00
` ``
2026-07-12 16:28:45 -04:00
Apply:
` ``sh
sectool exec tofu apply --auto-approve
` ``
## Secrets
To list secrets:
` ``sh
sectool vault list
` ``
To set a secret:
` ``sh
sectool vault set <secret name> <secret value>
` ``
To set a secret:
` ``sh
sectool vault get <secret name> <secret value>
` ``
2026-06-09 20:45:08 +02:00
### Module structure
- ` terraform/modules/apps/` — application modules (Nextcloud, etc.)
- ` terraform/modules/db/` — database modules (MariaDB with backups)
- ` terraform/modules/utils/` — utilities (exporters, cert-checker, prometheus, trivy, etc.)
## Scripts (` scripts/`)
One-off utility scripts — not library code:
- ` install-opnsense.sh` — boots OPNsense on a VM via virt-install (one-time router setup)
- ` chronograf.sh` — ` kubectl port-forward` wrapper for Chronograf pod
- ` proxy-pt.sh` — ` kubectl port-forward` wrapper for m3uproxy pod
- ` steamos` — launches SteamOS gaming session with sunshine
- ` cpu_power_monitor.py` — RAPL power monitoring (requires root)
## Environment Setup
` ``sh
# Ansible + dev tools
pip install -r requirements/ansible.txt -r requirements/dev.txt
# Terraform/OpenTofu deps
pip install -r requirements/opentofu.txt
` ``
## Contabo CLI
` ``sh
sectool exec cntb get instances --oauth2-clientid="$CONTABO_CLIENT_ID" ...
` ``
## Windows hosts
- Use ` ConfigureRemotingForAnsible.ps1` in ` scripts/` to enable WinRM on Windows targets.
- On MSYS2: install packages listed in ` Readme.MD` (go, python, cryptography, paramiko, rpds-py, etc.).
- Python venv: ` python -m venv .venv --system-site-packages`
## Style Conventions
- YAML: 120 char line length (warning threshold)
- Ansible roles follow galaxy conventions: ` defaults/`, ` tasks/`, ` meta/`, ` files/`, ` templates/`
- ` tasks/main.yml` is the entrypoint for every role
- Host vars: ` ansible/host_vars/<hostname>.yml`
2026-07-12 16:28:45 -04:00
## Troubleshooting and planning
- When troubleshooting and planning use deepwiki whenever possible to get documentation or information, deepwiki provides information about projects hosted on github to agents.