Datadog
Port's Datadog integration allows you to model Datadog resources in Port and ingest data into them.
SLO History, Service Metric and Service Dependency resources are not collected out of the box.
Follow the examples here to configure blueprints and resource mappings.
Setup
Choose your preferred installation method below. Not sure which to pick? See the installation methods overview.
Configuration
Port integrations use a YAML mapping block to ingest data from the third-party api into Port.
The mapping makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from the integration API.
Default mapping configuration
This is the default mapping configuration for this integration:
Default mapping configuration (click to expand)
deleteDependentEntities: true
createMissingRelatedEntities: true
enableMergeEntity: true
resources:
- kind: monitor
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"datadogMonitor"'
properties:
tags: .tags
monitorType: .type
overallState: .overall_state
thresholds: .thresholds
priority: .priority
createdBy: .creator.email
createdAt: .created
updatedAt: .modified
link: (\"https://app.datadoghq.com/monitors/\" + (.id | tostring))
relations:
owner_team_datadog: .tags | map(select(startswith("team:"))) | unique | map(split(":")[1])
service_datadog: .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
service:
combinator: '"and"'
rules:
- property: '"datadog_service_id"'
operator: '"in"'
value: .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
- kind: service
selector:
query: "true"
port:
entity:
mappings:
identifier: .attributes.schema.\"dd-service\"
title: .attributes.schema.\"dd-service\"
blueprint: '"datadogService"'
properties:
application: .attributes.schema.application
languages: .attributes.schema.languages
description: .attributes.schema.description
tags: .attributes.schema.tags
type: .attributes.schema.type
links: (\"https://app.datadoghq.com/services?selectedService=\" + (.attributes.schema.\"dd-service\"))
owners: '[.attributes.schema.contacts[]? | select(.type == "email") | .contact]'
relations:
owner_team_datadog: .team_it_doesnt_work_yet
- kind: slo
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"datadogSlo"'
properties:
tags: .tags
sloType: .type
description: .description
warningThreshold: .warning_threshold
targetThreshold: .target_threshold
createdBy: .creator.email
createdAt: .created_at | todate
updatedAt: .modified_at | todate
link: (\"https://app.datadoghq.com/slo/manage?sp=\" + (\"%5B%7B%22p%22%3A%7B%22id%22%3A%22\" + (.id | tostring) + \"%22%7D%2C%22i%22%3A%22slo-panel%22%7D%5D\"))
relations:
monitors: .monitor_ids | map(tostring)
owner_team_datadog: .monitor_tags + .tags | map(select(startswith("team:"))) | unique | map(split(":")[1])
service_datadog: .monitor_tags + .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
service:
combinator: '"and"'
rules:
- property: '"datadog_service_id"'
operator: '"in"'
value: .monitor_tags + .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
- kind: host
selector:
query: '[.sources[] | . as $source | ["azure", "gcp", "gce", "aws"] | contains([$source])] | any(.)'
port:
entity:
mappings:
identifier: .id | tostring
title: .aws_name // .host_name
blueprint: '"datadogCloudResource"'
properties:
up: .up
host_name: .host_name
platform: .meta.platform
is_muted: .is_muted
machine: .meta.machine
description: .description
sources: .sources
cpu_cores: .meta.cpuCores
agent_version: .meta.agent_version
tags: .tags_by_source
- kind: host
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .aws_name // .host_name
blueprint: '"datadogHost"'
properties:
up: .up
host_name: .host_name
platform: .meta.platform
is_muted: .is_muted
machine: .meta.machine
description: .description
sources: .sources
cpu_cores: .meta.cpuCores
agent_version: .meta.agent_version
tags: .tags_by_source
- kind: user
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .attributes.name
blueprint: '"datadogUser"'
properties:
email: .attributes.email
handle: .attributes.handle
status: .attributes.status
disabled: .attributes.disabled
verified: .attributes.verified
createdAt: .attributes.created_at | todate
- kind: team
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .id
blueprint: '"datadogTeam"'
- kind: team
selector:
query: "true"
includeMembers: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .attributes.name
blueprint: '"datadogTeam"'
properties:
description: .attributes.description
handle: .attributes.handle
userCount: .attributes.user_count
summary: .attributes.summary
createdAt: .attributes.created_at | todate
relations:
members: if .__members then .__members[].id else [] end
- kind: role
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .attributes.name
blueprint: '"datadogRole"'
properties:
createdAt: .attributes.created_at | todate
modifiedAt: .attributes.modified_at | todate
custom: if .attributes.managed == true then false else true end
userCount: .attributes.user_count
Mapping & selectors per resource
Use the explorer below to view sample payloads and the resulting Port entities for each resource type. For additional resources and advanced configurations, see the examples page.
Port's Datadog integration syncs Service entities from service definitions in the Datadog Service Catalog API (via the GET /api/v2/services/definitions endpoint).
That is separate from APM services, which Datadog discovers automatically from APM tracing. The integration does not fetch APM-discovered services.
Set up live events
- Hosted by Port
- Self-hosted
The Datadog integration keeps your catalog up to date in near real time through two complementary channels. Both are available for all installation methods.
The two channels carry different event types and are not interchangeable. Configure both for full coverage:
| Channel | Carries |
|---|---|
| 1. Monitor notifications | Monitor state transitions (for example OK → Alert → OK) and service dependency updates |
| 2. Audit trail forwarding | Configuration changes to monitors, SLOs, users, roles and teams, plus restriction policy changes |
The Datadog audit trail records user and API initiated actions, so a monitor changing state on its own does not appear in it. The overallState property on your monitor entities is therefore updated in real time only through channel 1; with channel 2 alone it refreshes on the next scheduled resync.
Live events base URL
For integrations installed using the Hosted by Port method, you can obtain the live events base URL from the Get an integration API. The response includes liveEventsUuid and liveEventsIngestHostname in the appSpec section.
Call the endpoint with your integration's identifier:
curl -X GET \
'https://api.port.io/v1/integration/<INTEGRATION_IDENTIFIER>' \
-H 'Authorization: Bearer <PORT_ACCESS_TOKEN>'
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
In the response, look for the following fields under spec.appSpec:
{
"spec": {
"appSpec": {
"liveEventsUuid": "abcdefghijk",
"liveEventsIngestHostname": "ingest.ocean.getport.io"
}
}
}
Combine them to build the live events base URL:
https://<liveEventsIngestHostname>/live-events/<liveEventsUuid>
For example, with the values above, the live events base URL is:
https://ingest.ocean.getport.io/live-events/abcdefghijk
This is the same URL configured for the integration.
1. Monitor notifications (automatic)
When the integration starts, it automatically registers a Datadog webhook and creates a monitor notification rule. Any monitor matching the configured scope sends state change events directly to Port - no manual setup required.
To register these objects automatically, the Datadog application key used by the integration must have the following permissions:
| Permission | Used for |
|---|---|
integrations_read | Read existing webhook configuration |
create_webhooks | Create the Port webhook |
manage_integrations | Update the Port webhook |
monitors_read | List existing notification rules |
monitor_config_policy_write | Create or update the monitor notification rule |
The following monitor alert types are supported: ci_pipelines_alert, ci_tests_alert, composite_monitor, error_tracking_alert, event_alert, event_v2_alert, log_alert, monitor_slo_alert, metric_slo_alert, outlier_monitor, process_alert, query_alert_monitor, rum_alert, service_check, synthetics_alert, trace_analytics_alert.
Use the monitorNotificationRuleScope configuration parameter to control which monitors trigger notifications (default: service:*, which captures all service monitors).
Example values:
service:*- all service monitors (default).service:my-service AND env:prod- monitors for a specific service and environment only.
Note that the default scope only matches monitors carrying a service tag. If your monitors are tagged differently, widen the scope accordingly, or those monitors will not send state change events to Port.
Manual registration (optional)
The webhook and the notification rule can also be created by a Datadog administrator rather than by the integration. The integration consumes the resulting events either way - automatic registration is a convenience, not a requirement.
You might prefer manual registration if you:
- manage Datadog resources as code, or through a change management process
- want explicit control over the naming, scope, and lifecycle of both objects
- want to reuse an existing webhook or notification rule instead of having a second one created
- cannot grant the application key the write permissions listed above, for example under a read-only credential policy
Automatic registration is the only part being replaced. You still need a live events base URL configured, and the application key still needs read access to monitors so the integration can fetch each monitor when an event arrives.
Registration steps (click to expand)
Step 1: Create the webhook in Datadog
- In Datadog, go to Integrations > Webhooks.
- Click New Webhook and fill in the following:
- Name: Any name you choose. Note it down - you will reference it in the next step.
- URL: Append
/integration/webhook/monitor-eventsto your live events base URL. - Payload: Enable Encode as JSON and enter the payload below exactly as shown.
- Custom headers: If you have set a
webhookSecret, add the following, replacing<your_webhook_secret>with its value. Skip this if you have not set a webhook secret.{"X-Port-Ocean-Webhook-Secret": "<your_webhook_secret>"}
- Save the webhook.
The payload template:
{
"id": "$ID",
"message": "$TEXT_ONLY_MSG",
"priority": "$PRIORITY",
"last_updated": "$LAST_UPDATED",
"event_type": "$EVENT_TYPE",
"event_url": "$LINK",
"service": "$HOSTNAME",
"service_id": "$SERVICE_ID",
"service_name": "$SERVICE_NAME",
"creator": "$USER",
"title": "$EVENT_TITLE",
"date": "$DATE",
"org_id": "$ORG_ID",
"org_name": "$ORG_NAME",
"alert_id": "$ALERT_ID",
"alert_metric": "$ALERT_METRIC",
"alert_status": "$ALERT_STATUS",
"alert_title": "$ALERT_TITLE",
"alert_type": "$ALERT_TYPE",
"tags": "$TAGS",
"body": "$EVENT_MSG"
}
Events missing event_type or alert_id are discarded, as are events missing org_name in multi-organization installations. Discards are silent, so an altered payload is difficult to diagnose.
Step 2: Create the monitor notification rule
- In Datadog, go to Monitors > Settings > Notification Rules.
- Create a new rule and add the webhook from step 1 as a recipient. Webhook recipients take the form
@webhook-<name>, where<name>is the webhook name from step 1. - Set the rule's scope to match the monitors you want to send state change events to Port.
- Save the rule.
Alternatively, add @webhook-<name> to the notification message of each individual monitor you want covered. A notification rule is usually preferable, since it applies to many monitors at once.
Step 3: Disable automatic registration
Set the skipWebhookCreation configuration parameter to true (integration.config.skipWebhookCreation for Helm installations), so the integration no longer attempts automatic registration on startup. It continues to receive and process live events normally.
2. Audit trail forwarding (manual setup required)
The integration processes Datadog audit trail events to reflect near-real-time changes to monitors, users, teams, SLOs, and roles in your catalog.
| Catalog entity | Datadog audit event |
|---|---|
| Monitor | Monitor |
| Monitor | Access Management (restriction policy) |
| SLO | SLO |
| SLO | Access Management (restriction policy) |
| User | Access Management |
| Role | Access Management |
| Team | Teams Management |
Datadog does not support managing audit trail forwarding destinations via its API. You must configure this destination manually in the Datadog UI, as described below.
To configure audit trail forwarding in Datadog:
- In Datadog, go to Organization Settings > Compliance > Audit Trail Settings.
- Under Forward Audit Events > Custom Destinations, click New Destination.
- Choose HTTP as the destination type and fill in the following:
- Destination URL: Append
/integration/webhook/audit-trailto your live events base URL. - Query filter: Enter the following query so that only events this integration handles are forwarded:
@asset.type:(monitor OR slo) OR @evt.name:("Access Management" OR "Teams Management")
- Authentication: Select Request Header and provide:
- Header name:
X-Port-Ocean-Webhook-Secret - Header value: The value of your
webhookSecretconfiguration. If you have not set a webhook secret, enter any random string - Datadog requires a non-empty value, and the integration will accept all requests regardless.
- Header name:
- Enable GZIP compression for payloads: Disable this option. It is enabled by default, but the integration expects uncompressed payloads.
- Destination URL: Append
- Save the destination.
BaseUrl & webhook configuration
To enable real-time updates of the data in your software catalog, you need to define the liveEvents.baseUrl parameter.
This parameter should be set to the URL of your Datadog integration instance, which needs to have the option to setup webhooks via HTTP requests/receive HTTP requests, so ensure the network is configured accordingly.
- If Datadog and the integration are in the same cluster/network: Use an internal URL (e.g., a Kubernetes service DNS name).
For Kubernetes deployments, create a service to expose the integration pod and use the service URL asliveEvents.baseUrl. If both the source system and integration are in the same cluster, an internal ClusterIP service is sufficient. - If Datadog is external to the integration's network: The integration must be exposed via an ingress, load balancer, or public URL that Datadog can reach.
If liveEvents.baseUrl is not provided, the integration will continue to function correctly. In such a configuration, to retrieve the latest information from the target system, the scheduledResyncInterval parameter has to be set, or a manual resync will need to be triggered through Port's UI.
To test webhooks or live event delivery to your local environment, expose your local pod or service to the internet using ngrok (e.g. ngrok http http://localhost:8000)
This integration supports live events, allowing real-time updates to your software catalog without waiting for the next scheduled sync.
Supported live event triggers (click to expand)
Monitoring Alerts:
- ci_pipelines_alert
- ci_tests_alert
- composite_monitor
- error_tracking_alert
- event_alert
- event_v2_alert
- log_alert
- monitor_slo_alert
- metric_slo_alert
- outlier_monitor
- process_alert
- query_alert_monitor
- rum_alert
- service_check
- synthetics_alert
- trace_analytics_alert
Audit Trail:
- Monitor
- Monitor (restriction policy)
- SLO
- SLO (restriction policy)
- User
- Role
- Team
The Datadog integration keeps your catalog up to date in near real time through two complementary channels. Both are available for all installation methods.
The two channels carry different event types and are not interchangeable. Configure both for full coverage:
| Channel | Carries |
|---|---|
| 1. Monitor notifications | Monitor state transitions (for example OK → Alert → OK) and service dependency updates |
| 2. Audit trail forwarding | Configuration changes to monitors, SLOs, users, roles and teams, plus restriction policy changes |
The Datadog audit trail records user and API initiated actions, so a monitor changing state on its own does not appear in it. The overallState property on your monitor entities is therefore updated in real time only through channel 1; with channel 2 alone it refreshes on the next scheduled resync.
1. Monitor notifications (automatic)
When the integration starts, it automatically registers a Datadog webhook and creates a monitor notification rule. Any monitor matching the configured scope sends state change events directly to Port - no manual setup required.
To register these objects automatically, the Datadog application key used by the integration must have the following permissions:
| Permission | Used for |
|---|---|
integrations_read | Read existing webhook configuration |
create_webhooks | Create the Port webhook |
manage_integrations | Update the Port webhook |
monitors_read | List existing notification rules |
monitor_config_policy_write | Create or update the monitor notification rule |
The following monitor alert types are supported: ci_pipelines_alert, ci_tests_alert, composite_monitor, error_tracking_alert, event_alert, event_v2_alert, log_alert, monitor_slo_alert, metric_slo_alert, outlier_monitor, process_alert, query_alert_monitor, rum_alert, service_check, synthetics_alert, trace_analytics_alert.
Use the monitorNotificationRuleScope configuration parameter to control which monitors trigger notifications (default: service:*, which captures all service monitors).
Example values:
service:*- all service monitors (default).service:my-service AND env:prod- monitors for a specific service and environment only.
Note that the default scope only matches monitors carrying a service tag. If your monitors are tagged differently, widen the scope accordingly, or those monitors will not send state change events to Port.
Manual registration (optional)
The webhook and the notification rule can also be created by a Datadog administrator rather than by the integration. The integration consumes the resulting events either way - automatic registration is a convenience, not a requirement.
You might prefer manual registration if you:
- manage Datadog resources as code, or through a change management process
- want explicit control over the naming, scope, and lifecycle of both objects
- want to reuse an existing webhook or notification rule instead of having a second one created
- cannot grant the application key the write permissions listed above, for example under a read-only credential policy
Automatic registration is the only part being replaced. You still need a live events base URL configured, and the application key still needs read access to monitors so the integration can fetch each monitor when an event arrives.
Registration steps (click to expand)
Step 1: Create the webhook in Datadog
- In Datadog, go to Integrations > Webhooks.
- Click New Webhook and fill in the following:
- Name: Any name you choose. Note it down - you will reference it in the next step.
- URL: Append
/integration/webhook/monitor-eventsto the base URL you configured in theliveEvents.baseUrlHelm parameter. - Payload: Enable Encode as JSON and enter the payload below exactly as shown.
- Custom headers: If you have set a
webhookSecret, add the following, replacing<your_webhook_secret>with its value. Skip this if you have not set a webhook secret.{"X-Port-Ocean-Webhook-Secret": "<your_webhook_secret>"}
- Save the webhook.
The payload template:
{
"id": "$ID",
"message": "$TEXT_ONLY_MSG",
"priority": "$PRIORITY",
"last_updated": "$LAST_UPDATED",
"event_type": "$EVENT_TYPE",
"event_url": "$LINK",
"service": "$HOSTNAME",
"service_id": "$SERVICE_ID",
"service_name": "$SERVICE_NAME",
"creator": "$USER",
"title": "$EVENT_TITLE",
"date": "$DATE",
"org_id": "$ORG_ID",
"org_name": "$ORG_NAME",
"alert_id": "$ALERT_ID",
"alert_metric": "$ALERT_METRIC",
"alert_status": "$ALERT_STATUS",
"alert_title": "$ALERT_TITLE",
"alert_type": "$ALERT_TYPE",
"tags": "$TAGS",
"body": "$EVENT_MSG"
}
Events missing event_type or alert_id are discarded, as are events missing org_name in multi-organization installations. Discards are silent, so an altered payload is difficult to diagnose.
Step 2: Create the monitor notification rule
- In Datadog, go to Monitors > Settings > Notification Rules.
- Create a new rule and add the webhook from step 1 as a recipient. Webhook recipients take the form
@webhook-<name>, where<name>is the webhook name from step 1. - Set the rule's scope to match the monitors you want to send state change events to Port.
- Save the rule.
Alternatively, add @webhook-<name> to the notification message of each individual monitor you want covered. A notification rule is usually preferable, since it applies to many monitors at once.
Step 3: Disable automatic registration
Set the skipWebhookCreation configuration parameter to true (integration.config.skipWebhookCreation for Helm installations), so the integration no longer attempts automatic registration on startup. It continues to receive and process live events normally.
2. Audit trail forwarding (manual setup required)
The integration processes Datadog audit trail events to reflect near-real-time changes to monitors, users, teams, SLOs, and roles in your catalog.
| Catalog entity | Datadog audit event |
|---|---|
| Monitor | Monitor |
| Monitor | Access Management (restriction policy) |
| SLO | SLO |
| SLO | Access Management (restriction policy) |
| User | Access Management |
| Role | Access Management |
| Team | Teams Management |
Datadog does not support managing audit trail forwarding destinations via its API. You must configure this destination manually in the Datadog UI, as described below.
To configure audit trail forwarding in Datadog:
- In Datadog, go to Organization Settings > Compliance > Audit Trail Settings.
- Under Forward Audit Events > Custom Destinations, click New Destination.
- Choose HTTP as the destination type and fill in the following:
- Destination URL: Append
/integration/webhook/audit-trailto the base URL you configured in theliveEvents.baseUrlHelm parameter. - Query filter: Enter the following query so that only events this integration handles are forwarded:
@asset.type:(monitor OR slo) OR @evt.name:("Access Management" OR "Teams Management")
- Authentication: Select Request Header and provide:
- Header name:
X-Port-Ocean-Webhook-Secret - Header value: The value of your
webhookSecretconfiguration. If you have not set a webhook secret, enter any random string - Datadog requires a non-empty value, and the integration will accept all requests regardless.
- Header name:
- Enable GZIP compression for payloads: Disable this option. It is enabled by default, but the integration expects uncompressed payloads.
- Destination URL: Append
- Save the destination.
Monitoring and sync status
To learn more about how to monitor and check the sync status of your integration, see the relevant documentation.
Examples
To view and test the integration's mapping against examples of the third-party API responses, use the jq playground in your data sources page. Find the integration in the list of data sources and click on it to open the playground.
Examples of blueprints and the relevant integration configurations can be found on the datadog examples page
Relevant Guides
For relevant guides and examples, see the guides section.