Getting Started with Infrahub

Getting Started with Infrahub
In: NetDevOps Network

If you're in the Network Automation space or attended one of the last two Autocon events, you might have come across a new tool called 'Infrahub' from OpsMill. I've been keeping an eye on it and experimenting with the product for some time now. In this blog post, we'll cover how to install Infrahub, what it is, and walk through a simple example to get you started. Let's dive in.

Infrahub Installation

Installing Infrahub is straightforward if you're familiar with Docker and have it installed. For this example, I'm using an Ubuntu 22.04 server with Docker and Docker Compose already set up. Here's all I had to do.

  1. Clone the Infrahub repository
  2. Run a single docker command to bring up the services
suresh@infrahub:~$ git clone https://github.com/opsmill/infrahub.git
Cloning into 'infrahub'...
remote: Enumerating objects: 95389, done.
remote: Counting objects: 100% (5707/5707), done.
remote: Compressing objects: 100% (2801/2801), done.
remote: Total 95389 (delta 3698), reused 4482 (delta 2877), pack-reused 89682
Receiving objects: 100% (95389/95389), 136.18 MiB | 40.26 MiB/s, done.
Resolving deltas: 100% (69451/69451), done.
suresh@infrahub:~$ cd infrahub/
suresh@infrahub:~/infrahub$ docker-compose up -d
[+] Running 70/7
 ✔ message-queue 10 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      		0B/0B      Pulled
 ✔ task-manager 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      	0B/0B      Pulled
 ✔ cache 8 layers [⣿⣿⣿⣿⣿⣿⣿⣿]      					0B/0B      Pulled
 ✔ infrahub-server Pulled                                               
 ✔ database 5 layers [⣿⣿⣿⣿⣿]      					0B/0B      Pulled
 ✔ task-manager-db 11 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      	0B/0B      Pulled
 ✔ task-worker 16 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      	0B/0B      Pulled
[+] Running 16/16
 ✔ Network infrahub_default              Created
 ✔ Volume "infrahub_storage_data"        Created
 ✔ Volume "infrahub_workflow_data"       Created
 ✔ Volume "infrahub_git_data"            Created
 ✔ Volume "infrahub_git_remote_data"     Created
 ✔ Volume "infrahub_database_data"       Created
 ✔ Volume "infrahub_database_logs"       Created
 ✔ Volume "infrahub_workflow_db"         Created
 ✔ Container infrahub-database-1         Healthy
 ✔ Container infrahub-cache-1            Healthy
 ✔ Container infrahub-task-manager-db-1  Healthy
 ✔ Container infrahub-message-queue-1    Healthy
 ✔ Container infrahub-task-manager-1     Healthy
 ✔ Container infrahub-infrahub-server-1  Started
 ✔ Container infrahub-task-worker-2      Started
 ✔ Container infrahub-task-worker-1      Started

This command will take a few minutes to pull the necessary images and start the applications. Once everything is running, open your browser and navigate to http://<your_ip>:8000. Use the default credentials admin for the username and infrahub for the password to log in.

You can also install the CLI utility called infrahubctl on top of Infrahub. This tool will be useful as we proceed through the blog.

It's a good practice to use a virtual environment (venv) to keep your dependencies isolated and avoid conflicts with other projects. First, create and activate a virtual environment. Once your virtual environment is activated, you can install infrahub using the pip command.

# Create a virtual environment named 'venv'
python3 -m venv venv

# Activate the virtual environment
source venv/bin/activate
pip install 'infrahub-sdk[ctl]'
(venv) suresh@infrahub:~/infrahub$ infrahubctl version
Infrahub: v1.0.8
Python SDK: v1.1.0

Okay, How Do I Add My Device?

Once you log in, you might be wondering how to add your devices, interfaces, and inventory, but you'll notice there's no predefined place for it. This is where Infrahub differs from other tools like NetBox.

NetBox is such a mature, great product that when you log in for the first time, you have tons of tabs to manage your inventory. Infrahub, on the other hand, doesn’t come with any of that 'out of the box.'

Where Infrahub shines is in letting you manage the 'schema.' But what exactly is a 'schema'? The way I think about it is that a schema is a blueprint that defines the structure of your data. It specifies the nodes (like devices and interfaces), their attributes, and the relationships between them. This allows you to customize how you organize and manage your inventory in Infrahub.

Suppose all you want to do is add your devices and their interfaces. Well, you just need to create a simple 'schema' file and define what you want to see or manage.

Schema to Manage Devices and Interfaces

Let’s look at an example of how to create a simple schema to add a device and its interfaces. I’ll be following the official documentation for this, and I encourage you to check it out if you want to learn more.

You can load the schema into Infrahub using the infrahubctl CLI tool we installed earlier. Before using infrahubctl, you need to generate an API key and pass it to the CLI tool.

  1. Navigate to Account Settings > Token in the web GUI to create a new token.
  2. Once the API key is created, copy it and add it as an environment variable in your CLI.
export INFRAHUB_API_TOKEN="180f9fdb-11c5-abbd-3d6b-c51bf2bf29c6"

Schema File

As mentioned earlier, I’m using an example from the official documentation to create a schema for managing devices and their interfaces. First, you need to define the schema as a YAML file. This file can be stored anywhere, including in a Git repository for version control.

