infra-edge-lab · v0.1.0

Installation

This page sets up a workstation for working on the repository and for running its environments. Tested on 2026-10-21 and 2026-10-22 on Linux x86_64 with the versions in toolchain.md; the Python part was also tested in the python:3.12-slim and python:3.13-slim containers.

Requirements

Requirement Version Notes
Git any current version
Python 3.12 or 3.13, with the venv module Debian and Ubuntu: package python3-venv
go-task 3.54.0 runs task lint, task test, task tofu, task molecule, task e2e:local and the environment tasks
OpenTofu, gitleaks, actionlint as in toolchain.md needed by task lint
OpenTofu, TFLint, Trivy as in toolchain.md needed by task tofu (Trivy for its iac step), OpenTofu also by task e2e:local and the environment tasks; on Linux x86_64, bash scripts/install_tofu_tools.sh ~/.local/bin tofu tflint trivy installs them after checking their sha256
Docker Engine allows privileged containers needed by the integration step of task tofu (the docker_host module boots containers with systemd), by task molecule (the role scenarios) and by the local environment (task e2e:local, task up ENV=local); about 2 GB of free memory for the docker and monitoring scenarios and for the monitoring host of local, which keep Docker’s storage inside the container on tmpfs
OpenSSH client any current version ssh-keygen creates the throwaway key of the local environment and of task e2e:tunnel, whose SSH check also needs ssh
SOPS, age as in toolchain.md read the encrypted files in secrets/; task dns-backup encrypts the zone copy with age
curl any current version task e2e:tunnel checks demo-web with it and downloads the pinned cloudflared
cloudflared as in toolchain.md on the PATH for task configure and task smoke of a cloud server in demo or showcase, which Ansible reaches through the tunnel with cloudflared access ssh
Network access outbound HTTPS PyPI (the hash-pinned Python tools), GitHub (the luminare collections and the release downloads of node_exporter and Prometheus), Ansible Galaxy, Docker Hub (base images, Uptime Kuma) and the package mirrors of Debian, Ubuntu and Docker inside the hosts
Node.js 24.22.0 runs markdownlint-cli2 in task lint

Install every binary only after its sha256 matches the value in toolchain.md. The Python tools come from the hash-pinned requirements files; nothing is installed system-wide.

Install

git clone https://github.com/luminare-dev/infra-edge-lab.git
cd infra-edge-lab
task venv

task venv creates .venv and installs requirements-dev.txt and requirements-test.txt with pip install --require-hashes --only-binary=:all:. requirements-test.txt includes the ansible package, which brings the community collections that the roles, ansible-lint and Molecule use, so the tests need nothing from Ansible Galaxy.

To run the playbooks, install the collections of ansible/requirements.yml into ansible/collections:

task collections

luminare.infra_edge and luminare.gameserver are cloned from their public GitHub repositories (luminare-dev/ansible-collection-infra_edge, luminare-dev/ansible-collection-gameserver) at the release tags pinned in that file; devsec.hardening and prometheus.prometheus come from Ansible Galaxy at exact versions, and the other community collections from the ansible package of the virtual environment. task e2e:local runs the same install itself. The unit tests and ansible-lint need none of them.

Keys for the environments with credentials

local needs no key and no account. Before working on lab, demo or showcase, create your age key and the encrypted files of the environment as described in configuration.md; for lab, also the Proxmox VE users of the runbook.

Verify the release download

Every release has a SHA256SUMS file and a build provenance attestation:

sha256sum -c SHA256SUMS
gh attestation verify infra-edge-lab-<version>.tar.gz --repo luminare-dev/infra-edge-lab

Check that it works

task test

The unit tests end with a line that starts with OK (a test that needs an optional tool, such as markdownlint-cli2, that is not on the PATH is counted as skipped), and ansible-lint ends with Passed: 0 failure(s), 0 warning(s) and the production profile. task lint then runs every repository check; each one prints no finding. task tofu runs the OpenTofu checks; every tofu test ends with Success! and every validation with The configuration is valid. The OpenTofu checks download the providers named in the lock files into .terraform/ of each module and environment, one copy per directory: about 1.5 GB unpacked, because the Cloudflare provider (about 190 MB) is used by three modules and three environments. With TF_PLUGIN_CACHE_DIR set to a directory, every provider is stored there once, about 320 MB in all.

task molecule ROLE=<role> runs a role’s Molecule scenario on both platforms (Debian 13 and Ubuntu 24.04, one after the other); each ends with Executed: Successful for every step, and the idempotence step reports changed=0. Add PLATFORM=debian13 or PLATFORM=ubuntu2404 to run one platform only.

To try an environment without any account, rebuild local from nothing and throw it away again; this is what CI’s e2e-local workflow runs:

task e2e:local

It creates edge-01, db-01 and fx-01 as containers, configures them twice with ansible/playbooks/site.yml (the second run must change nothing), plans again (no changes), smoke-tests them, backs each one up and tests the restore, destroys them, and ends with a table of its steps and their times (Result: passed). To keep the environment for a look inside, build it step by step instead, with one passphrase for the whole session:

export TF_VAR_state_passphrase="$(openssl rand -base64 32)"
task collections
task up ENV=local
docker exec -it lab-local-edge-01 bash
task destroy ENV=local

Uninstall

Delete the clone. Inside it, the tasks create .venv/ (Python tools), .task/ (go-task’s checksum cache), tofu/modules/*/.terraform/ and tofu/envs/*/.terraform/ (provider downloads), and an environment with a local state keeps terraform.tfstate (and backend_override.tf after BACKEND=local) in its folder. Before deleting a state, destroy what it holds (task destroy ENV=local with the same passphrase, which also deletes the empty state of local, ansible/inventories/local/hosts.yml and the generated secrets in ansible/inventories/local/.generated/). The docker_host integration test removes its containers, network and image when it ends, and every Molecule scenario removes its containers; the Molecule images molecule_local/lab-molecule-debian13 and molecule_local/lab-molecule-ubuntu2404 and the base images debian:trixie and ubuntu:24.04 stay in the Docker image store (docker image rm removes them); the destroy of local removes its image lab-systemd-host-* too. The Prometheus archive of the local environment is cached in ansible/inventories/local/.generated/ and goes with it. ansible/collections/ holds the collections installed from ansible/requirements.yml. Outside it, download caches in your home directory remain: pip’s (~/.cache/pip, written by task venv and task test), npm’s (~/.npm, where npx markdownlint-cli2 in task lint keeps the package), and Molecule’s and ansible-lint’s working files (~/.ansible/tmp, ~/.cache/ansible-compat). They may also hold files of other projects, so delete them only if nothing else needs them.

docs/install.md on GitHub

Licensed under Apache-2.0. Source: luminare-dev/infra-edge-lab at v0.1.0.