Azure SQL Database¶
Consider Azure MCP instead
Most users should start with the Azure MCP integration, which provides broad access to all Azure APIs including Azure SQL. This standalone toolset is only needed if you require the specialized Query Store analysis tools that aren't available through the general MCP server.
By enabling this toolset, HolmesGPT can analyze Azure SQL Database performance, health, and operational issues using Azure REST APIs and Query Store data.
Warning
This toolset is in Experimental stage.
Prerequisites¶
- Azure SQL Database instance
- Azure authentication (Service Principal or Azure AD Workload Identity)
- Appropriate Azure and SQL permissions
Configuration¶
Azure AD Workload Identity
Add the following to ~/.holmes/config.yaml. Create the file if it doesn't exist:
toolsets:
azure/sql:
enabled: true
config:
database:
subscription_id: "your-subscription-id"
resource_group: "your-resource-group"
server_name: "your-azure-sql-server-name"
database_name: "your-azure-sql-database-name"
After making changes to your configuration, run:
Service Principal
toolsets:
azure/sql:
enabled: true
config:
tenant_id: "your-tenant-id"
client_id: "your-client-id"
client_secret: "your-client-secret"
database:
subscription_id: "your-subscription-id"
resource_group: "your-resource-group"
server_name: "your-azure-sql-server-name"
database_name: "your-azure-sql-database-name"
After making changes to your configuration, run:
Azure AD Workload Identity
No Kubernetes secret is needed in this mode — credentials come from the workload identity.
toolsets:
azure/sql:
enabled: true
config:
database:
subscription_id: "your-subscription-id"
resource_group: "your-resource-group"
server_name: "your-azure-sql-server-name"
database_name: "your-azure-sql-database-name"
Service Principal
First, create a Kubernetes secret with the service principal credentials:
kubectl create secret generic azure-sql-credentials \
--from-literal=tenant-id=your-tenant-id \
--from-literal=client-id=your-client-id \
--from-literal=client-secret=your-client-secret \
-n holmes
Namespace must match Holmes' deployment
Create the secret in the same namespace where Holmes runs. The -n holmes flag in the Holmes Helm tab and -n default in the Robusta Helm tab match each chart's documented defaults — adjust if you installed Holmes/Robusta into a different namespace. A secret in the wrong namespace silently resolves to an empty env var and authentication will fail with no clear error.
Then add to your Holmes Helm values:
additionalEnvVars:
- name: AZURE_SQL_TENANT_ID
valueFrom:
secretKeyRef:
name: azure-sql-credentials
key: tenant-id
- name: AZURE_SQL_CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-sql-credentials
key: client-id
- name: AZURE_SQL_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-sql-credentials
key: client-secret
toolsets:
azure/sql:
enabled: true
config:
tenant_id: "{{ env.AZURE_SQL_TENANT_ID }}"
client_id: "{{ env.AZURE_SQL_CLIENT_ID }}"
client_secret: "{{ env.AZURE_SQL_CLIENT_SECRET }}"
database:
subscription_id: "your-subscription-id"
resource_group: "your-resource-group"
server_name: "your-azure-sql-server-name"
database_name: "your-azure-sql-database-name"
Azure AD Workload Identity
No Kubernetes secret is needed in this mode — credentials come from the workload identity.
holmes:
toolsets:
azure/sql:
enabled: true
config:
database:
subscription_id: "your-subscription-id"
resource_group: "your-resource-group"
server_name: "your-azure-sql-server-name"
database_name: "your-azure-sql-database-name"
Service Principal
First, create a Kubernetes secret with the service principal credentials:
kubectl create secret generic azure-sql-credentials \
--from-literal=tenant-id=your-tenant-id \
--from-literal=client-id=your-client-id \
--from-literal=client-secret=your-client-secret \
-n default
Namespace must match Holmes' deployment
Create the secret in the same namespace where Holmes runs. The -n holmes flag in the Holmes Helm tab and -n default in the Robusta Helm tab match each chart's documented defaults — adjust if you installed Holmes/Robusta into a different namespace. A secret in the wrong namespace silently resolves to an empty env var and authentication will fail with no clear error.
Then add to your Robusta Helm values:
holmes:
additionalEnvVars:
- name: AZURE_SQL_TENANT_ID
valueFrom:
secretKeyRef:
name: azure-sql-credentials
key: tenant-id
- name: AZURE_SQL_CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-sql-credentials
key: client-id
- name: AZURE_SQL_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-sql-credentials
key: client-secret
toolsets:
azure/sql:
enabled: true
config:
tenant_id: "{{ env.AZURE_SQL_TENANT_ID }}"
client_id: "{{ env.AZURE_SQL_CLIENT_ID }}"
client_secret: "{{ env.AZURE_SQL_CLIENT_SECRET }}"
database:
subscription_id: "your-subscription-id"
resource_group: "your-resource-group"
server_name: "your-azure-sql-server-name"
database_name: "your-azure-sql-database-name"
Update your Helm values and run a Helm upgrade:
Roles / Access controls¶
The service principal requires these roles:
Azure¶
SQL¶
Database Level (SQL permissions):
├── CREATE USER [holmes-service-principal] FROM EXTERNAL PROVIDER
├── GRANT VIEW SERVER STATE TO [holmes-service-principal]
└── ALTER ROLE db_datareader ADD MEMBER [holmes-service-principal]
Query Store¶
In addition, Query Store should be enabled on target databases
Capabilities¶
| Tool Name | Description |
|---|---|
| analyze_database_health_status | Analyze overall database health and status |
| analyze_database_performance | Analyze database performance metrics |
| analyze_database_connections | Analyze database connection patterns and issues |
| analyze_database_storage | Analyze database storage usage and growth |
| get_top_cpu_queries | Get queries with highest CPU usage |
| get_slow_queries | Get slowest performing queries |
| get_top_data_io_queries | Get queries with highest data I/O usage |
| get_top_log_io_queries | Get queries with highest log I/O usage |
| get_active_alerts | Get active alerts for the database |
| analyze_connection_failures | Analyze connection failure patterns |