For simplicity, I’m placing the file called schema_guide.yml in my home directory for this example.

---
version: "1.0"
nodes:
  - name: Device
    namespace: Network
    human_friendly_id: ['hostname__value']
    attributes:
      - name: hostname
        kind: Text
        unique: true
      - name: model
        kind: Text
    relationships:
      - name: interfaces
        cardinality: many
        peer: NetworkInterface
        kind: Component
  - name: Interface
    namespace: Network
    attributes:
      - name: name
        kind: Text
      - name: description
        kind: Text
        optional: true
    relationships:
      - name: device
        cardinality: one
        peer: NetworkDevice
        optional: false
        kind: Parent

Understanding the schema might seem tricky at first, but once you get the hang of it, it’s fairly straightforward to use. In this example, I’ve defined two nodes - Device and Interface and the relationship between them.

  • Device Node
    This node includes attributes like hostname and model. The hostname is marked as unique. The Device node also has a relationship with the Interface node.
    • Cardinality - Indicates that a device can have multiple interfaces.
    • Kind - Specifies that the interface is a component of the device.
  • Interface Node
    The Interface node has attributes like name and an optional description. It also has a relationship back to the Device node.
    • Cardinality - Indicates that an interface belongs to exactly one device.
    • Kind - Specifies that the interface is a parent-child relationship with the device.

By defining this schema, you’re essentially setting up a structured way to manage devices and their interfaces within Infrahub.

💡
You can define a human_friendly_id for each node, which makes interacting with the API easier. For example, instead of using the ID of a device in an API call, you can simply pass its hostname. In this case, hostname__value serves as a human-readable identifier. I plan to cover this in more detail in a future blog post with GraphQL.

Let’s load this schema into Infrahub using the following command.

infrahubctl schema load ~/schema_guide.yml 

schema '/home/suresh/schema_guide.yml' loaded successfully
 1 schema processed in 7.981 seconds.

Now, we should be able to create a new Device and add Interfaces Infrahub as shown below.

Infrahub Branch

Before we move forward, it’s worth noting another great feature of Infrahub - it supports 'branches.' This means you can create a branch to experiment with your schema or inventory without affecting your current environment. You can merge the changes once you're happy with them into the main branch.

Let’s create a new branch called network-vendor using the following command. Inside this branch, we will modify the schema to include a 'Vendor' field for the devices. We will also set this field as optional.

infrahubctl branch create network-vendor

Branch 'network-vendor' created successfully (180fefef-025e-3d68-c511dddca3bc).

Once the branch is created, you can view it in the web GUI under Change Control > Branches.

I'm going to update the schema to include the 'Vendor' attribute and then load this modified schema into the branch we just created.

---
version: "1.0"
nodes:
  - name: Device
    namespace: Network
    human_friendly_id: ['hostname__value']
    attributes:
      - name: hostname
        kind: Text
        unique: true
      - name: model
        kind: Text
      - name: vendor
        kind: Text
        optional: true
    relationships:
      - name: interfaces
        cardinality: many
        peer: NetworkInterface
        kind: Component
  - name: Interface
    namespace: Network
    attributes:
      - name: name
        kind: Text
      - name: description
        kind: Text
        optional: true
    relationships:
      - name: device
        cardinality: one
        peer: NetworkDevice
        optional: false
        kind: Parent
infrahubctl schema load --branch network-vendor ~/schema_guide.yml 
 
 schema '/home/suresh/schema_guide.yml' loaded successfully
 1 schema processed in 9.764 seconds.

While we are inside the new branch, you can check if everything looks as good as expected and if you are happy with the changes, you can merge the branch to the main branch.

You can also create a new branch via the web GUI. Let's create a new branch and modify an existing device.

For the sake of simplicity, I'm going to modify an existing device under this new branch to include the vendor name as shown below.

Once we make the changes, we can view the diff right from the GUI to see what has changed.

Schema Library

If you are thinking 'Oh, do I need to now go and create my own schema', hold your thought because there are plenty of schemas readily available from Opsmill's GitHub repo. Feel free to check it out but here is an example of importing the base schema and some extensions from the library.

git clone https://github.com/opsmill/schema-library.git

Cloning into 'schema-library'...
remote: Enumerating objects: 1173, done.
remote: Counting objects: 100% (483/483), done.
remote: Compressing objects: 100% (328/328), done.
remote: Total 1173 (delta 210), reused 322 (delta 155), pack-reused 690 (from 1)
Receiving objects: 100% (1173/1173), 288.38 KiB | 3.95 MiB/s, done.
Resolving deltas: 100% (558/558), done.
infrahubctl schema load --branch base-schema /home/suresh/schema-library/base
infrahubctl schema load --branch base-schema /home/suresh/schema-library/extensions/vlan/
infrahubctl schema load --branch base-schema /home/suresh/schema-library/extensions/location_minimal/

Here you can see there are plenty of attributes for 'Network Device' like status, device type, platform, serial, location and more.

0:00
/0:27

Closing Thoughts

I hope this gives you an idea of what Infrahub is and the problems it aims to solve. I’m still new to Infrahub and learning as I go. In the comments, let me know what you think about this approach and whether you’d prefer to manage your own schema. I’m planning to write more content on Infrahub, so don’t forget to subscribe.

References

https://docs.infrahub.app/

Table of Contents
Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.