https://github.com/dryvist/ansible-proxmox-apps
Ansible roles for configuring applications on Proxmox VMs and LXC containers - includes Cribl Edge, Cribl Stream, HAProxy syslog load balancer, and common application patterns
https://github.com/dryvist/ansible-proxmox-apps
ansible automation cribl devops haproxy infrastructure-as-code log-management lxc observability proxmox syslog virtualization
Last synced: 26 days ago
JSON representation
Ansible roles for configuring applications on Proxmox VMs and LXC containers - includes Cribl Edge, Cribl Stream, HAProxy syslog load balancer, and common application patterns
- Host: GitHub
- URL: https://github.com/dryvist/ansible-proxmox-apps
- Owner: dryvist
- License: apache-2.0
- Created: 2026-01-18T02:52:50.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2026-07-03T02:58:36.000Z (27 days ago)
- Last Synced: 2026-07-03T04:36:00.271Z (27 days ago)
- Topics: ansible, automation, cribl, devops, haproxy, infrastructure-as-code, log-management, lxc, observability, proxmox, syslog, virtualization
- Language: Jinja
- Size: 7.5 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 20
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Ansible Proxmox Apps
Configure applications running on Proxmox VMs and LXC containers.
This repository manages application deployment and configuration only. It assumes
the target VMs and containers — and their persistent storage — already exist and
are reachable over SSH. It does not provision infrastructure; it consumes a
published inventory describing the hosts it should configure (see
[Inventory contract](#inventory-contract)).
## Purpose and Scope
Deploy and configure the following application stacks:
- **Cribl Edge**: Syslog ingestion and log processing with persistent queue
- **Cribl Stream**: Central processing node for log pipeline
- **HAProxy**: Syslog/netflow load balancer distributing traffic to Cribl nodes
Cribl Edge, Cribl Stream, and HAProxy run natively on LXC containers. Splunk runs
on a VM. This repository handles application configuration on those hosts; it does
not create them.
## Inventory contract
This repository is configuration-only. It expects the hosts, their IPs, and the
pipeline's port constants to be supplied at run time as a published inventory
artifact — a single JSON document — rather than hardcoded here. Any system that
emits a document matching the shape below can drive these playbooks.
The inventory loader (`inventory/load_tofu.yml`) resolves the artifact at run
time, in priority order (first that resolves wins):
1. `TOFU_INVENTORY_PATH` — an explicit local file (pin / override, e.g. tests).
2. **Published S3 artifact** — the raw inventory JSON fetched natively from S3
(`amazon.aws.aws_caller_info` + `amazon.aws.s3_object`; boto3 comes from the
dev shell — no checkout, no provisioning toolchain, no `aws` CLI). Point at it
with `TOFU_INVENTORY_S3_URI` (else the URI is derived from the active AWS
account); set the region with `TOFU_INVENTORY_S3_REGION` (default `us-east-2`).
3. `inventory/tofu_inventory.json` — a local gitignored cache.
The resolved document is loaded as `tofu_data` and validated before any play
runs. It MUST contain at least:
- `tofu_data.domain` — the DNS domain used to derive each container's Proxmox
node host as `{node-role}.{domain}` (so there is no global Proxmox host to set).
- `tofu_data.nodes` — node-name to role mapping, used in the FQDN derivation above.
- `tofu_data.containers`, `tofu_data.vms`, `tofu_data.docker_vms`,
`tofu_data.splunk_vm` — the hosts to configure, each carrying its IP and
connection settings; surfaced to roles via `hostvars`.
- `tofu_data.constants` — the pipeline's port assignments. `service_ports` and
`syslog_ports` are required; roles also read `syslog_port_map`, `netflow_ports`,
`notification_ports`, and `media_ports`. Ports are never hardcoded in playbooks
or roles — they are always read from `tofu_data.constants`.
If `tofu_data` is missing required keys, the loader fails loudly before
configuring anything.
## Installation
This repository owns its toolchain via a Nix flake + direnv (`ansible`,
`ansible-lint`, `molecule`, `sops`, `age`, `python3` with paramiko/pyyaml/jinja2,
`jq`, `yq`, `pre-commit`). Run everything inside that dev shell.
```bash
git clone ansible-proxmox-apps
cd ansible-proxmox-apps
direnv allow # one-time per worktree — auto-activates the dev shell on cd
# Install required Ansible Galaxy collections
ansible-galaxy collection install -r requirements.yml
# Configure Doppler for secrets (API keys, passwords)
doppler configure set project ansible-proxmox-apps
doppler configure set config prd
```
Set the SSH key used to reach the LXC containers. The Docker-VM roles
(testing/dev only) reach their hosts over a separate key, which the inventory
loader requires whenever the inventory contains Docker VMs:
```bash
# SSH key for the LXC containers (production stacks)
export PROXMOX_SSH_KEY_PATH=""
# SSH key for the Docker VMs — required when the inventory has docker_vms
export PROXMOX_DKR_SSH_KEY_PATH=""
```
## Usage
Run playbooks inside the dev shell, with secrets injected by Doppler. Hosts and
ports come from the published inventory (see
[Inventory contract](#inventory-contract)).
```bash
# Deploy Cribl Edge (syslog processing on LXC containers)
doppler run -- ansible-playbook \
-i inventory/hosts.yml playbooks/site.yml --tags cribl_edge
# Deploy Cribl Stream (netflow/IPFIX processing on LXC containers)
doppler run -- ansible-playbook \
-i inventory/hosts.yml playbooks/site.yml --tags cribl_stream
# Deploy HAProxy (load balancer on LXC container)
doppler run -- ansible-playbook \
-i inventory/hosts.yml playbooks/site.yml --tags haproxy
# Deploy all applications
doppler run -- ansible-playbook \
-i inventory/hosts.yml playbooks/site.yml
```
## Roles
### cribl_edge
Deploy Cribl Edge log processor with syslog listeners and Splunk HEC output.
- Installs Cribl Edge from official package repository
- Configures UDP/TCP syslog listeners (ports 1514-1518)
- Configures Splunk HEC output
- Mounts 100GB persistent queue disk at `/opt/cribl/data`
See `roles/cribl_edge/README.md` for detailed configuration.
### cribl_stream
Deploy Cribl Stream as central processing node in the pipeline.
- Installs Cribl Stream from official packages
- Configures as processing node (not leader)
- Mounts 100GB persistent queue disk at `/opt/cribl/data`
See `roles/cribl_stream/README.md` for configuration options.
### haproxy
Production load balancer on a dedicated LXC container.
- Installs HAProxy and Nginx Stream on the HAProxy LXC container
- Forwards syslog traffic (TCP/UDP) to Cribl Edge LXC containers
- Forwards netflow/IPFIX traffic (TCP/UDP) to Cribl Stream LXC containers
- HAProxy stats dashboard available (port from `tofu_data.constants`)
See `roles/haproxy/README.md` for details.
### apt_cacher_ng
APT package caching proxy to reduce bandwidth usage across containers and VMs.
See `roles/apt_cacher_ng/README.md` for configuration.
### cribl_docker_stack (testing/dev only)
Deploy Cribl Stream and Cribl Edge as Docker containers on the docker-host VM.
This role is for testing and development only. Production pipelines use the
`cribl_edge` and `cribl_stream` roles on native LXC containers.
### mailpit_docker
Deploy Mailpit email testing container for local SMTP capture and inspection.
### mssql_docker
Deploy Microsoft SQL Server as a Docker container.
### ntfy_docker
Deploy ntfy push notification service as a Docker container.
### technitium_dns
Deploy Technitium DNS server container for local DNS resolution and blocking.
## Architecture
All production components run on LXC containers (Cribl Edge, Cribl Stream,
HAProxy) or VMs (Splunk).
```text
┌──────────────────┐ ┌──────────────────┐
│ Syslog Sources │ │ NetFlow Sources │
└────────┬─────────┘ └────────┬─────────┘
│ │
(UDP/TCP syslog) (UDP IPFIX)
│ │
▼ ▼
┌────────────────────────────────────────┐
│ HAProxy LXC │
│ (Load Balancer) │
└───────┬────────────────────┬───────────┘
│ │
(syslog) (netflow)
│ │
▼ ▼
┌─────────┐ ┌──────────┐
│Cribl │ │Cribl │
│Edge LXCs│ │Stream │
│(syslog) │ │LXCs │
└────┬────┘ │(IPFIX) │
│ └────┬─────┘
│ │
└─────────┬─────────┘
│
(Splunk HEC)
│
▼
┌──────────────┐
│ Splunk │
│ VM │
└──────────────┘
```
## File Layout
```text
ansible-proxmox-apps/
├── README.md This file
├── CLAUDE.md AI agent documentation
├── ansible.cfg Ansible configuration
├── requirements.yml Ansible Galaxy dependencies
├── .ansible-lint Linting rules
├── .gitignore Git ignore rules
├── .pre-commit-config.yaml Pre-commit hooks
├── inventory/
│ ├── hosts.yml Static shared vars (hosts added dynamically)
│ ├── load_tofu.yml Resolves & validates the inventory artifact
│ └── group_vars/
│ └── all.yml Global variables
├── playbooks/
│ └── site.yml Main playbook (all roles)
└── roles/
├── cribl_edge/
│ ├── README.md
│ ├── defaults/main.yml
│ ├── tasks/main.yml
│ ├── handlers/main.yml
│ └── templates/
├── cribl_stream/
│ ├── README.md
│ ├── defaults/main.yml
│ ├── tasks/main.yml
│ ├── handlers/main.yml
│ └── templates/
└── haproxy/
├── README.md
├── defaults/main.yml
├── tasks/main.yml
├── handlers/main.yml
└── templates/
└── haproxy.cfg.j2
```
## Linting
Validate code quality with ansible-lint:
```bash
ansible-lint
```
Fix common issues automatically:
```bash
ansible-lint --fix
```
## Contributing
1. Update inventory handling in `inventory/`
2. Modify roles in `roles/*/`
3. Test with `--check --diff` mode
4. Validate with `ansible-lint`
5. Run playbook to apply
## License
Apache License 2.0 - see [LICENSE](LICENSE) for details.
---
> Part of a [larger ecosystem of ~40 repos](https://docs.jacobpevans.com) — see how it all fits together.