Deployment guide

Infrahub

Overview

Infrahub is an open source infrastructure data management platform, a source of truth you shape yourself. Instead of bending your infrastructure into the fixed data model of someone else, you define your own schema. The schema holds the node kinds, attributes and relationships that describe the sites, devices, circuits, IP address space and services you actually run.

You then create, relate and query those objects through a GraphQL API or a web interface.

What makes Infrahub different from a database with a web front end is that it applies version control to your data. Changes are made on a branch, reviewed as a proposed change, and merged. Your source of truth carries the same branching, peer review and history that your teams already expect from code.

Generators and transformations turn that data into device configuration and artifacts. Synchronized Git repositories keep templates and business logic alongside the data they render.

The SecureAnyCloud image installs Infrahub 1.10.5 as a digest-pinned Docker Compose stack managed by systemd, so a working source of truth is online within minutes of launch.

What you get:

  • Infrahub 1.10.5 (Apache-2.0), from the official published image docker.io/opsmill/infrahub:1.10.5, pinned by digest so the appliance can never silently drift onto a different build
  • Docker Engine (Docker CE) and the Docker Compose plugin, from the official Docker package repository
  • Neo4j 2025.10.1 Community Edition (GPLv3), the graph database that holds your source of truth
  • PostgreSQL 18 for the task manager, Redis 8.4.0 as the cache, and RabbitMQ 4.2.1 as the message broker
  • The embedded Prefect task manager plus two task workers, for generators, transformations and Git synchronization
  • The Infrahub web interface and GraphQL API published on port 80. The graph database, PostgreSQL, Redis and RabbitMQ publish no host port at all and are reachable only on the private container network
  • All stateful data on a dedicated 128 GiB data disk mounted at /var/lib/infrahub (the Docker data-root is relocated there), independently resizable and re-provisioned on every VM
  • A per-VM admin password and a per-VM API token, both generated at first boot
  • Anonymous read access disabled (upstream ships it enabled), and product telemetry opted out
  • Bundled component license notices for Neo4j and Redis under /usr/share/doc/sac/third-party-licences/
  • Two systemd units: infrahub.service (a oneshot wrapper around docker compose up -d) and infrahub-firstboot.service
  • 24/7 SecureAnyCloud support

About the credentials

The public Compose file of upstream hardcodes a default admin password, an admin API token, an agent API token, a JWT signing key, a Neo4j password and a broker password. Those literals sit in a public git repository, so they are not secrets. None of them survive on this image.

On the first boot of every VM, infrahub-firstboot.service generates a fresh value for each one. It initializes the databases empty under the rotated credentials and verifies both the password login and the API token round trip. It then writes the two credentials you need to /root/infrahub-credentials.txt.

Prerequisites

You need an active Azure subscription, an SSH key, and a VNet with a subnet.

Standard_B8ms (8 vCPU / 32 GB RAM) is the recommended size. This is a genuinely heavy appliance. OpsMill documents a floor of 6 CPU cores and 12 GB RAM and a recommended 8 cores / 16 GB.

The stack runs seven containers, including a JVM graph database, an Erlang message broker, PostgreSQL, Redis and three Python services. A 2 vCPU / 4 GB size is well under half the documented minimum and will not work.

For NSG inbound rules, allow 22/tcp from your management CIDR for SSH. Allow 80/tcp from the CIDR that needs the Infrahub web interface and API. Add 443/tcp if you put your own TLS in front.

1

Connect over SSH

Replace <vm-ip> with the public IP of your VM. The default login user is azureuser.

ssh azureuser@<vm-ip>
2

Confirm the services are active

sudo systemctl is-active docker.service infrahub.service docker --version docker compose version

You should see active printed twice, the Docker Engine version, and the Docker Compose v2 plugin version.

3

Confirm the Infrahub containers are running

cd /opt/infrahub && sudo docker compose --env-file .env ps

All seven containers should report Up. The ones with health checks should also report (healthy).

