Installation & Setup
Everything needed to run the AI/DC solution locally is included in the repository. The environment runs in Docker; you interact with it through the infrahubctl CLI and the Infrahub web UI.
Requirements​
- Python 3.11+ (3.12 recommended)
- Docker and Docker Compose (v2)
- uv — Python package manager
- Git — for cloning the repository
The infrahubctl CLI is installed automatically as part of the infrahub-sdk dependency. No separate installation is needed.
Getting started​
Cloning the repository​
First we have to clone the repository.
git clone https://github.com/opsmill/infrahub-solution-ai-dc.git
Install dependencies​
uv sync --all-packages
This installs all Python dependencies including infrahub-sdk (which provides infrahubctl), invoke (task runner), and the solution's own infrahub-solution-ai-dc package.
Configure environment variables​
export INFRAHUB_USERNAME="admin"
export INFRAHUB_PASSWORD="infrahub"
INFRAHUB_USERNAME and INFRAHUB_PASSWORD are used by infrahubctl to authenticate with the Infrahub API. VERSION sets the Infrahub image tag. If not using direnv, source the file manually or export these variables:
Alternatively, you can use direnv and define the environment variables in a .envrc file at the root of the project.
Build container image​
uv run inv build
This will build a custom Infrahub container image, this is needed because this solution is using a custom Python package src/infrahub_solution_ai_dc that we want to use in our Generators. This makes importing classes and functions from this package easier and more reliable.
Start Infrahub​
uv run inv start
This downloads the base docker-compose.yml from https://infrahub.opsmill.io (if not already present), builds a custom Docker image, then runs docker compose up -d. The custom image extends the standard Infrahub image with the infrahub-solution-ai-dc Python package — a shared library (in src/infrahub_solution_ai_dc/) that the Generators and Transforms use for common logic such as IP addressing, cabling, and interface sorting. Without it, Generators running inside the task workers would not have access to that shared code. The override file (docker-compose.override.yml) ensures the custom image is used in place of the standard one.
Services started:
| Service | Description | Port |
|---|---|---|
infrahub-server | Infrahub API and web UI | 8000 |
task-manager | Prefect API server for workflow orchestration | 4200 |
task-worker | Infrahub task workers (2 replicas) | — |
database | Neo4j graph database | 7474, 7687 |
cache | Redis | — |
message-queue | RabbitMQ | — |
task-manager-db | PostgreSQL for Prefect | — |
Open http://localhost:8000 in a browser and log in with username admin, password infrahub.
Load data​
uv run inv load
This runs four steps in sequence:
infrahubctl schema load schemas— loads the 7 schema files defining the data modelinfrahubctl menu load menus/— loads UI menu configurationinfrahubctl object load objects/— loads all design objects (groups, manufacturers, device types, IPAM, overlay resource pools, profiles, device templates, fabrics, pods, racks, and the seedBlueoverlay tenant)infrahubctl object load repository.yml— registers the Git repository with Infrahub
After inv load, Infrahub imports the repository and reads .infrahub.yml to register Generators, Transforms, queries, and artifact definitions. Verify with infrahubctl repository list. Generators cannot run until this completes.
Load trigger rules​
uv run infrahubctl object load triggers.yml
This creates the CoreGeneratorAction and CoreNodeTriggerRule objects that drive automatic modular Generator execution — including the tenant/overlay trigger (run-tenant-generator). triggers.yml is a committed top-level file that is not part of inv load: it must be loaded after the repository has synced, because the trigger rules reference Generator definitions that need to exist first.
If loaded before Generator definitions are imported, the trigger rules will fail to resolve their action references.
Load supplementary data (optional)​
# NOTE: the data/ directory is NOT loaded by `inv load`.
uv run infrahubctl object load data/permissions.yml # sample operator account `john`
uv run infrahubctl object load data/tenant-red.yml # second, day-two overlay tenant `Red`
The data/ directory holds material that is intentionally kept out of the default load: a sample operator persona (account john, role and group definitions) and a second overlay tenant (Red on Fabric-A) used to demonstrate scoped, non-clobbering day-two multi-tenant generation. Load these manually when you want them.
Repository structure​
The repository is self-contained — everything below is included. You do not need to build any of these from scratch.
Schemas​
| File | Contents |
|---|---|
schemas/logical_design.yml | NetworkFabric and NetworkPod — the design hierarchy with Generator signaling attributes (checksum, amount_of_spines) and the fabric overlay ASN |
schemas/physical_location.yml | LocationHall and LocationRack — physical locations with Generator target support |
schemas/device.yml | NetworkDevice, NetworkInterface, and NetworkLink — devices with computed attributes, ASN, route-reflector role, and VTEP loopback |
schemas/ipam.yml | IpamIPPrefix with role-based allocation and IpamIPAddress |
schemas/overlay.yml | NetworkTenant, NetworkVrf, and NetworkSegment — the overlay intent model |
schemas/routing.yml | NetworkBGPSession — the stored iBGP EVPN control-plane sessions |
schemas/generator.yml | GeneratorTarget generic enabling trigger-based modular Generator execution via checksum attribute |
Generators​
| File | Responsibility |
|---|---|
generators/generate_fabric.py | FabricGenerator — IP pool and overlay ASN allocation, super spine creation, writes checksums to child Pods |
generators/generate_pod.py | PodGenerator — validates fabric complete, spine creation, spine-to-super-spine cabling, iBGP EVPN sessions, writes checksums to child Racks |
generators/generate_rack.py | RackGenerator — validates pod complete, leaf creation, leaf-to-spine cabling, VTEP loopbacks |
generators/generate_tenant.py | OverlayGenerator (registered as generate-tenant, targets the tenants group) — allocates overlay identifiers and materializes tenant/VRF/segment state |
Each Generator has a paired .gql query file in the same directory. The .infrahub.yml file in the repository root wires Generator definitions to their queries and target groups. Note the naming split for the overlay Generator: the definition, file, and query are named generate-tenant/generate_tenant, while the Python class is OverlayGenerator.
Transforms and artifacts​
| File | Purpose |
|---|---|
transforms/startup_config.gql + templates/startup_config_{cisco,arista,dell}.j2 | Three per-vendor Jinja2 Transforms, each producing a startup configuration artifact for the devices in its vendor group (cisco_devices / arista_devices / dell_devices). See Multivendor configuration. |
transforms/cabling_plan.py / .gql | Python Transform producing a CSV cabling plan artifact per fabric |
transforms/computed_interface_description.py / .gql | Python Transform applied as a computed attribute on each interface |
Demo data (object files)​
Loaded in numbered order by infrahubctl object load objects/:
| File | Contents |
|---|---|
objects/01_groups.yml | CoreStandardGroup objects: halls, racks, fabrics, pods, devices, tenants, and the per-vendor device groups cisco_devices / arista_devices / dell_devices |
objects/02_manufacturer.yml | Equipment manufacturers (Cisco, Arista, Dell) |
objects/03_device_type.yml | Per-vendor device types for leaf, spine, and super spine switches |
objects/04_ipam.yml | IP supernet (10.0.0.0/8) and FabricSupernetPool |
objects/05_profiles.yml | Interface role profiles (MTU, role assignments) |
objects/06_device_template.yml | Per-vendor device templates defining interface layouts per device role |
objects/07_pools.yml | Overlay resource pools: ASN, L2VNI, L3VNI, and VLAN number pools |
objects/10_fabric.yml | Fabric and Pod objects: Fabric-A (Cisco), Fabric-B (Arista), Fabric-C (Dell) — each single-vendor |
objects/11_rack.yml | Rack objects across all three fabrics with leaf counts and per-vendor template assignments |
objects/12_overlay.yml | Seed overlay tenant Blue on Fabric-A, with a VRF and segments (routed, rack-scoped, and L2-only examples) |
Trigger rules live in the top-level triggers.yml (not under objects/) and are loaded separately after repository sync — see Load trigger rules. Supplementary data (data/permissions.yml, data/tenant-red.yml) is loaded manually — see Load supplementary data.
Infrastructure​
| File | Purpose |
|---|---|
Dockerfile | Builds a custom Infrahub image with the infrahub-solution-ai-dc Python package installed |
docker-compose.override.yml | Replaces standard Infrahub image with the custom build; mounts src/ for live code changes |
repository.yml | CoreRepository object pointing to /upstream (the mounted repository) |
tasks.py | Invoke task definitions for environment management |
.infrahub.yml | Central configuration wiring Generators, Transforms, queries, and artifacts |
Invoke tasks​
| Task | Command | Description |
|---|---|---|
| Start | inv start | Download compose file (if needed) and start all services |
| Stop | inv stop | Stop containers, remove networks (data preserved) |
| Destroy | inv destroy | Stop containers, remove networks and volumes (full reset) |
| Restart | inv restart | Restart all services (or inv restart --component=<name> for one) |
| Load | inv load | Load schemas, menus, objects, and register repository |
| Load schema | inv load-schema | Load schema files only |
| Load menu | inv load-menu | Load menu definitions only |
| Build | inv build | Build the custom Docker image locally |
| Test | inv test | Run pytest test suite |
| Format | inv format | Run Ruff formatter and auto-fix linting issues |
Troubleshooting​
Services fail to start​
- Check Docker is running:
docker info - Check port conflicts: Infrahub uses ports 8000, 4200, 7474, 7687
- View logs:
docker compose logs infrahub-serverordocker compose logs task-worker - Full reset:
uv run inv destroy && uv run inv start
Repository not syncing​
- Verify with
infrahubctl repository list - The repository mounts from
/upstreaminside the container — checkdocker compose logs task-workerfor import errors - Schema mismatches between what
.infrahub.ymlreferences and what is loaded can block sync