Skip to main content

Custom Data

If the integrations that Cortex provides out-of-the-box isn't sufficient, you can easily extend the metadata using Custom Data.

Summary

Custom Data allows you to include additional information about all the services in your catalog, to be used for:

  • Querying with CQL
  • Applying Scorecards rules to data from internal tools
  • Viewing extra details in the Catalog

Custom Data can be added to services programmatically via a REST API or through defined manually in a Service Descriptor.

Use Cases

Cataloging

The Catalog contains lots of useful metadata about services, including ownership and data from integrations. However, you may have your own custom fields that you want to include that would make exploring the catalog easier.

These can include things like:

  • Which AWS zones is this deployed in?
  • What databases does the service consume?
  • When was the last successful CI run?
tip

If the answers to these questions fit a pre-enumerated list, consider using Service Groups. Custom data for cataloging makes the most sense when the data is more freeform/flexible.

The data in the Catalog can then be queried against through our CQL-powered Query Builder, or even to quickly view information directly in the Service Homepage.

Scorecards

You may want to write Scorecard rules that apply to information outside of data provided by our out-of-the-box integrations. For example, you may want to write rules that depend on data from your own internal tools, or vulnerability scan data that happens as part of a CI pipeline.

Using the Custom Data API to push data into Cortex is a great way to extend your Scorecards. You can even send in entire JSON payloads, and use jq to process them in a Scorecard or even as an input to a custom OPA Policy as a Scorecard rule.

Defining Custom Data

There are a few ways you can add Custom Data to a service, including the Service Descriptor, a POST REST API, and a simple webhook.

Service Descriptor

The simplest way to describe information in the yaml is to define an object.

x-cortex-custom-metadata:
my-key: the value
another-key:
this: is
an: object
final-key:
- also
- use
- lists!

Custom data can be of any type, including scalars (strings, numbers, booleans), objects, and lists.

Adding Descriptions

If you want to add a description to one of your pieces of data, just define it with the value key set explicitly.

x-cortex-custom-metadata:
my-key:
value: the actual value for the key
description: This is the description

API

You can also pipe custom data directly into Cortex if you know the Service Tag, by POSTing to /api/v1/services/tags/{service-identifier}/custom-data, where the service-identifier is the x-cortex-tag of the service.

The request body is the following, in JSON format. See API Docs for authentication details.

FieldTypeDescription
keystringThe key for custom data
valueobject (string, boolean, number, list, ...)Value to set for the service
descriptionstring (optional)An optional description for the data to be displayed in the dashboard.
YAML is the source of truth

If a key has already been set through the Service Descriptor, an API call will NOT overwrite the existing value. Instead, it will simply return the existing value - you'll notice the source value in the response body is YAML.

To explicitly overwrite values set in the YAML file, use the force=true flag as a query param. If you find yourself using the force flag, you should likely remove the field from the YAML file since it is no longer the source of truth, or update the value in the cortex.yaml file instead.

Read more about the Source Hierarcy.

Bulk Upload

If you're trying to upload multiple keys for a single service, or many keys for many services, you can use the bulk upload endpoint.

Just POST data in the following format to /api/v1/services/custom-data:

{
"values":{
"<service tag>":[
{
"key":"foo",
"value":"bar",
"description":"foobar"
}
],
"<another service tag>":[
{
"key":"foo",
"value":{
"my-data":"my-value",
"complex": "data",
"v": 0
}
}
]
}
}

For each service tag, you can include multiple key/value objects. The object conforms to the same shape as the single upload API.

Webhook

In some cases, you may not have obvious access to the Service Tag, or ability to add authentication headers. For example, if you're unable to connect Cortex directly to your SonarQube instance, you may want to dump SonarQube webhook data into Cortex as Custom Data.

"Custom Data Webhooks" give you the ability to create unique URLs that you can use to directly POST arbitrary JSON payloads without auth or an explicit service tag in the URL. Instead, you can tell Cortex how to process the payload to map it to a service (e.g., the payload may include a data.tag field that corresponds to the Service Tag).

To create a Webhook URL:

  1. Visit Settings → Custom Integrations
  2. Create a new Custom Integration
  3. Give this webhook a human-readable name, like SonarQube Webhook.
  4. Define a jq expression that Cortex will use to extract the Service Tag from the payload, for example .data.service.tag. If the tag that Cortex extracts from the payload is not exactly equal to the Service Tag, the endpoint will throw a 400.
  5. Add a key under which the data will be stored for services, which is the same as the key when using the Service Descriptor or REST API.
  6. Save the integration, and copy the provided webhook URL.
  7. cURL any JSON your heart desires to this URL!

The data can be used exactly the same way as Custom Data defined through the Service Descriptor or the API.

Custom Integrations Settings

Data Source Hierarchy

What happens when you try to define the same key from multiple sources? There's a hierarchy that's applied:

  1. The Service Descriptor is the source of truth. If a key is defined there, the API or webhooks cannot override the key.
  2. The API and Webhook approaches are at the same level and can override each other.

You can override keys defined in the YAML by adding a force=true param when using the API, but there's guarantee – when the Service Descriptor is eventually re-processed, the data provided via the API will be overwritten.