The following CLI tools are required to run the commands on this page:
| Tool | Minimum version | Notes |
|---|---|---|
7.50 | Must be built with HTTP/2 support ( | |
Azure CLI ( | 2.40 | Required for service principal and role assignment commands. Verify with |
1.5 | Optional Used to extract values from JSON responses. Verify with |
Actions in this section must be performed by an Azure administrator with appropriate permissions.
Before running Azure CLI commands, ensure:
You have Azure CLI installed and authenticated (az login)
Your Azure account has one of the following:
Application Administrator role in Microsoft Entra ID
Cloud Application Administrator role in Microsoft Entra ID
microsoft.directory/servicePrincipals/create permission.
And one of the following:
Owner role at the target scope (subscription or management group)
User Access Administrator role at the target scope
A custom role with Microsoft.Authorization/roleAssignments/write permission
For Management Group monitoring scope, you need role assignment permissions at the management group level, not just individual subscriptions.
Decide which monitoring scope you'll use and gather the required IDs:
| Monitoring scope | Required information |
|---|---|
| Management Group ID (found in Azure portal under Management groups) |
| Subscription ID (found in Azure portal under Subscriptions) |
Dynatrace can poll Azure Monitor metrics only from subscriptions where the Microsoft.Insights resource provider is registered. Azure often registers it automatically—for example, when you create an alert rule or configure diagnostic settings—but not in every subscription. If it isn't registered, Dynatrace still discovers your topology but doesn't ingest metrics.
Check every subscription in your monitoring scope. For a Management Group scope, check every subscription beneath it. To register a resource provider, you need the Contributor or Owner role on the subscription. The Dynatrace service principal can't register it.
To check and register it in the Azure portal:
Microsoft.Insights. If the status is NotRegistered, select it and then select Register. If the status is Registering, wait until it shows Registered.To check it with Azure CLI:
az provider show --namespace Microsoft.Insights --subscription <SUBSCRIPTION_ID> --query registrationState --output tsv
If the output isn't Registered, run the following command. With --wait, the command returns once registration is complete.
az provider register --namespace Microsoft.Insights --subscription <SUBSCRIPTION_ID> --wait
For details, see Azure resource providers and types.
Create a programmatic access permission policy with the following permissions:
ALLOWsettings:objects:read,settings:objects:write,settings:schemas:readWHERE settings:schemaId = "builtin:hyperscaler-authentication.connections.azure";ALLOWextensions:definitions:read,extensions:definitions:write,extensions:configurations:read,extensions:configurations:writeWHERE extensions:extension-name = "com.dynatrace.extension.da-azure";
Create a service user and assign the policy created in step 1 to it.
Create a platform token for the service user created in step 2 with the following scopes:
extensions:configurations:readextensions:configurations:writeextensions:definitions:readextensions:definitions:writesettings:schemas:readsettings:objects:readsettings:objects:write
If this is the first time an Azure connection is created in this Dynatrace environment, install the Azure extension. For details, see Hub capabilities API - POST an extension 2.0 to environment.
curl -X POST \'<YOUR_ENVIRONMENT_URL>/api/v2/hub/extensions2/com.dynatrace.extension.da-azure/actions/addToEnvironment' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \-H 'Accept: application/json'
Replace the following placeholders with your values:
<YOUR_ENVIRONMENT_URL>: URL of your Dynatrace environment (for example, https://abc12345.apps.dynatrace.com).<YOUR_BEARER_TOKEN>: Platform token created in step 3.A complete Azure monitoring setup requires two resources:
The shell commands on this page use \ for line continuation (bash/zsh). On Windows, replace \ with a backtick (`) in PowerShell, or ^ in command prompt.
The monitoring configuration requires an Azure connection to access your Azure environment. Dynatrace supports two authentication methods:
| Authentication method | Description | Notes |
|---|---|---|
Federated identity Recommended | Uses federated identity credentials. | More secure, passwordless authentication |
Uses a service principal with client secret. | Password-based authentication |
Federated identity credentials provide passwordless authentication and are more secure than client secrets.
This is the recommended approach for production environments.
Prepare the request payload.
[{"value": {"federatedIdentityCredential": {"consumers": ["SVC:com.dynatrace.da"]},"name": "<CONNECTION_NAME>","type": "federatedIdentityCredential"},"schemaId": "builtin:hyperscaler-authentication.connections.azure"}]
Replace the <CONNECTION_NAME> placeholder with a descriptive name for the connection.
Prepare the request to the REST API endpoint.
curl -X 'POST' \'<YOUR_ENVIRONMENT_URL>/platform/classic/environment-api/v2/settings/objects?validateOnly=false&adminAccess=false' \-H 'accept: application/json' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \-d '<REQUEST_PAYLOAD>'
Replace the following placeholders with your values:
<YOUR_BEARER_TOKEN>: Settings platform token
<YOUR_ENVIRONMENT_URL>: URL of your Dynatrace environment
<REQUEST_PAYLOAD>: Request payload prepared in the previous step
Send the request to the REST API endpoint. A successful request responds with an Azure connection ID (in objectId field):
[{"code": 200,"objectId": "vu9U3hXa3q0AAAABADRidWlsdGlu..."}]
objectId field). You'll need it for the next steps.Configure the federated identity credential in Microsoft Entra ID for your service principal using the object ID from the last step above.
Prepare for registering a new application in your Microsoft Entra ID tenant.
For details, see How to register an app in Microsoft Entra ID.
az ad sp create-for-rbac \--name "<CONNECTION_NAME>" \--create-password false \--query "{CLIENT_ID:appId, TENANT_ID:tenant}" \--output table
Replace the <CONNECTION_NAME> placeholder with a descriptive name for the connection (used in Dynatrace) and register a new application.
Prepare for creating a federated credential for the Microsoft Entra ID app. Dynatrace uses this for OIDC token exchange.
For details, see az ad app federated-credential.
az ad app federated-credential create \--id "<CLIENT_ID>" \--parameters '{"name": "<CONNECTION_NAME>-Federated-Credential", \"issuer": "https://token.dynatrace.com", \"subject": "dt:connection-id/<OBJECT_ID_FROM_STEP_1>", \"audiences": ["<DYNATRACE_ENVIRONMENT_ID>.apps.dynatrace.com/svc-id/com.dynatrace.da"]}'
Replace the following placeholders with your values and create a federated credential:
<CLIENT_ID>: Application (client) ID from the previous step<CONNECTION_NAME>: Descriptive name for the federated credential<OBJECT_ID_FROM_STEP_1>: The objectId returned in step 1<DYNATRACE_ENVIRONMENT_ID>: Your Dynatrace environment ID (for example, abc12345)<OBJECT_ID>: Object ID of the service principal (retrieved in step 3)Get the object ID of the service principal.
az ad sp show --id "<CLIENT_ID>" --query "{OBJECT_ID:id}" --output table
Assign the Monitoring Reader Azure RBAC built-in role to the service principal at the appropriate monitoring scope.
For the Management Group scope:
The --scope requires the management group resource ID, not its display name. To find it:
az account management-group list --query "[].{name:name, displayName:displayName}" --output table
Use the value in the Name column as <MANAGEMENT_GROUP_ID>.
az role assignment create \--assignee-object-id "<OBJECT_ID>" \--role "Monitoring Reader" \--scope "/providers/Microsoft.Management/managementGroups/<MANAGEMENT_GROUP_ID>" \--assignee-principal-type ServicePrincipal \--description "Dynatrace Monitoring"
For the Subscription scope:
az role assignment create \--assignee-object-id "<OBJECT_ID>" \--role "Monitoring Reader" \--scope "/subscriptions/<SUBSCRIPTION_ID>" \--assignee-principal-type ServicePrincipal \--description "Dynatrace Monitoring"
Verify the role assignment was successful:
az role assignment list --assignee-object-id "<OBJECT_ID>" --output table
You should see the Monitoring Reader role listed at your specified scope.
Prepare the updated payload.
{"value": {"federatedIdentityCredential": {"directoryId": "<TENANT_ID>","applicationId": "<CLIENT_ID>","consumers": ["SVC:com.dynatrace.da"]},"name": "<CONNECTION_NAME>","type": "federatedIdentityCredential"}}
Replace the following placeholders with your values:
<CONNECTION_NAME>: Descriptive name for the connection (same as in step 1)<TENANT_ID>: Microsoft Entra ID tenant (directory) ID<CLIENT_ID>: Application (client) ID of the service principalPrepare the PUT request to update the connection.
curl -X 'PUT' \'<YOUR_ENVIRONMENT_URL>/platform/classic/environment-api/v2/settings/objects/<AZURE_CONNECTION_ID>?validateOnly=false' \-H 'accept: application/json' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \-d '<UPDATE_PAYLOAD>'
Replace the following placeholders with your values and send the PUT request to update the connection.
<YOUR_BEARER_TOKEN>: Settings platform token<YOUR_ENVIRONMENT_URL>: URL of your Dynatrace environment<AZURE_CONNECTION_ID>: The objectId returned in step 1.<UPDATE_PAYLOAD>: Request payload prepared aboveA successful request responds with the updated Azure connection ID (in objectId field):
{"code": 200,"objectId": "vu9U3hXa3q0AAAABADRidWlsdGlu..."}
If the API call fails, validate that:
After successful completion, you can proceed to Create the Azure monitoring configuration.
The monitoring configuration is the blueprint that contains all the settings used on initial Azure onboarding (Azure services to poll for metrics, monitored regions, filtering rules, and more).
Settings can be modified post onboarding.
The monitoring configuration API schema is versioned.
Fetch the active version before constructing your request payload.
curl -X 'GET' \"<YOUR_ENVIRONMENT_URL>/platform/extensions/v2/extensions?filter=name='com.dynatrace.extension.da-azure'&add-fields=activeVersion" \-H 'accept: application/json' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
Replace the following placeholders with your values:
<YOUR_ENVIRONMENT_URL>: URL of your Dynatrace environment (for example, https://abc12345.apps.dynatrace.com)<YOUR_BEARER_TOKEN>: Settings platform token (from Prerequisites)The response contains the active schema version:
{"items": [{"extensionName": "com.dynatrace.extension.da-azure","version": "1.0.5","activeVersion": "1.0.0"}],"totalCount": 1}
Use the activeVersion value as <API_SCHEMA_VERSION> in the monitoring configuration payload.
Prepare the request payload.
To get all valid values for locationFiltering and featureSets, query the extension schema:
curl -X 'GET' \'<YOUR_ENVIRONMENT_URL>/platform/extensions/v2/extensions/com.dynatrace.extension.da-azure/<API_SCHEMA_VERSION>/schema' \-H 'accept: application/json' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
Extract valid location names:
| jq '[.enums["dynatrace.datasource.azure:location"].items[].value]'
Extract valid feature set names:
| jq '[.enums["FeatureSetsType"].items[].value]'
To allow telemetry signals-in-context and inventory on all relevant regions, the topology service must poll for topology signals on all regions where any signal is ingested.
{"scope": "integration-azure","value": {"enabled": true,"description": "<CONFIGURATION_NAME>","version": "<API_SCHEMA_VERSION>","featureSets": ["microsoft_compute.virtualmachines_essential","microsoft_storage.storageaccounts_essential","microsoft_web.sites_functionapp_essential"],"azure": {"subscriptionFilteringMode": "INCLUDE","credentials": [{"description": "<CONFIGURATION_NAME>","enabled": true,"connectionId": "<AZURE_CONNECTION_ID>","servicePrincipalId": "<CLIENT_ID>"}],"locationFiltering": ["<MONITORED_REGION_1>","<MONITORED_REGION_2>"]}}}
Replace the following placeholders with your values:
<CONFIGURATION_NAME>: Name of the monitoring configuration (letters, numbers, hyphens only; must start with a letter)<AZURE_CONNECTION_ID>: The objectId returned in the Azure connection step<CLIENT_ID>: Application (client) ID of the service principal<MONITORED_REGION_1>, <MONITORED_REGION_2>: Azure regions to monitor (for example, eastus, westeurope, northeurope)<API_SCHEMA_VERSION>: Active schema version from the Get API schema version stepSend the POST request.
curl -X 'POST' \'<YOUR_ENVIRONMENT_URL>/platform/extensions/v2/extensions/com.dynatrace.extension.da-azure/monitoring-configurations' \-H 'accept: application/json' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \-d '<REQUEST_PAYLOAD>'
Successful request responds with the new monitoring configuration ID (in objectId field):
{"objectId": "e4bf05f3-d829-3689-8dd4-a9d2aeab0607","code": 200}
Save the monitoring configuration ID (in objectId field). You'll need it to modify or delete the configuration later.
The monitoring configuration supports additional filtering and enrichment options to customize what resources are monitored and how data is enriched in Dynatrace.
Control which Azure subscriptions to monitor using subscriptionFiltering and subscriptionFilteringMode.
Include mode: Monitor only specified subscriptions:
"subscriptionFiltering": ["00000000-0000-0000-0000-000000000001","00000000-0000-0000-0000-000000000002"],"subscriptionFilteringMode": "INCLUDE"
Exclude mode: Monitor all subscriptions except specified ones:
"subscriptionFiltering": ["00000000-0000-0000-0000-000000000001"],"subscriptionFilteringMode": "EXCLUDE"
Filter which Azure resources to monitor based on their tags using tagFiltering.
Include mode: Monitor only resources with matching tags:
"tagFiltering": [{"key": "environment","value": "production","condition": "INCLUDE"},{"key": "monitoring","value": "enabled","condition": "INCLUDE"}]
If you ingest Azure logs or events, also add the following entry to your include filters. For details, see Event Hubs requirements.
{"key": "managed-by","value": "dynatrace","condition": "INCLUDE"}
Exclude mode: Monitor all resources except those with matching tags:
"tagFiltering": [{"key": "monitoring","value": "disabled","condition": "EXCLUDE"}]
Azure tag-based filters instruct the Dynatrace poll services to include or exclude signals for ingest based on Azure tag key-value pairs.
If resources that don't match your filter are still monitored, see Troubleshooting.
Enrich Dynatrace signals with Azure resource tags by specifying tag keys in tagEnrichment. The specified Azure tag keys are added as attributes to signals in Dynatrace.
"tagEnrichment": ["environment","cost-center","application","team"]
Map Azure tags or literal values to Dynatrace labels using dtLabelsEnrichment. This is particularly useful for cost allocation (dt.cost.costcenter, dt.cost.product) and security context (dt.security_context).
Using literal values
"dtLabelsEnrichment": {"dt.security_context": {"literal": "production"},"dt.cost.costcenter": {"literal": "CC-12345"},"dt.cost.product": {"literal": "MyProduct"}}
Using Azure tags
"dtLabelsEnrichment": {"dt.security_context": {"tagKey": "environment"},"dt.cost.costcenter": {"tagKey": "cost-center"},"dt.cost.product": {"tagKey": "product-name"}}
When using tagKey, the value of the specified Azure tag is used as the label value in Dynatrace. Use literal for a fixed string value, or tagKey for a dynamic value from an Azure tag, but not both.
{"scope": "integration-azure","value": {"enabled": true,"description": "production-monitoring","version": "<API_SCHEMA_VERSION>","featureSets": ["microsoft_compute.virtualmachines_essential","microsoft_storage.storageaccounts_essential","microsoft_web.sites_functionapp_essential"],"azure": {"credentials": [{"description": "production-monitoring","enabled": true,"connectionId": "vu9U3hXa3q0AAAABADRidWlsdGlu...","servicePrincipalId": "00000000-0000-0000-0000-000000000000"}],"locationFiltering": ["westeurope","northeurope","eastus"],"subscriptionFiltering": ["00000000-0000-0000-0000-000000000001","00000000-0000-0000-0000-000000000002"],"subscriptionFilteringMode": "INCLUDE","tagFiltering": [{"key": "environment","value": "production","condition": "INCLUDE"},{"key": "monitoring","value": "disabled","condition": "EXCLUDE"}],"tagEnrichment": ["environment","cost-center","application","team"],"dtLabelsEnrichment": {"dt.security_context": {"tagKey": "environment"},"dt.cost.costcenter": {"tagKey": "cost-center"},"dt.cost.product": {"literal": "Platform"}}}}}
Prepare the REST API request.
curl -X 'POST' \'<YOUR_ENVIRONMENT_URL>/platform/extensions/v2/extensions/com.dynatrace.extension.da-azure/monitoring-configurations' \-H 'accept: application/json' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \-d '<MONITORING_CONFIG_PAYLOAD>'
Replace the following placeholders with your values and send the REST API request.
<YOUR_BEARER_TOKEN>: Settings platform token (from Prerequisites)<YOUR_ENVIRONMENT_URL>: URL of your Dynatrace environment (for example, https://abc12345.apps.dynatrace.com)<MONITORING_CONFIG_PAYLOAD>: Request payload prepared in the previous stepA successful request responds with the new monitoring configuration ID (in objectId field):
{"objectId": "e4bf05f3-d829-3689-8dd4-a9d2aeab0607","code": 200}
If the API call fails, validate that
After successful completion, head over to
Settings > Cloud and virtualization > Azure.
In the next few minutes the newly created connection should be visible and Healthy.
To list, modify, or delete an existing monitoring configuration, or to roll over the client secret of a service principal, see Manage your Azure connections via API.
Clouds. Azure resources with telemetry should start to appear shortly.For a full list of supported Azure services, including topology relationships and available metric collection sets, see Supported Azure services.
This error occurs when your Azure identity lacks permission to create applications in Microsoft Entra ID.
Solution: Ask your Azure administrator to grant you the Application Administrator role or create the service principal on your behalf.
This error occurs when your Azure identity lacks permission to assign roles at the specified scope.
Solution:
Management Group scope, confirm you have permissions at the management group level, not just individual subscriptions.Management Group scope, verify you use the resource ID in --scope, not the display name. Run az account management-group list and use the Name column value. Display names differ from IDs and produce the same error.This error indicates that Microsoft Entra ID has not yet propagated the federated credential.
Solution: Wait a few seconds for propagation to complete, then retry the API call.
Some environments return no HTTP response to curl requests against the /platform/extensions/v2/ endpoints, causing the command to hang until a timeout.
Solution: Add --http2 to force HTTP/2:
curl --http2 -X 'POST' \'<YOUR_ENVIRONMENT_URL>/platform/extensions/v2/extensions/com.dynatrace.extension.da-azure/monitoring-configurations' \...
Verify your curl build includes HTTP/2 support by running curl --version—the output should include HTTP2 in the features list.
An include filter can only match a resource that Azure reports the tag for. A resource remains monitored when:
Its Azure resource type doesn't support tags. Many types, especially child types, have no tags property. For example, Microsoft.DBforPostgreSQL/flexibleServers supports tags, but Microsoft.DBforPostgreSQL/flexibleServers/configurations doesn't. To check a type, see Tag support for Azure resources.
The tag is set on the resource group or the parent resource, not on the resource. Azure resources don't inherit tags from a resource group or subscription, and Dynatrace doesn't propagate tags from a parent resource to its children. The same applies to resources in Azure-managed resource groups, such as the MC_<cluster-name>_<region> group that Azure Kubernetes Service creates. Dynatrace collects these resources together with their parent, but Azure doesn't inherit the parent's tags to them. Configure tag inheritance in Azure instead. For details, see Configure tag inheritance in Azure.
Solution: To find the resources your include filter can't match, run the query in Verify which entities your tag filter matches.
This issue occurs when resources from a subscription appear in
Clouds but have no metrics, while metrics arrive for other subscriptions on the same connection. The connection reports as healthy, and Dynatrace might log DATA_ACQUISITION_EVENT warnings that report the identity isn't authorized to query metric data.
Two causes produce this symptom:
Monitoring Reader role at subscription scope or higher. Dynatrace polls metrics with the Azure Monitor metrics:getBatch API, which is a subscription-level API. The request fails unless the service principal has Monitoring Reader on the subscription itself, either assigned directly or inherited from a management group. A role assigned only on resource groups or individual resources isn't enough, even if it covers every resource in the subscription. For details, see 401 authorization errors.Microsoft.Insights resource provider isn't registered in the affected subscription. Azure Monitor doesn't return metrics for a subscription without it, even when the service principal has the Monitoring Reader role. For details, see 403 authorization failures.Solution:
Verify that the service principal has the Monitoring Reader role at subscription scope or higher:
az role assignment list --assignee <CLIENT_ID> --subscription <SUBSCRIPTION_ID> --include-inherited --query "[?roleDefinitionName=='Monitoring Reader'].scope" --output tsv
If the output is empty, assign the role at subscription or management group scope. For details, see Assign Azure roles using Azure CLI.
Check and register Microsoft.Insights in the affected subscription.
Wait for the next polling cycles. The metric poller runs every five minutes.
To find the warning events for your connection, run this query. Replace <CONFIGURATION_ID> with the Monitoring Configuration ID shown on the Overview tab of your connection. For details, see Connection properties.
fetch dt.system.events| filter event.kind == "DATA_ACQUISITION_EVENT"| filter da.clouds.configurationId == "<CONFIGURATION_ID>"| sort timestamp desc