Create custom model rules using Terraform
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.
Basic custom model rules
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"
}
}
}
}
}Advanced service model with scope and lookup
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
}
}
}
}Multi-entity model configuration
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"
}
}
}
}
}Complex entity with enrichment
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
}
}
}
}Database and infrastructure entities
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"
}
}
}
}
}Resource reference
grafana_asserts_custom_model_rules
Manage 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.
Arguments
Rules block
Each rules block supports the following:
Entity block
Each entity block supports the following:
defined_by block
Each defined_by block supports the following:
Note
When
disabled = trueis set for adefined_byquery, only thequeryfield is used for matching. All other fields in the block are ignored.
Best practices
Entity models
- Design your entity models to reflect your actual infrastructure and application architecture
- Use descriptive names for custom model rules that indicate their purpose and scope
- Start with basic entity definitions and gradually add complexity as needed
- Define clear entity scopes using the
scopeparameter to organize entities by environment, region, or team
Query design and performance
- Write efficient Prometheus queries that don’t overload your monitoring system
- Test your Prometheus queries independently before using them in model rules
- Use specific label filters to reduce the scope of your queries where possible
- Consider the cardinality implications of your entity definitions
- Use the
disabledflag to temporarily disable problematic queries during debugging
Relationships and enrichment
- Use
lookupmappings to establish relationships between different entity types - Leverage
enriched_byto specify additional data sources for entity enrichment - Map Prometheus labels to entity attributes using clear and descriptive names
- Use meaningful
literalsto add static metadata that helps with entity identification
Label and attribute management
- Establish consistent labeling conventions across your infrastructure
- Use
label_valuesto extract dynamic attributes from your metrics - Document the meaning and expected values of custom literals
- Ensure label names match across different entity definitions for proper relationship discovery
Validation
After applying the Terraform configuration, verify that:
- Custom model rules are applied in your Knowledge Graph instance
- Entities are being discovered according to your defined queries
- Entity relationships and enrichment are working as expected
- Entity graphs display the correct entity types and connections
- Queries perform well without causing excessive load