The stack is infrahub-server, task-manager, two task-worker replicas, database (Neo4j), task-manager-db (PostgreSQL), cache (Redis) and message-queue (RabbitMQ).

4

Retrieve your per-VM credentials

Every credential on this image is generated on first boot and is unique to your VM. Read them from the credentials file:

sudo cat /root/infrahub-credentials.txt

Keep this file safe. It contains your admin password and your API token.

5

Confirm the API is answering

curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1/api/config

HTTP 200 confirms the Infrahub server is up and serving.

6

Confirm the datastores are not reachable from the network

This image publishes exactly one host port. The graph database that holds your source of truth is reachable only on the private container network, and so are PostgreSQL, Redis and RabbitMQ.

sudo ss -ltnH '! src 127.0.0.0/8' | awk '{print $4}' | sed 's/.*://' | sort -un

You should see 22 (SSH) and 80 (Infrahub) only. The Neo4j ports 7474 and 7687, the PostgreSQL port 5432, the Redis port 6379 and the RabbitMQ port 5672 must not appear.

7

Sign in to the web interface

Browse to http://<vm-ip>/ and sign in as admin with the password from Step 4.

After signing in, you land on the Infrahub home view. The left-hand navigation has the object explorer, the schema browser and the branch controls.

8

Browse the schema

The schema is the heart of Infrahub. It lets you model your own infrastructure rather than accept a fixed data model.

Open Schema from the navigation to browse the node kinds currently loaded, their attributes and their relationships.

9

Authenticate against the API

The Infrahub API is GraphQL. You can authenticate either with a session token from a password login, or directly with the API token from Step 4 using the X-INFRAHUB-KEY header. The token is simpler for scripting.

First, set your token as a shell variable, using the value from Step 4:

TOKEN='<INFRAHUB_API_TOKEN>'

Confirm it authenticates against a resource that requires authentication:

curl -s -o /dev/null -w 'HTTP %{http_code}\n' \
  -H "X-INFRAHUB-KEY: $TOKEN" http://127.0.0.1/api/schema

HTTP 200 confirms the token is valid. The same request without the header is refused, because anonymous access is disabled on this image:

curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1/api/schema
10

Load a schema of your own

This step turns Infrahub into your source of truth. The following command loads a small schema that defines a Site node kind in a Demo namespace, with a name, a site code and a device count.

cat > /tmp/demo-schema.json <<'EOF' { "schemas": [ { "version": "1.0", "nodes": [ { "name": "Site", "namespace": "Demo", "label": "Site", "description": "A physical network site.", "default_filter": "name__value", "display_labels": ["name__value"], "attributes": [ { "name": "name", "kind": "Text", "unique": true }, { "name": "code", "kind": "Text", "optional": true }, { "name": "device_count", "kind": "Number", "optional": true } ] } ] } ] } EOF curl -s -o /dev/null -w 'HTTP %{http_code}\n' \
  -X POST 'http://127.0.0.1/api/schema/load?branch=main' \
  -H "X-INFRAHUB-KEY: $TOKEN" -H 'Content-Type: application/json' \
  --data-binary @/tmp/demo-schema.json

The schema is applied asynchronously. Confirm the new kind is live:

curl -s -H "X-INFRAHUB-KEY: $TOKEN" \
  'http://127.0.0.1/api/schema?branch=main' | grep -c DemoSite

A count of 1 or more confirms DemoSite is now part of your schema.

11

Create and read back an object

Now create an object of the kind you just defined, using a GraphQL mutation:

