docs/sources/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/custom-model-rules.md
Custom model rules in Knowledge Graph allow you to define how entities are discovered and modeled based on Prometheus queries. These rules enable you to create custom entity types, define their relationships, and specify how they should be enriched with additional data.
For information about managing entities and relations in the Knowledge Graph UI, refer to Manage entities and relations.
Create a file named custom-model-rules.tf and add the following:
# Basic custom model rule for services
resource "grafana_asserts_custom_model_rules" "basic_service" {
provider = grafana.asserts
name = "basic-service-model"
rules {
entity {
type = "Service"
name = "service"
defined_by {
query = "up{job!=''}"
label_values = {
service = "job"
}
literals = {
_source = "up_query"
}
}
}
}
}
Define service entities with environment scoping and relationship mappings:
# Advanced service model with environment scoping
resource "grafana_asserts_custom_model_rules" "advanced_service" {
provider = grafana.asserts
name = "advanced-service-model"
rules {
entity {
type = "Service"
name = "workload | service | job"
scope = {
namespace = "namespace"
env = "asserts_env"
site = "asserts_site"
}
lookup = {
workload = "workload | deployment | statefulset | daemonset | replicaset"
service = "service"
job = "job"
proxy_job = "job"
}
defined_by {
query = "up{job!='', asserts_env!=''}"
label_values = {
service = "service"
job = "job"
workload = "workload"
namespace = "namespace"
}
literals = {
_source = "up_with_workload"
}
}
defined_by {
query = "up{job='maintenance'}"
disabled = true
}
}
}
}
Define multiple entity types in a single configuration:
# Multiple entity types in a single model
resource "grafana_asserts_custom_model_rules" "multi_entity" {
provider = grafana.asserts
name = "kubernetes-entities"
rules {
# Service entity
entity {
type = "Service"
name = "service"
scope = {
namespace = "namespace"
cluster = "cluster"
}
defined_by {
query = "up{service!=''}"
label_values = {
service = "service"
namespace = "namespace"
cluster = "cluster"
}
}
}
# Pod entity
entity {
type = "Pod"
name = "Pod"
scope = {
namespace = "namespace"
cluster = "cluster"
}
lookup = {
service = "service"
workload = "workload"
}
defined_by {
query = "kube_pod_info{pod!=''}"
label_values = {
Pod = "pod"
namespace = "namespace"
cluster = "cluster"
service = "service"
}
literals = {
_entity_type = "Pod"
}
}
}
# Namespace entity
entity {
type = "Namespace"
name = "namespace"
scope = {
cluster = "cluster"
}
defined_by {
query = "kube_namespace_status_phase{namespace!=''}"
label_values = {
namespace = "namespace"
cluster = "cluster"
}
}
}
}
}
Create service entities with multiple data sources and enrichment:
# Service entity with enrichment from multiple sources
resource "grafana_asserts_custom_model_rules" "enriched_service" {
provider = grafana.asserts
name = "enriched-service-model"
rules {
entity {
type = "Service"
name = "service"
enriched_by = [
"prometheus_metrics",
"kubernetes_metadata",
"application_logs"
]
scope = {
environment = "asserts_env"
region = "asserts_site"
team = "team"
}
lookup = {
deployment = "workload"
Pod = "pod"
container = "container"
}
# Primary definition from service up metrics
defined_by {
query = "up{service!='', asserts_env!=''}"
label_values = {
service = "service"
environment = "asserts_env"
region = "asserts_site"
team = "team"
}
literals = {
_primary_source = "service_up"
}
}
# Secondary definition from application metrics
defined_by {
query = "http_requests_total{service!=''}"
label_values = {
service = "service"
environment = "environment"
version = "version"
}
literals = {
_secondary_source = "http_metrics"
}
}
# Disabled definition for testing
defined_by {
query = "test_metric{service!=''}"
disabled = true
}
}
}
}
Define database and infrastructure entity models:
# Database and infrastructure entity models
resource "grafana_asserts_custom_model_rules" "infrastructure" {
provider = grafana.asserts
name = "infrastructure-entities"
rules {
# Database entity
entity {
type = "Database"
name = "database_instance"
scope = {
environment = "env"
region = "region"
}
lookup = {
host = "instance"
port = "port"
db_name = "database"
}
defined_by {
query = "mysql_up{instance!=''}"
label_values = {
database_instance = "instance"
database = "database"
env = "environment"
region = "region"
}
literals = {
_db_type = "mysql"
}
metric_value = "1"
}
defined_by {
query = "postgres_up{instance!=''}"
label_values = {
database_instance = "instance"
database = "datname"
env = "environment"
}
literals = {
_db_type = "postgresql"
}
}
}
# Load balancer entity
entity {
type = "LoadBalancer"
name = "lb_instance"
scope = {
environment = "env"
}
defined_by {
query = "haproxy_up{proxy!=''}"
label_values = {
lb_instance = "instance"
proxy = "proxy"
env = "environment"
}
literals = {
_lb_type = "haproxy"
}
}
}
}
}
grafana_asserts_custom_model_rulesManage Knowledge Graph custom model rules through the Grafana API. This resource allows you to define custom entity models based on Prometheus queries with advanced mapping and enrichment capabilities.
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The name of the custom model rules. This field is immutable and forces recreation if changed. |
rules | list(object) | Yes | The rules configuration containing entity definitions. Refer to rules block for details. |
Each rules block supports the following:
| Name | Type | Required | Description |
|---|---|---|---|
entity | list(object) | Yes | List of entity definitions. Refer to entity block for details. |
Each entity block supports the following:
| Name | Type | Required | Description |
|---|---|---|---|
type | string | Yes | The type of the entity (for example, Service, Pod, Namespace). |
name | string | Yes | The name pattern for the entity. Can include pipe-separated alternatives. |
defined_by | list(object) | Yes | List of queries that define this entity. Refer to defined_by block for details. |
disabled | bool | No | Whether this entity is disabled. Defaults to false. |
enriched_by | list(string) | No | List of enrichment sources for the entity. |
lookup | map(string) | No | Lookup mappings for the entity to relate different label names. |
scope | map(string) | No | Scope labels that define the boundaries of this entity type. |
defined_by blockEach defined_by block supports the following:
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The Prometheus query that defines this entity. |
disabled | bool | No | Whether this query is disabled. Defaults to false. |
label_values | map(string) | No | Label value mappings for extracting entity attributes from query results. |
literals | map(string) | No | Literal value mappings for adding static attributes to entities. |
metric_value | string | No | Metric value to use from the query result. |
{{< admonition type="note" >}}
When disabled = true is set for a defined_by query, only the query field is used for matching. All other fields in the block are ignored.
{{< /admonition >}}
Consider the following best practices when creating custom model rules with Terraform.
scope parameter to organize entities by environment, region, or teamdisabled flag to temporarily disable problematic queries during debugginglookup mappings to establish relationships between different entity typesenriched_by to specify additional data sources for entity enrichmentliterals to add static metadata that helps with entity identificationlabel_values to extract dynamic attributes from your metricsAfter applying the Terraform configuration, verify that: