Skip to main content

datadog

Monitoring, alerting and reporting platform for cloud platforms and applications.

Provider Summary

total services: 18
total resources: 615

See also: [SHOW] [DESCRIBE] [REGISTRY]


Installation​

To pull the latest version of the datadog provider, run the following command:

REGISTRY PULL datadog;

To view previous provider versions or to pull a specific provider version, see here.

Authentication​

The following system environment variables are used for authentication by default (the same variables the Datadog Terraform provider and the official API clients read):

  • DD_API_KEY - Datadog API key, sent as the DD-API-KEY header (see API keys)
  • DD_APP_KEY - Datadog application key, sent as the DD-APPLICATION-KEY header (see application keys)

These variables are sourced at runtime (from the local machine or as CI variables/secrets). The application key's scopes determine which resources are readable and writable.

Using different environment variables

To use different environment variables (instead of the defaults), use the --auth flag of the stackql program. For example:


AUTH='{ "datadog": { "type": "custom", "location": "header", "name": "DD-API-KEY", "credentialsenvvar": "YOUR_DD_API_KEY_VAR", "successor": { "type": "custom", "location": "header", "name": "DD-APPLICATION-KEY", "credentialsenvvar": "YOUR_DD_APP_KEY_VAR" }}}'
stackql shell --auth="${AUTH}"

or using PowerShell:


$Auth = "{ 'datadog': { 'type': 'custom', 'location': 'header', 'name': 'DD-API-KEY', 'credentialsenvvar': 'YOUR_DD_API_KEY_VAR', 'successor': { 'type': 'custom', 'location': 'header', 'name': 'DD-APPLICATION-KEY', 'credentialsenvvar': 'YOUR_DD_APP_KEY_VAR' }}}"
stackql.exe shell --auth=$Auth

Datadog site (region)​

Every request goes to https://api.{site}. The site server variable defaults to datadoghq.com (US1) and is resolved from the DD_SITE environment variable when it is set - the same convention as the Datadog Agent and API clients:

export DD_SITE=datadoghq.eu # EU1; also us3.datadoghq.com, us5.datadoghq.com, ap1.datadoghq.com, ap2.datadoghq.com, ddog-gov.com

A WHERE site = '...' predicate on any query overrides the environment for that statement, so one session can address organizations on different sites. Queries never need a site predicate otherwise; the parameter is omitted from the examples in this documentation for that reason.

Provider scope​

The provider merges the Datadog v1 and v2 REST APIs into 18 services (monitoring, dashboards, organization, logs, metrics, security, service_management, integrations, ...). Resources from the v2 API return the JSON:API row shape - id, type, attributes and relationships columns - so attributes are addressed with json_extract; v1 resources (monitors, dashboards, hosts, SLOs, synthetics, log indexes and pipelines) return flat columns. Column and parameter names are snake_case; the handful of camelCase wire names are aliased.

List operations with cursor pagination (page[cursor]) are traversed automatically; a SQL LIMIT is pushed to the API's page size parameter. Query parameters such as filter[query], filter[from] or tags are used directly as WHERE predicates.

Example Queries​

Try the following queries using stackql shell, or run them from a script or CI pipeline with stackql exec.

Monitors​

Every monitor with its state - the first query most teams run:

SELECT id, name, type, overall_state, tags
FROM datadog.monitoring.monitors;

Only alerting monitors, using the API's own filter:

SELECT id, name, overall_state
FROM datadog.monitoring.monitors
WHERE group_states = 'alert';

Search monitors with the monitor search syntax:

SELECT id, name, status, type
FROM datadog.monitoring.monitor_search_results
WHERE query = 'type:metric status:alert';

Users, roles and keys​

User audit with status and login method:

SELECT
id,
json_extract(attributes, '$.email') AS email,
json_extract(attributes, '$.status') AS status,
json_extract(attributes, '$.disabled') AS disabled,
json_extract(attributes, '$.created_at') AS created_at
FROM datadog.organization.users;

Roles, and the users assigned to a role:

SELECT id, json_extract(attributes, '$.name') AS name, json_extract(attributes, '$.user_count') AS user_count
FROM datadog.organization.roles;

SELECT id, json_extract(attributes, '$.email') AS email
FROM datadog.organization.role_users
WHERE role_id = 'a633c0c8-91b4-11f0-a729-da7ad0900010';

API keys by age - rotate the old ones:

SELECT
id,
json_extract(attributes, '$.name') AS name,
json_extract(attributes, '$.created_at') AS created_at,
json_extract(attributes, '$.last4') AS last4
FROM datadog.organization.api_keys
ORDER BY created_at;

Dashboards and SLOs​

SELECT id, title, layout_type, author_handle, modified_at
FROM datadog.dashboards.dashboards;

SELECT id, name, type, json_extract(thresholds, '$[0].target') AS target
FROM datadog.service_management.slos;

Infrastructure​

Hosts reporting to Datadog, with their apps and mute state:

SELECT host_name, up, is_muted, apps, last_reported_time
FROM datadog.infrastructure.hosts;

SELECT total_up, total_active
FROM datadog.infrastructure.host_totals;

Active metrics reported in the last hour (from is a required Unix timestamp):

SELECT metrics
FROM datadog.metrics.active_metrics
WHERE "from" = strftime('%s', 'now') - 3600;

Logs, audit and usage​

Log indexes and their retention:

SELECT name, num_retention_days, daily_limit
FROM datadog.logs.indexes;

Audit events for the last day - cursor-paginated, the time window pushed down as filter[from]:

SELECT
id,
json_extract(attributes, '$.timestamp') AS timestamp,
json_extract(attributes, '$.attributes.evt.name') AS event,
json_extract(attributes, '$.attributes.usr.email') AS actor
FROM datadog.organization.audit_logs
WHERE "filter[from]" = 'now-1d';

Usage summary for a month:

SELECT date, infra_host_top99p, apm_host_top99p, logs_ingested_bytes_sum
FROM datadog.organization.usage_summary
WHERE start_month = '2026-08';

Provision, mutate and tear down​

Mutations use the same SQL grammar. A v1 resource (monitor) takes its fields as columns; a v2 resource (role, API key, downtime) takes the JSON:API data document. A monitor end to end:

-- create
INSERT INTO datadog.monitoring.monitors (name, type, query, message, tags)
SELECT 'High CPU on web hosts',
'metric alert',
'avg(last_5m):avg:system.cpu.user{env:prod} by {host} > 90',
'CPU above 90% on {{host.name}} @slack-ops',
'["team:web", "managed-by:stackql"]';

-- validate a definition without creating it
EXEC datadog.monitoring.monitors.validate_monitor
@type = 'metric alert',
@query = 'avg(last_5m):avg:system.cpu.user{env:prod} > 90',
@name = 'High CPU on web hosts';

-- replace the definition (the v1 monitor API updates with PUT)
REPLACE datadog.monitoring.monitors
SET name = 'High CPU on web hosts', type = 'metric alert',
query = 'avg(last_5m):avg:system.cpu.user{env:prod} by {host} > 95'
WHERE monitor_id = 12345678;

-- remove it
DELETE FROM datadog.monitoring.monitors
WHERE monitor_id = 12345678;

A role (v2) end to end:

INSERT INTO datadog.organization.roles (data)
SELECT '{"type": "roles", "attributes": {"name": "read-only-auditors"}}';

UPDATE datadog.organization.roles
SET data = '{"id": "<role-id>", "type": "roles", "attributes": {"name": "auditors"}}'
WHERE role_id = '<role-id>';

DELETE FROM datadog.organization.roles
WHERE role_id = '<role-id>';

Schedule a downtime for a scope:

INSERT INTO datadog.service_management.downtimes (data)
SELECT '{"type": "downtime", "attributes": {"message": "release window", "scope": "env:prod",
"monitor_identifier": {"monitor_tags": ["team:web"]},
"schedule": {"start": "2026-09-01T22:00:00Z", "end": "2026-09-01T23:00:00Z"}}}';

Services​