Define and visualize your functional organization structure and hierarchies in OpsLevel.


OpsLevel now supports organizational hierarchies within our Teams model

We've updated Teams to support hierarchies and all the other goodies that Groups had to offer. If you are a customer who joined us before October 16th, 2023 we'll be working with you to migrate your Groups into Teams over the coming weeks. If you joined after that date or we've already migrated you, all the info you need to understand or model hierarchies in OpsLevel is now available over in our Teams guide.

Groups allow you to define and visualize your functional organization structure in OpsLevel. You can arrange teams into a series of groups that represent the logical business components of your organization. Groups also makes it easier to view reports for teams in order to see how they are performing.

Creating Groups

Groups can be created from the Groups page by clicking New Group.

New Group Button

A modal will open where you can fill out the group name, description, managers, parent group, and the teams that directly belong to the group you are creating. Teams and groups can only belong directly to one parent group.

Group Modal

Note: There is a limit of 100 groups that can be created per account. If you need more, please reach out to us at [email protected].

Adding a New Subgroup

If you want to create a group whose parent has already been created, you can click the ... icon next to the group and then select Add Subgroup.

Add Subgroup

This will open the modal with the parent group pre-filled, making group creation faster.

Modal with Parent Group Pre-filled

Viewing Organization Structure

You can view all your groups and teams in a tree view on the groups page. Parent Groups can be expanded to see all the subgroups and teams that directly belong to it.

Group Tree View

You can also search for a group or team by its name to quickly find it. We will filter out the other groups and teams and expand all of its parent groups so you can see where it is in the organization.

Group Search

Group Details

Clicking on a group allows you to see the description, manager(s), direct subgroups, teams and services. Teams that directly belong to the group or belong to any of the group’s descendant subgroups are shown. Services owned by the group’s direct teams or any of the teams of its descendant subgroups are shown as well. At the top of the page, breadcrumbs containing the group’s parent groups until the root are shown so you know where the group is in the org.

Group Details

Filtering by Group

Filtering services to see which ones are owned by a functional group of teams is a lot easier with groups. Instead of creating a filter with all the teams in it and having to keep that list up to date, you can now create a filter with a group.

Group Filter

In the example above, we will filter down to the services that are owned by teams that directly belong to the Platform group or belong to any of Platform’s descendant subgroups.

Reporting by Groups

You can filter the maturity report by group to easily view how teams and services are performing across a functional grouping. The reports table contains the group that the team directly belongs to.

Reporting by Group

Example: Creating Groups with the OpsLevel CLI

In addition to creating Groups in our UI, our:

are all options for configuring and maintaining your Groups. Below you’ll find an example using the GitHub Teams API and the OpsLevel CLI (plus some bash and jq too).

#!/usr/bin/env bash

TEMP_FILE=$(mktemp -d)/group.yaml
TEAMS_DATA=$(gh api -H "Accept: application/vnd.github.v3+json" /orgs/OpsLevel/teams)

for row in $(echo "${TEAMS_DATA}" | jq -r '.[] | @base64'); do
    _jq() {
     echo ${row} | base64 --decode | jq -r ${1}
    cat << EOF > ${TEMP_FILE}
name: "$(_jq '.slug')"
description: "$(_jq '.description')"
    cat ${TEMP_FILE} | opslevel create group -f -

for row in $(echo "${TEAMS_DATA}" | jq -r '.[] | @base64'); do
    _jq() {
     echo ${row} | base64 --decode | jq -r ${1}
    if [ $(_jq '.parent.slug') != "null" ]; then
        cat << EOF > ${TEMP_FILE}
  alias: "$(_jq '.parent.slug')"
        cat ${TEMP_FILE} | opslevel update group "$(_jq '.slug')" -f -