Vendor-agnostic NetDevOps toolbox for Ansible, OpenTofu, Python, and CI/CD pipelines.
1.2K
https://github.com/lucas-weiselowski/bezalel.gitβ
"I have filled him with the Spirit of God, with wisdom, with understanding, with knowledge and with all kinds of skillsβto make artistic designs, to work in gold, silver and bronze..."
β Exodus 31:3-4
Bezalel is the master artisan. In this repository, it represents the ultimate NetDevOps container toolbox. This image gives you the power and tools to build, automate, and craft robust network infrastructure.
Vendor-agnostic network automation container built for speed, consistency,
and scale. Named after the master artisan β the non-root user is artisan,
the workshop is /forge.
Bezalel eliminates the "works on my machine" problem: one pre-configured, multi-arch (amd64/arm64) environment for Python scripts, Ansible playbooks, OpenTofu deployments and automated network tests β in GitLab/GitHub CI pipelines or ephemerally on your laptop.
| Tag | Target | Use case |
|---|---|---|
latest / full | runtime-full | Complete engineering workspace: pyATS[full], Nornir, NAPALM, rich, pyang + jq, yq, bat, make, ping, dig. Local development, jump-hosts. |
slim | runtime-slim | Core automation drivers only: ansible-core, Netmiko, Scrapli, ncclient, pygnmi, pytest, Pydantic. Fast CI/CD runners. |
Both flavors ship uv, OpenTofu (tofu) and gnmic binaries, plus git,
ssh and curl. Python environment is uv-managed and locked (uv.lock).
| Layer | Tools |
|---|---|
| CLI / SSH | Netmiko, Scrapli, Paramiko |
| NETCONF | ncclient, scrapli-netconf |
| RESTCONF / HTTP | httpx, requests |
| gNMI | gnmic (binary), pygnmi |
| IaC / Config Mgmt | Ansible, OpenTofu |
| Data & Validation | Pydantic, xmltodict, lxml, jmespath, Jinja2, pyang* |
| Testing | pytest, pyATS |
* full image only (plus Nornir, NAPALM, rich, yamllint).
-u $(id -u):$(id -g); generated files
belong to you, not root. Works on OpenShift and GitLab runners with
random UIDs (entrypoint self-registers unknown UIDs in /etc/passwd)..env discovery β entrypoint sources /forge/.env when present;
python-dotenv is preinstalled for your own scripts./forge, non-root user artisan, TZ=Europe/Berlin.Add to ~/.bashrc / ~/.zshrc:
# Bezalel β ephemeral network automation toolbox
bezalel() {
local args=(--rm -it --hostname forge -u "$(id -u):$(id -g)" --group-add 0 -v "${PWD}:/forge")
# global defaults first, project-local .env second (wins on conflict)
[[ -f "${HOME}/.bezalel.env" ]] && args+=(--env-file "${HOME}/.bezalel.env")
[[ -f "${PWD}/.env" ]] && args+=(--env-file "${PWD}/.env")
docker run "${args[@]}" "${BEZALEL_IMAGE:-karlender/bezalel:full}" "$@"
}
bezalel # interactive shell in /forge
bezalel ansible-playbook deploy_fabric.yml
bezalel python gather_facts.py
bezalel gnmic -a router1:57400 capabilities
bezalel tofu plan
BEZALEL_IMAGE=karlender/bezalel:slim bezalel pytest tests/
# GitLab CI
deploy_network:
image: karlender/bezalel:slim
script:
- tofu init
- tofu apply -auto-approve
- pytest tests/test_reachability.py
# GitHub Actions
jobs:
lint:
runs-on: ubuntu-latest
container: karlender/bezalel:slim
steps:
- uses: actions/checkout@v4
- run: ansible-playbook --syntax-check site.yml
docker build --target runtime-slim -t karlender/bezalel:slim .
docker build --target runtime-full -t karlender/bezalel:full .
Pin tool versions: --build-arg TOFU_VERSION=1.12.3 --build-arg GNMIC_VERSION=0.46.0 --build-arg UV_VERSION=0.7.12.
Releases are automated: pushing a vX.Y.Z tag triggers the GitHub Actions
workflow which builds multi-arch images, scans them with Trivy and pushes
slim, full, latest, X.Y.Z, X.Y.Z-slim, X.Y.Z-full to Docker Hub.
.env Handlingbezalel() function passes ~/.bezalel.env and ./.env via --env-file.entrypoint.sh sources /forge/.env β covers CI and plain docker run.python-dotenv β your scripts can load_dotenv().Never bake credentials into the image; .env stays in .gitignore.
Content type
Image
Digest
sha256:6c8623bb6β¦
Size
1 GB
Last updated
3 months ago
docker pull karlender/bezalel