Azure Resource Manager SDK for Azure SQL in .NET. Use for MANAGEMENT PLANE operations: creating/managing SQL servers, databases, elastic pools, firewall rules, and failover groups via Azure Resource Manager. NOT for data plane operations (executing queries) - use Microsoft.Data.SqlClient for that. Triggers: "SQL server", "create SQL database", "manage SQL resources", "ARM SQL", "SqlServerResource", "provision Azure SQL", "elastic pool", "firewall rule".
Documentation
Azure.ResourceManager.Sql (.NET)
Management plane SDK for provisioning and managing Azure SQL resources via Azure Resource Manager.
⚠️ Management vs Data Plane
This SDK (Azure.ResourceManager.Sql): Create servers, databases, elastic pools, configure firewall rules, manage failover groups
Data Plane SDK (Microsoft.Data.SqlClient): Execute queries, stored procedures, manage connections
Current Versions: Stable v1.3.0, Preview v1.4.0-beta.3
Environment Variables
AZURE_SUBSCRIPTION_ID=<your-subscription-id> # Required: Azure subscription IDAZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionAZURE_TENANT_ID
Authentication
Resource Hierarchy
Core Workflow
1. Create SQL Server
2. Create SQL Database
3. Create Elastic Pool
4. Add Database to Elastic Pool
5. Configure Firewall Rules
6. List Resources
7. Get Connection String
Key Types Reference
Type
Purpose
ArmClient
Entry point for all ARM operations
SqlServerResource
Represents an Azure SQL server
SqlServerCollection
Collection for server CRUD
SqlDatabaseResource
Represents a SQL database
SqlDatabaseCollection
Collection for database CRUD
ElasticPoolResource
Represents an elastic pool
ElasticPoolCollection
Collection for elastic pool CRUD
SqlFirewallRuleResource
Represents a firewall rule
SqlFirewallRuleCollection
Collection for firewall rule CRUD
SqlServerData
Server creation/update payload
SqlDatabaseData
Database creation/update payload
ElasticPoolData
Elastic pool creation/update payload
SqlFirewallRuleData
Firewall rule creation/update payload
SqlSku
SKU configuration (tier, capacity)
Common SKUs
Database SKUs
SKU Name
Tier
Description
Basic
Basic
5 DTUs, 2 GB max
S0-S12
Standard
10-3000 DTUs
P1-P15
Premium
125-4000 DTUs
GP_Gen5_2
GeneralPurpose
vCore-based, 2 vCores
BC_Gen5_2
BusinessCritical
vCore-based, 2 vCores
HS_Gen5_2
Hyperscale
vCore-based, 2 vCores
Elastic Pool SKUs
SKU Name
Tier
Description
BasicPool
Basic
50-1600 eDTUs
StandardPool
Standard
50-3000 eDTUs
PremiumPool
Premium
125-4000 eDTUs
GP_Gen5_2
GeneralPurpose
vCore-based
BC_Gen5_2
BusinessCritical
vCore-based
Best Practices
Use WaitUntil.Completed for operations that must finish before proceeding
Use WaitUntil.Started when you want to poll manually or run operations in parallel
Always use DefaultAzureCredential — never hardcode passwords in production
Handle RequestFailedException for ARM API errors
Use CreateOrUpdateAsync for idempotent operations
Navigate hierarchy via Get* methods (e.g., server.GetSqlDatabases())
Use elastic pools for cost optimization when managing multiple databases
Configure firewall rules before attempting connections
AZURE_CLIENT_ID=<client-id> # For service principal auth (optional)
AZURE_CLIENT_SECRET=<client-secret> # For service principal auth (optional)
using Azure.Identity;using Azure.ResourceManager;using Azure.ResourceManager.Sql;// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>var credential = new DefaultAzureCredential( DefaultAzureCredential.DefaultEnvironmentVariableName);// Or use a specific credential directly in production:// See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes// var credential = new ManagedIdentityCredential();var armClient = new ArmClient(credential);// Get subscriptionvar subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");var subscription = armClient.GetSubscriptionResource( new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
var poolData = new ElasticPoolData(AzureLocation.EastUS){ Sku = new SqlSku("StandardPool") { Tier = "Standard", Capacity = 100 // 100 eDTUs }, PerDatabaseSettings = new ElasticPoolPerDatabaseSettings { MinCapacity = 0, MaxCapacity = 100 }};var poolCollection = server.GetElasticPools();var poolOperation = await poolCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-elastic-pool", poolData);ElasticPoolResource pool = poolOperation.Value;
var databaseData = new SqlDatabaseData(AzureLocation.EastUS){ ElasticPoolId = pool.Id};await databaseCollection.CreateOrUpdateAsync( WaitUntil.Completed, "pooled-database", databaseData);
// Allow Azure servicesvar azureServicesRule = new SqlFirewallRuleData{ StartIPAddress = "0.0.0.0", EndIPAddress = "0.0.0.0"};var firewallCollection = server.GetSqlFirewallRules();await firewallCollection.CreateOrUpdateAsync( WaitUntil.Completed, "AllowAzureServices", azureServicesRule);// Allow specific IP rangevar clientRule = new SqlFirewallRuleData{ StartIPAddress = "203.0.113.0", EndIPAddress = "203.0.113.255"};await firewallCollection.CreateOrUpdateAsync( WaitUntil.Completed, "AllowClientIPs", clientRule);
// List all servers in subscriptionawait foreach (var srv in subscription.GetSqlServersAsync()){ Console.WriteLine($"Server: {srv.Data.Name} in {srv.Data.Location}");}// List databases in a serverawait foreach (var db in server.GetSqlDatabases()){ Console.WriteLine($"Database: {db.Data.Name}, SKU: {db.Data.Sku?.Name}");}// List elastic poolsawait foreach (var ep in server.GetElasticPools()){ Console.WriteLine($"Pool: {ep.Data.Name}, DTU: {ep.Data.Sku?.Capacity}");}