curl -s -X POST 'http://127.0.0.1/graphql' \
  -H "X-INFRAHUB-KEY: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"mutation { DemoSiteCreate(data: {name: {value: \"london-1\"}, code: {value: \"LON1\"}, device_count: {value: 24}}) { ok object { id name { value } } } }"}'

Then read it back with a GraphQL query:

curl -s -X POST 'http://127.0.0.1/graphql' \
  -H "X-INFRAHUB-KEY: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"query { DemoSite(name__value: \"london-1\") { edges { node { id name { value } code { value } device_count { value } } } } }"}'

The response contains the object you created, with the values you wrote. That round trip (define a schema, create an object, read it back) is Infrahub working end to end.

You can see the same object in the web interface under the object explorer.

12

Work on a branch

Branching is the defining capability of Infrahub. Create a branch and make changes against it. The main branch stays untouched until you merge.

curl -s -X POST 'http://127.0.0.1/graphql' \
  -H "X-INFRAHUB-KEY: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"mutation { BranchCreate(data: {name: \"demo-change\", description: \"trial change\"}) { ok object { id name } } }"}'

List your branches to confirm:

curl -s -X POST 'http://127.0.0.1/graphql' \
  -H "X-INFRAHUB-KEY: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"query { Branch { id name description } }"}'

Queries and mutations can then be scoped to that branch by posting to /graphql/demo-change instead of /graphql.

In the web interface, the branch selector at the top of the page switches the whole view to your branch. Proposed Changes is where a branch is reviewed and merged.

13

Change the admin password

The password from Step 4 is generated for your VM, but you should still set your own. In the web interface, open the account menu and change the password there.

Managing the service

Stop, start or restart the whole stack through systemd:

sudo systemctl stop infrahub.service
sudo systemctl start infrahub.service
sudo systemctl restart infrahub.service

Follow the logs for a single component:

cd /opt/infrahub && sudo docker compose --env-file .env logs -f infrahub-server

From a cold start, the stack takes a couple of minutes to become fully healthy. The graph database and the task manager both initialize before the server accepts traffic.

Where things live

  • /opt/infrahub/docker-compose.yml: the appliance Compose stack
  • /opt/infrahub/.env: every generated per-VM secret (root-only, 0600)
  • /opt/infrahub/upstream-docker-compose.yml.reference: the Compose file of upstream at the pinned tag, for reference
  • /var/lib/infrahub: the dedicated data disk, which is the Docker data-root and holds the graph, the task database, artifacts and Git repositories
  • /root/infrahub-credentials.txt: your per-VM admin password and API token (root-only, 0600)
  • /usr/share/doc/sac/third-party-licences/: bundled component license notices and verbatim license texts

Enabling HTTPS

Infrahub is served over plain HTTP on port 80, so the image works immediately on any network. For anything beyond evaluation, put TLS in front of it.

You have two options. Use an Azure Application Gateway or Front Door to terminate TLS and forward to port 80. Or run a reverse proxy on the VM itself with a certificate from your own CA or Let's Encrypt.

If you terminate TLS elsewhere, restrict the NSG rule for port 80 to the address of the proxy, so the plain HTTP port is not reachable from the internet.

Backing up

Everything stateful lives on the data disk at /var/lib/infrahub, so an Azure disk snapshot of that volume captures your source of truth, the task history, artifacts and synchronized repositories together.

Take the snapshot with the stack stopped for a consistent point in time:

sudo systemctl stop infrahub.service
# take your Azure disk snapshot here
sudo systemctl start infrahub.service

Licensing

Infrahub is licensed under the Apache License 2.0. This image also bundles third-party components under their own terms. Their license notices and verbatim license texts ship on the image:

ls /usr/share/doc/sac/third-party-licences/
  • Neo4j 2025.10.1 Community Edition: GPLv3. This is the Community edition, which is freely redistributable. It is not Neo4j Enterprise Edition. The notice includes a written offer for the corresponding source.
  • Redis 8.4.0: triple-licensed under RSALv2, SSPLv1 and AGPLv3. SecureAnyCloud elects SSPLv1 for this bundled component.
  • RabbitMQ and PostgreSQL: RabbitMQ is under MPL-2.0 and PostgreSQL under the PostgreSQL License.

Support

SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com and include your Azure subscription ID and the VM name.

Deploy on Azure

Launch Infrahub 1.10.5 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure