I’ve recently had the need to better manage my homelab and have been using netbox to do so. However, when you have a lot of VM’s, it gets daunting to catalog them. So I’ve written a role to do my baselining.
The convenient thing about having your entire infrastructure in netbox means that you can use it for dynamically generating your inventories afterwards. But that’s another post entirely. This first post focuses on installing netbox automatically with an ansible script.
Netbox is mostly a one-shot installation. However, it can be useful to have a tool such as netbox if you’re repetitively baselining infrastructure. This can be the case if you’re an IT admin in a consultancy managing several clients; or perhaps if you suddenly have to catalog an entire infrastructure and you have nothing but a default set of credentials. Perhaps you want to deploy this on your ludus instance for practice.
Whatever your use-case may be, here’s a simple role on which you can base your installations.
I’m operating on the assumption that you already have python3-pip and python3-venv installed on a debian-based
distro, with a bash shell.
Note: I first posted this article on the 26th of October, but I’ve since come back and modified it. I realized that it didn’t work out of the box and I wanted something at least functional; I’ve since published a ludus netbox role which you’ll find here: https://github.com/Inf0Junki3/inf0junki3.ludus
# Set up a virtual environment.
python3 -m venv venv
source venv/bin/activate
# Install the tools we need - in this case we'll set up both ansible and netbox.
pip install ansible pynetbox
Next, we’ll set up a collection and a role:
ansible-galaxy collection init heapspray.netbox # Be sure to edit your galaxy.yml file with the appropriate metadata.
cd heapspray/netbox/roles
ansible-galaxy role init installation # For the installation of the netbox instance.
# Don't forget to fill out meta/main.yml!
ansible-galaxy role init inventory # For populating the netbox instance with your inventory.
# Don't forget to fill out this meta/main.yml too!
Now for the role. You’ll need some default variables in default/main.yml:
GENERIC_TIMEZONE: "America/New_York"
TZ: "America/New_York"
PUID: "1000"
PGID: "1000"
SUPERUSER_EMAIL: "[email protected]"
SUPERUSER_PASSWORD: "changeme"
ALLOWED_HOST: "castle.mario.time"
POSTGRES_USER: "postgres"
POSTGRES_DB: "netbox"
# You know what to do here :) Generate those users and passwords with `pwgen -s -B -1 16 4`
DB_NAME: "netbox"
DB_USER: "postgres"
DB_PASSWORD: "badpassword"
DB_HOST: "postgres"
DB_PORT: ""
REDIS_HOST: "redis"
REDIS_PORT: ""
REDIS_PASSWORD: "badpassword"
REDIS_DB_TASK: ""
REDIS_DB_CACHE: ""
# BASE_PATH: #optional
# REMOTE_AUTH_ENABLED: #optional
# REMOTE_AUTH_BACKEND: #optional
# REMOTE_AUTH_HEADER: #optional
# REMOTE_AUTH_AUTO_CREATE_USER: #optional
# REMOTE_AUTH_DEFAULT_GROUPS: #optional
# REMOTE_AUTH_DEFAULT_PERMISSIONS: #optional
Next, we create a tasks file in tasks/main.yml. This one is simple - I’m going off the premise that you’ll set up an
unencrypted docker compose file here and will add your traefik or caddy proxy afterwards.
---
- name: Create the directory for the certs
ansible.builtin.file:
path: "{{ item }}"
mode: "0755"
state: directory
loop:
- /opt/netbox
- /opt/netbox/config
- name: Set up the docker compose file
ansible.builtin.template:
src: docker-compose.yml.j2
dest: /opt/netbox/docker-compose.yml
- name: Run the compose project
community.docker.docker_compose_v2:
project_src: /opt/netbox
Last but not least, the templates/docker-compose.yml.j2 file will allow you to spin up a docker project:
---
services:
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: {{ DB_PASSWORD }}
POSTGRES_DB: {{ DB_NAME }}
volumes:
- /opt/postgres/data:/var/lib/postgresql
networks:
- netbox
redis:
image: redis
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
environment:
REDIS_PASSWORD: {{ REDIS_PASSWORD }}
volumes:
- /opt/redis/data:/data
networks:
- netbox
netbox:
image: lscr.io/linuxserver/netbox:latest
container_name: netbox
environment:
- PUID={{ PUID }}
- PGID={{ PGID }}
- TZ={{ TZ }}
- SUPERUSER_EMAIL={{ SUPERUSER_EMAIL }}
- SUPERUSER_PASSWORD={{ SUPERUSER_PASSWORD }}
- ALLOWED_HOST={{ ALLOWED_HOST }}
- DB_NAME={{ DB_NAME }}
- DB_USER={{ DB_USER | default('postgres') }}
- DB_PASSWORD={{ DB_PASSWORD }}
- DB_HOST={{ DB_HOST | default('postgres') }}
- DB_PORT={{ DB_PORT }}
- REDIS_HOST={{ REDIS_HOST | default('redis') }}
- REDIS_PORT={{ REDIS_PORT }}
- REDIS_PASSWORD={{ REDIS_PASSWORD }}
- REDIS_DB_TASK={{ REDIS_DB_TASK }}
- REDIS_DB_CACHE={{ REDIS_DB_CACHE }}
- BASE_PATH= #optional
- REMOTE_AUTH_ENABLED= #optional
- REMOTE_AUTH_BACKEND= #optional
- REMOTE_AUTH_HEADER= #optional
- REMOTE_AUTH_AUTO_CREATE_USER= #optional
- REMOTE_AUTH_DEFAULT_GROUPS= #optional
- REMOTE_AUTH_DEFAULT_PERMISSIONS= #optional
volumes:
- /opt/netbox/config:/config
- /opt/netbox/certs:/certs
ports:
- 8000:8000
restart: unless-stopped
networks:
- netbox
networks:
netbox: