Provider: DataDog/datadog
~> 3.46
Resource:datadog_dashboard_json
Terraform:>= 1.5.0
- Overview
- Architecture
- Prerequisites
- Quick Start
- File Structure
- Authentication
- Variable Reference
- Output Reference
- Usage Examples
- Importing an Existing Dashboard
- Multi-Environment Deployment
- CI/CD Integration
- Troubleshooting
- FAQ
This Terraform configuration provisions a Datadog dashboard from an exported JSON file using the official DataDog/datadog Terraform provider — the standard, HashiCorp-partner-tier provider for managing Datadog resources via Infrastructure as Code.
Why
DataDog/datadogand not a community module?
Unlike AWS where community wrappers liketerraform-aws-modules/eks/awsexist, Datadog's native Terraform provider already covers every resource type (dashboards, monitors, SLOs, downtimes, etc.) in a production-ready manner. The provider is the standard module.
- Reads an exported Datadog dashboard JSON file from disk
- Overrides title, description, template variables, and layout via Terraform variables
- Filters widget types on/off without editing the JSON
- Provisions the dashboard using
datadog_dashboard_json - Outputs the dashboard ID, URL, widget statistics, and more
terraform/
├── main.tf # Everything: provider, variables, locals,
│ # resource, and outputs in one file
└── terraform.tfvars.example # Example variable values
┌──────────────────┐ ┌───────────────────┐ ┌──────────────────┐
│ JSON Dashboard │─────▶│ Terraform Locals │─────▶│ datadog_ │
│ Export File │ │ (overrides, │ │ dashboard_json │
│ │ │ filtering) │ │ resource │
└──────────────────┘ └───────────────────┘ └────────┬─────────┘
│
▼
┌──────────────────┐
│ Datadog API │
│ (live dashboard)│
└──────────────────┘
| Requirement | Minimum Version | Notes |
|---|---|---|
| Terraform | >= 1.5.0 |
Download |
| Datadog Account | — | API + Application key with dashboard write permissions |
| JSON File | — | Exported from Datadog UI or hand-crafted |
# 1. Navigate to the terraform directory
cd terraform
# 2. Set your Datadog credentials
export DD_API_KEY="your-datadog-api-key"
export DD_APP_KEY="your-datadog-app-key"
# 3. (Optional) Copy and edit the example tfvars
cp terraform.tfvars.example terraform.tfvars
# 4. Initialise
terraform init
# 5. Preview the changes
terraform plan
# 6. Apply
terraform apply
# 7. Open the dashboard URL printed in outputs| File | Purpose |
|---|---|
main.tf |
Single consolidated file containing provider config, all variables, local computations, the datadog_dashboard_json resource, and all outputs. |
terraform.tfvars.example |
Example variable values — copy to terraform.tfvars and customise. |
../eks_container_vulnerability.json |
Default source JSON dashboard definition. |
The provider supports two authentication methods (can be mixed):
export DD_API_KEY="your-api-key"
export DD_APP_KEY="your-app-key"
# Optional:
export DD_HOST="https://api.datadoghq.eu" # For EU regionWhen environment variables are set, leave datadog_api_key and datadog_app_key at their default null.
# terraform.tfvars (DO NOT commit to version control)
datadog_api_key = "your-api-key"
datadog_app_key = "your-app-key"data "vault_generic_secret" "datadog" {
path = "secret/datadog"
}
provider "datadog" {
api_key = data.vault_generic_secret.datadog.data["api_key"]
app_key = data.vault_generic_secret.datadog.data["app_key"]
}| Variable | Type | Default | Sensitive | Description |
|---|---|---|---|---|
datadog_api_key |
string |
null |
Yes | Datadog API key. Recommended: set DD_API_KEY env var instead. |
datadog_app_key |
string |
null |
Yes | Datadog Application key. Recommended: set DD_APP_KEY env var instead. |
datadog_api_url |
string |
"https://api.datadoghq.com" |
No | API endpoint URL. Change for non-US regions: US3 (us3.datadoghq.com), US5 (us5.datadoghq.com), EU1 (datadoghq.eu), AP1 (ap1.datadoghq.com), GOV (ddog-gov.com). |
validate_credentials |
bool |
true |
No | Whether the provider validates API/App keys during terraform init. Set to false for CI pipelines that validate separately. |
| Variable | Type | Default | Description |
|---|---|---|---|
dashboard_json_path |
string |
"../eks_container_vulnerability.json" |
Relative or absolute path to the Datadog dashboard JSON export. Must be a valid JSON file with title and widgets keys. |
| Variable | Type | Default | Description |
|---|---|---|---|
dashboard_title_override |
string |
null |
If set, replaces the title from the JSON file. Useful for multi-env deploys (e.g. "[STAGING] Container Vulns"). |
dashboard_description_override |
string |
null |
If set, replaces the description from the JSON file. |
is_read_only |
bool |
false |
When true, only the Terraform service account can edit the dashboard in the Datadog UI. |
notify_list |
list(string) |
[] |
User handles (emails) notified when the dashboard definition changes. |
| Variable | Type | Default | Description |
|---|---|---|---|
dashboard_tags |
list(string) |
["terraform-managed", "container-security", "vulnerability-management"] |
Tags attached to the dashboard for filtering inside Datadog. |
environment |
string |
"production" |
Added as env:<value> tag. Use values like production, staging, dev. |
team |
string |
"platform-engineering" |
Added as team:<value> tag. Use your team name. |
| Variable | Type | Default | Validation | Description |
|---|---|---|---|---|
layout_type |
string |
"ordered" |
ordered | free |
ordered = responsive grid; free = pixel positioning. |
reflow_type |
string |
"fixed" |
auto | fixed |
Only applies to ordered layouts. fixed preserves explicit widths; auto reflows to screen. |
| Variable | Type | Default | Description |
|---|---|---|---|
default_template_variable_values |
map(string) |
{} |
Overrides default values of template variables defined in the JSON. Key = variable name, value = new default. Example: { status = "running" }. |
template_variable_presets |
list(object) |
[] |
Quick-filter presets shown in the dashboard dropdown. Each preset has a name and template_variables list. See examples. |
| Variable | Type | Default | Description |
|---|---|---|---|
enable_widgets |
object |
{} (all true) |
Toggle individual widget types. Any type set to false is stripped from the dashboard. Supported types: note, query_value, timeseries, toplist, treemap, sunburst, group, table, change, distribution, geomap, heatmap, hostmap, image, log_stream, alert_graph, alert_value, check_status, free_text, iframe, event_stream, event_timeline, monitor_summary, service_map, slo. |
| Variable | Type | Default | Description |
|---|---|---|---|
severity_thresholds |
object |
See below | Thresholds for severity-based conditional formatting. Extend the locals block to consume these. |
severity_thresholds defaults:
| Field | Default | Description |
|---|---|---|
critical_warning |
10 |
Warning threshold for critical severities |
critical_danger |
100 |
Danger threshold for critical severities |
high_warning |
50 |
Warning threshold for high severities |
high_danger |
200 |
Danger threshold for high severities |
medium_warning |
100 |
Warning threshold for medium severities |
medium_danger |
500 |
Danger threshold for medium severities |
| Output | Type | Description |
|---|---|---|
dashboard_id |
string |
The unique ID assigned by Datadog. |
dashboard_url |
string |
Direct URL to the dashboard in the Datadog web UI. |
dashboard_title |
string |
Resolved title after overrides. |
dashboard_description |
string |
Resolved description after overrides. |
total_widgets |
number |
Count of top-level widgets. |
widget_types |
list(string) |
Distinct widget types (e.g. ["note","group","timeseries"]). |
template_variable_names |
list(string) |
Template variable names. |
template_variable_details |
list(object) |
Full template variable config (name, prefix, default). |
tags |
list(string) |
All tags applied to the dashboard. |
is_read_only |
bool |
Read-only status. |
dashboard_json_preview |
string |
First 500 chars of the rendered JSON (debugging). |
# terraform.tfvars
dashboard_json_path = "../eks_container_vulnerability.json"
environment = "production"
team = "security"export DD_API_KEY="..."
export DD_APP_KEY="..."
terraform init && terraform applydashboard_json_path = "../eks_container_vulnerability.json"
dashboard_title_override = "[STAGING] Container Image Vulnerabilities"
environment = "staging"default_template_variable_values = {
status = "running"
image_registry = "123456789.dkr.ecr.us-east-1.amazonaws.com"
}template_variable_presets = [
{
name = "Production Running"
template_variables = [
{ name = "status", values = ["running"] }
]
},
{
name = "All Images"
template_variables = [
{ name = "status", values = ["*"] },
{ name = "image_name", values = ["*"] }
]
}
]enable_widgets = {
treemap = false
sunburst = false
note = false
}datadog_api_url = "https://api.datadoghq.eu"If the dashboard already exists in Datadog and you want Terraform to manage it:
# 1. Get the dashboard ID from the Datadog URL
# e.g. https://app.datadoghq.com/dashboard/abc-def-ghi
# Dashboard ID = abc-def-ghi
# 2. Import into Terraform state
terraform import datadog_dashboard_json.this abc-def-ghi
# 3. Verify
terraform plan
# Should show "No changes"- Open the dashboard in Datadog
- Click the gear icon (⚙️) → Export Dashboard JSON
- Save the file to your project directory
- Update
dashboard_json_pathin yourterraform.tfvars
Use Terraform workspaces or separate variable files:
# Create workspaces
terraform workspace new production
terraform workspace new staging
# Deploy to staging
terraform workspace select staging
terraform apply -var="environment=staging" \
-var='dashboard_title_override=[STAGING] Container Vulnerabilities'
# Deploy to production
terraform workspace select production
terraform apply -var="environment=production"# production
terraform apply -var-file="envs/production.tfvars"
# staging
terraform apply -var-file="envs/staging.tfvars"name: Deploy Datadog Dashboard
on:
push:
branches: [main]
paths: ['terraform/**', '*.json']
jobs:
deploy:
runs-on: ubuntu-latest
env:
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
DD_APP_KEY: ${{ secrets.DATADOG_APP_KEY }}
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.7.0"
- run: terraform -chdir=terraform init
- run: terraform -chdir=terraform plan -out=tfplan
- run: terraform -chdir=terraform apply -auto-approve tfplandeploy_dashboard:
image: hashicorp/terraform:1.7
variables:
DD_API_KEY: $DATADOG_API_KEY
DD_APP_KEY: $DATADOG_APP_KEY
script:
- cd terraform
- terraform init
- terraform apply -auto-approve
only:
- mainError: error validating API key
Fix: Ensure DD_API_KEY and DD_APP_KEY are set and valid. Check that the keys have dashboard write permissions.
Error: Error in function call — invalid character ...
Fix: Validate the JSON file syntax:
python -m json.tool < ../eks_container_vulnerability.json > /dev/nullIf terraform plan shows no changes but the UI dashboard differs:
# Re-import from Datadog
terraform import datadog_dashboard_json.this <dashboard-id>Error: Failed to query available provider packages
Fix: Run terraform init -upgrade to refresh provider cache.
Q: Can I use this with multiple JSON files?
A: Yes. Change dashboard_json_path per workspace/environment or create multiple resource blocks.
Q: Does this support monitors or SLOs?
A: This file is focused on dashboards. The same DataDog/datadog provider supports datadog_monitor, datadog_service_level_objective, and 50+ other resources.
Q: Why datadog_dashboard_json instead of datadog_dashboard?
A: datadog_dashboard_json accepts the raw API payload, giving 1-to-1 parity with the Datadog API and making it trivial to import UI-exported dashboards. datadog_dashboard uses native HCL blocks which provide better type checking but require significant rewriting of the JSON.
Q: How do I destroy the dashboard?
A: terraform destroy removes the dashboard from Datadog.
MIT License. See LICENSE file for details.