Files
ntbops-ansible/README.md
T

307 lines
8.1 KiB
Markdown

# nbops-ansible
## nbops
#### Infrastructure as Code for notBoris' Homelab
nbops is the central operations repository for my hosted infrastructure, containing everything required to provision, configure, and maintain my virtual machines and services. The goal is to treat my infrastructure as code for reproducibility and automation from source control, while having minimal manual intervention.
## About
nbops-ansible contains the configuration management layer of the nbops platform.
Every virtual machine begins life as a standardised Debian 13 GenericCloud template, provisioned by Proxmox and bootstrapped with Cloud-Init. Once the operating system has completed its initial configuration, the host runs ansible-pull against this repository to configure itself according to its assigned role.
A freshly created virtual machine should require little more than a hostname, network configuration and SSH key before automatically configuring itself into a production-ready host.
# Design Philosophy
This repository follows a layered approach where each component has a clearly defined responsibility.
```mermaid
flowchart TD
A[GitHub: nbops-ansible] --> B[Proxmox VE]
B --> C[Debian 13 GenericCloud Template]
C --> D[Clone VM]
D --> E[Cloud-Init Bootstrap]
E --> F[ansible-pull]
F --> G[Apply Base Roles]
G --> H[Apply Service Roles]
H --> I[Docker Compose]
I --> J[Running Services]
```
## Layer Responsibilities
```mermaid
flowchart LR
P[Proxmox VE<br/>VM lifecycle<br/>storage<br/>networking]
D[Debian 13<br/>GenericCloud<br/>minimal OS]
C[Cloud-Init<br/>identity<br/>network<br/>bootstrap]
A[Ansible<br/>desired state<br/>roles<br/>configuration]
DC[Docker Compose<br/>service runtime]
S[Applications<br/>actual workloads]
P --> D --> C --> A --> DC --> S
```
# Repository Structure
.
├── inventories/
│ ├── production/
│ └── development/
│
├── playbooks/
│
├── roles/
│ ├── base/
│ ├── docker/
│ ├── ssh/
│ ├── ufw/
│ ├── mtls/
│ ├── monitoring/
│ ├── traefik/
│ ├── authentik/
│ ├── immich/
│ ├── gitea/
│ ├── arr/
│ ├── ocis/
│ └── pterodactyl/
│
├── group_vars/
├── host_vars/
├── templates/
├── files/
├── scripts/
└── docs/
As the infrastructure grows, additional functionality should be implemented as new roles rather than modifying existing ones wherever practical.
# Configuration Workflow
Cloud-Init is intentionally lightweight.
Its responsibility is limited to preparing the operating system by configuring:
* Hostname
* Networking
* DNS
* Users
* SSH
* Docker
* Firewall
* Internal CA trust
* Base packages
Once complete, Cloud-Init hands over to Ansible.
Ansible is responsible for configuring and maintaining the desired state of every machine for the remainder of its lifecycle.
# Roles
The repository is built around reusable Ansible roles; every server receives a common baseline before additional service-specific roles are applied.
## Core Roles
* base
* docker
* ssh
* ufw
* mtls
* monitoring
* updates
## Service Roles
* traefik
* authentik
* gitea
* Pelican
* etc..
This approach allows new services to inherit the same security, logging and operating system configuration while remaining independent from one another.
# Operating System Standard
Unless otherwise required, every virtual machine deployed by nbops follows the same baseline.
* Debian 13 (Trixie)
* GenericCloud image
* UEFI (OVMF)
* Q35 machine type
* VirtIO networking
* VirtIO SCSI storage
* QEMU Guest Agent
* Docker Engine
* Docker Compose Plugin
* Chrony
* UFW
* SSH key authentication only
Standardising the operating system significantly reduces maintenance overhead and configuration drift across the environment.
# Infrastructure Principles
The following principles guide every decision made within this repository.
* Everything should be reproducible.
* Everything should be version controlled.
* Manual configuration should be avoided.
* Infrastructure should be disposable rather than unique.
* Security should be built into the baseline.
* Applications should remain isolated from the operating system wherever possible.
* Configuration should be modular and reusable.
# Future Goals
Planned work includes:
* Automated Debian template creation
* Cloud-Init template generation
* Automated certificate management
* Secret management
* Monitoring and alerting
* Backup automation
* Configuration validation
* Disaster recovery testing
* Multi-node infrastructure support
# Contributing
This repository is primarily maintained for my own homelab, but the techniques and playbooks may be useful to others building similar self-hosted environments.
Suggestions, improvements and ideas are always welcome.
# License
Unless otherwise stated, all code within this repository is released under the MIT License.
# nbops-ansible
Ansible repository for a reproducible Proxmox-based Infrastructure as Code
platform using Debian 13 GenericCloud, Cloud-Init, Docker Engine, Docker Compose,
and `ansible-pull`.
## Model
```text
Proxmox
-> Debian 13 GenericCloud template
-> clone
-> Cloud-Init
-> ansible-pull
-> base roles
-> service roles
-> Docker Compose
```
Cloud-Init handles Day 0 bootstrap only. Ansible owns Day 1 onward state.
## Layout
- `inventories/`: production and development inventories
- `playbooks/`: site and pull entrypoints
- `roles/`: reusable core and application roles
- `group_vars/`: shared defaults
- `host_vars/`: per-VM overrides
- `templates/`: Cloud-Init and shared templates
- `scripts/`: local helper scripts
- `docs/`: operational notes
## Roles
Core roles:
- `base`
- `ssh`
- `ufw`
- `updates`
- `docker`
- `mtls`
- `monitoring`
Application roles:
- `traefik`
- `authentik`
- `immich`
- `gitea`
- `ocis`
- `pterodactyl`
- `arr`
Enable roles per host with `nbops_roles`.
```yaml
nbops_roles:
- base
- ssh
- ufw
- updates
- docker
- mtls
- monitoring
- traefik
```
## VM Topology
Every VM is expected to run Docker. Put `docker` in `nbops_roles` for each VM.
The edge VM normally runs `traefik` and `authentik`, with Traefik publishing
ports `80` and `443`. Downstream VMs can run their own internal Traefik and set
`nbops_service_routing_mode: traefik` so applications register with Traefik
instead of exposing individual host ports.
See `host_vars/edge.yml.example`, `host_vars/downstream.yml.example`, and
`docs/topology.md`. The full Docker service list is in `docs/service-catalog.md`.
## Compose Updates
Compose-backed roles deploy from role-owned Jinja templates, not directly from
upstream examples. Upstream README and Compose examples are tracked as copied
snapshots under each role's `upstream/` directory and indexed in
`docs/upstream-sources.yml`.
Use `compose_paths` for Compose files inside an upstream repository and
`compose_urls` for direct raw HTTP Compose YAML fallbacks. Use role-level
`local_compose_file` for Compose reference material already stored in this
repository. README fenced Compose blocks are parsed when no explicit Compose
file is available.
Use `docs/compose-update-policy.md` when updating services so upstream drift,
NBOPS overrides, image pins, and generated Compose files stay reviewable in Git.
To test upstream references for one role:
```sh
scripts/vendor-upstream-snapshots.py jellyfin
```
To refresh copied upstream references:
```sh
scripts/vendor-upstream-snapshots.py --apply jellyfin
```
## Bootstrap
Render `templates/cloud-init-user-data.yml.j2` with host variables and pass it to
Proxmox as user-data. The template installs baseline packages, Docker from
Docker's official Debian repository, configures UFW and SSH, creates `/srv` and
PKI directories, and executes `ansible-pull`.
## Secrets
Secrets are intentionally excluded. Do not commit passwords, API keys,
certificates, private keys, or generated `.env` files. Use Ansible Vault, SOPS,
Vault, or Smallstep-backed issuance when introducing real secret material.
## Validation
```sh
ansible-galaxy collection install -r requirements.yml
scripts/check.sh
```