GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-mgmt-apimanagement-dotnet

Azure Resource Manager SDK for API Management in .NET. Use for MANAGEMENT PLANE operations: creating/managing APIM services, APIs, products, subscriptions, policies, users, groups, gateways, and backends via Azure Resource Manager. Triggers: "API Management", "APIM service", "cre

Ciza · 0 points · 17 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_plugins_azure-sdk-dotnet_skills_azure-mgmt-apimanagement-dotnet-e58528d.zip · 7 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/azure-mgmt-apimanagement-dotnet
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git git clone https://github.com/microsoft/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Azure.ResourceManager.ApiManagement (.NET)

Management plane SDK for provisioning and managing Azure API Management resources via Azure Resource Manager.

⚠️ Management vs Data Plane

  • This SDK (Azure.ResourceManager.ApiManagement): Create services, APIs, products, subscriptions, policies, users, groups
  • Data Plane: Direct API calls to your APIM gateway endpoints

Installation

dotnet add package Azure.ResourceManager.ApiManagement
dotnet add package Azure.Identity

Current Version: v1.3.0

Environment Variables

AZURE_SUBSCRIPTION_ID=<your-subscription-id> # Required: Azure subscription ID
AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production
AZURE_TENANT_ID=<tenant-id> # For service principal auth (optional)
AZURE_CLIENT_ID=<client-id> # For service principal auth (optional)
AZURE_CLIENT_SECRET=<client-secret> # For service principal auth (optional)

Authentication

using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.ApiManagement;

// 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 subscription
var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
var subscription = armClient.GetSubscriptionResource(
    new ResourceIdentifier($"/subscriptions/{subscriptionId}"));

Resource Hierarchy

ArmClient
└── SubscriptionResource
    └── ResourceGroupResource
        └── ApiManagementServiceResource
            ├── ApiResource
            │   ├── ApiOperationResource
            │   │   └── ApiOperationPolicyResource
            │   ├── ApiPolicyResource
            │   ├── ApiSchemaResource
            │   └── ApiDiagnosticResource
            ├── ApiManagementProductResource
            │   ├── ProductApiResource
            │   ├── ProductGroupResource
            │   └── ProductPolicyResource
            ├── ApiManagementSubscriptionResource
            ├── ApiManagementPolicyResource
            ├── ApiManagementUserResource
            ├── ApiManagementGroupResource
            ├── ApiManagementBackendResource
            ├── ApiManagementGatewayResource
            ├── ApiManagementCertificateResource
            ├── ApiManagementNamedValueResource
            └── ApiManagementLoggerResource

Core Workflow

1. Create API Management Service

using Azure.ResourceManager.ApiManagement;
using Azure.ResourceManager.ApiManagement.Models;

// Get resource group
var resourceGroup = await subscription
    .GetResourceGroupAsync("my-resource-group");

// Define service
var serviceData = new ApiManagementServiceData(
    location: AzureLocation.EastUS,
    sku: new ApiManagementServiceSkuProperties(
        ApiManagementServiceSkuType.Developer, 
        capacity: 1),
    publisherEmail: "admin@contoso.com",
    publisherName: "Contoso");

// Create service (long-running operation - can take 30+ minutes)
var serviceCollection = resourceGroup.Value.GetApiManagementServices();
var operation = await serviceCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    "my-apim-service",
    serviceData);

ApiManagementServiceResource service = operation.Value;

2. Create an API

var apiData = new ApiCreateOrUpdateContent
{
    DisplayName = "My API",
    Path = "myapi",
    Protocols = { ApiOperationInvokableProtocol.Https },
    ServiceUri = new Uri("https://backend.contoso.com/api")
};

var apiCollection = service.GetApis();
var apiOperation = await apiCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    "my-api",
    apiData);

ApiResource api = apiOperation.Value;

3. Create a Product

var productData = new ApiManagementProductData
{
    DisplayName = "Starter",
    Description = "Starter tier with limited access",
    IsSubscriptionRequired = true,
    IsApprovalRequired = false,
    SubscriptionsLimit = 1,
    State = ApiManagementProductState.Published
};

var productCollection = service.GetApiManagementProducts();
var productOperation = await productCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    "starter",
    productData);

ApiManagementProductResource product = productOperation.Value;

// Add API to product
await product.GetProductApis().CreateOrUpdateAsync(
    WaitUntil.Completed,
    "my-api");

4. Create a Subscription

var subscriptionData = new ApiManagementSubscriptionCreateOrUpdateContent
{
    DisplayName = "My Subscription",
    Scope = $"/products/{product.Data.Name}",
    State = ApiManagementSubscriptionState.Active
};

var subscriptionCollection = service.GetApiManagementSubscriptions();
var subOperation = await subscriptionCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    "my-subscription",
    subscriptionData);

ApiManagementSubscriptionResource subscription = subOperation.Value;

// Get subscription keys
var keys = await subscription.GetSecretsAsync();
Console.WriteLine($"Primary Key: {keys.Value.PrimaryKey}");

5. Set API Policy

var policyXml = @"
<policies>
    <inbound>
        <rate-limit calls=""100"" renewal-period=""60"" />
        <set-header name=""X-Custom-Header"" exists-action=""override"">
            <value>CustomValue</value>
        </set-header>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>";

var policyData = new PolicyContractData
{
    Value = policyXml,
    Format = PolicyContentFormat.Xml
};

await api.GetApiPolicy().CreateOrUpdateAsync(
    WaitUntil.Completed,
    policyData);

6. Backup and Restore

// Backup
var backupParams = new ApiManagementServiceBackupRestoreContent(
    storageAccount: "mystorageaccount",
    containerName: "apim-backups",
    backupName: "backup-2024-01-15")
{
    AccessType = StorageAccountAccessType.SystemAssignedManagedIdentity
};

await service.BackupAsync(WaitUntil.Completed, backupParams);

// Restore
await service.RestoreAsync(WaitUntil.Completed, backupParams);

Key Types Reference

Type Purpose
ArmClient Entry point for all ARM operations
ApiManagementServiceResource Represents an APIM service instance
ApiManagementServiceCollection Collection for service CRUD
ApiResource Represents an API
ApiManagementProductResource Represents a product
ApiManagementSubscriptionResource Represents a subscription
ApiManagementPolicyResource Service-level policy
ApiPolicyResource API-level policy
ApiManagementUserResource Represents a user
ApiManagementGroupResource Represents a group
ApiManagementBackendResource Represents a backend service
ApiManagementGatewayResource Represents a self-hosted gateway

SKU Types

SKU Purpose Capacity
Developer Development/testing (no SLA) 1
Basic Entry-level production 1-2
Standard Medium workloads 1-4
Premium High availability, multi-region 1-12 per region
Consumption Serverless, pay-per-call N/A

Best Practices

  1. Use WaitUntil.Completed for operations that must finish before proceeding
  2. Use WaitUntil.Started for long operations like service creation (30+ min)
  3. Always use DefaultAzureCredential — never hardcode keys
  4. Handle RequestFailedException for ARM API errors
  5. Use CreateOrUpdateAsync for idempotent operations
  6. Navigate hierarchy via Get* methods (e.g., service.GetApis())
  7. Policy format — Use XML format for policies; JSON is also supported
  8. Service creation — Developer SKU is fastest for testing (~15-30 min)

Error Handling

using Azure;

try
{
    var operation = await serviceCollection.CreateOrUpdateAsync(
        WaitUntil.Completed, serviceName, serviceData);
}
catch (RequestFailedException ex) when (ex.Status == 409)
{
    Console.WriteLine("Service already exists");
}
catch (RequestFailedException ex) when (ex.Status == 400)
{
    Console.WriteLine($"Bad request: {ex.Message}");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}

Reference Files

File When to Read
references/service-management.md Service CRUD, SKUs, networking, backup/restore
references/apis-operations.md APIs, operations, schemas, versioning
references/products-subscriptions.md Products, subscriptions, access control
references/policies.md Policy XML patterns, scopes, common policies

Related Resources

Resource Purpose
API Management Documentation Official Azure docs
Policy Reference Complete policy reference
SDK Reference .NET API reference
Files (skills)
  • references
    • apis-operations.md 3.8 KB
      # APIs and Operations
      
      Patterns for managing APIs, operations, and schemas.
      
      ## Create API from OpenAPI
      
      ```csharp
      var apiData = new ApiCreateOrUpdateContent
      {
          DisplayName = "Pet Store API",
          Path = "petstore",
          Protocols = { ApiOperationInvokableProtocol.Https },
          // Import from OpenAPI spec
          Format = ContentFormat.OpenApiJson,
          Value = File.ReadAllText("petstore-openapi.json"),
          // Or from URL
          // Format = ContentFormat.OpenApiJsonLink,
          // Value = "https://petstore.swagger.io/v2/swagger.json"
      };
      
      var api = await service.GetApis()
          .CreateOrUpdateAsync(WaitUntil.Completed, "petstore-api", apiData);
      ```
      
      ## Create API Manually
      
      ```csharp
      var apiData = new ApiCreateOrUpdateContent
      {
          DisplayName = "Custom API",
          Path = "custom",
          Protocols = { ApiOperationInvokableProtocol.Https },
          ServiceUri = new Uri("https://backend.contoso.com"),
          SubscriptionKeyParameterNames = new SubscriptionKeyParameterNamesContract
          {
              Header = "X-API-Key",
              Query = "api-key"
          }
      };
      
      var api = await service.GetApis()
          .CreateOrUpdateAsync(WaitUntil.Completed, "custom-api", apiData);
      ```
      
      ## List APIs
      
      ```csharp
      await foreach (var api in service.GetApis())
      {
          Console.WriteLine($"{api.Data.DisplayName}: {api.Data.Path}");
      }
      ```
      
      ## Create Operation
      
      ```csharp
      var operationData = new ApiOperationData
      {
          DisplayName = "Get Users",
          Method = "GET",
          UrlTemplate = "/users",
          Description = "Retrieves all users",
          Responses =
          {
              new ResponseContract(200)
              {
                  Description = "Success",
                  Representations =
                  {
                      new RepresentationContract("application/json")
                  }
              }
          }
      };
      
      var operation = await api.Value.GetApiOperations()
          .CreateOrUpdateAsync(WaitUntil.Completed, "get-users", operationData);
      ```
      
      ## Operation with Parameters
      
      ```csharp
      var operationData = new ApiOperationData
      {
          DisplayName = "Get User by ID",
          Method = "GET",
          UrlTemplate = "/users/{userId}",
          TemplateParameters =
          {
              new ParameterContract("userId")
              {
                  Description = "User identifier",
                  ParameterContractType = "string",
                  IsRequired = true
              }
          },
          Request = new RequestContract
          {
              QueryParameters =
              {
                  new ParameterContract("include")
                  {
                      Description = "Related data to include",
                      ParameterContractType = "string",
                      IsRequired = false
                  }
              }
          }
      };
      ```
      
      ## API Versioning
      
      ```csharp
      // Create version set
      var versionSetData = new ApiVersionSetData
      {
          DisplayName = "My API Versions",
          VersioningScheme = VersioningScheme.Segment // or Header, Query
      };
      
      var versionSet = await service.GetApiVersionSets()
          .CreateOrUpdateAsync(WaitUntil.Completed, "my-api-versions", versionSetData);
      
      // Create versioned API
      var apiV1Data = new ApiCreateOrUpdateContent
      {
          DisplayName = "My API v1",
          Path = "myapi",
          ApiVersion = "v1",
          ApiVersionSetId = versionSet.Value.Id,
          Protocols = { ApiOperationInvokableProtocol.Https }
      };
      
      var apiV2Data = new ApiCreateOrUpdateContent
      {
          DisplayName = "My API v2",
          Path = "myapi",
          ApiVersion = "v2",
          ApiVersionSetId = versionSet.Value.Id,
          Protocols = { ApiOperationInvokableProtocol.Https }
      };
      ```
      
      ## API Revisions
      
      ```csharp
      // Create revision
      var revisionData = new ApiCreateOrUpdateContent
      {
          SourceApiId = api.Value.Id,
          Path = api.Value.Data.Path,
          ApiRevisionDescription = "Added new endpoint"
      };
      
      var revision = await service.GetApis()
          .CreateOrUpdateAsync(WaitUntil.Completed, "my-api;rev=2", revisionData);
      
      // Make revision current
      await revision.Value.UpdateAsync(WaitUntil.Completed, 
          new ApiCreateOrUpdateContent { IsCurrent = true });
      ```
      
      ## Delete API
      
      ```csharp
      await api.Value.DeleteAsync(WaitUntil.Completed);
      ```
      
    • products-subscriptions.md 4 KB
      # Products and Subscriptions
      
      Patterns for managing products, subscriptions, and access control.
      
      ## Create Product
      
      ```csharp
      var productData = new ApiManagementProductData
      {
          DisplayName = "Premium",
          Description = "Premium tier with full access",
          IsSubscriptionRequired = true,
          IsApprovalRequired = true,  // Requires admin approval
          SubscriptionsLimit = 5,
          State = ApiManagementProductState.Published,
          Terms = "Terms and conditions for premium tier..."
      };
      
      var product = await service.GetApiManagementProducts()
          .CreateOrUpdateAsync(WaitUntil.Completed, "premium", productData);
      ```
      
      ## List Products
      
      ```csharp
      await foreach (var product in service.GetApiManagementProducts())
      {
          Console.WriteLine($"{product.Data.DisplayName}: {product.Data.State}");
      }
      ```
      
      ## Add API to Product
      
      ```csharp
      // Get product
      var product = await service.GetApiManagementProductAsync("premium");
      
      // Add API
      await product.Value.GetProductApis()
          .CreateOrUpdateAsync(WaitUntil.Completed, "my-api");
      ```
      
      ## Remove API from Product
      
      ```csharp
      var productApi = await product.Value.GetProductApiAsync("my-api");
      await productApi.Value.DeleteAsync(WaitUntil.Completed);
      ```
      
      ## List APIs in Product
      
      ```csharp
      await foreach (var api in product.Value.GetProductApis())
      {
          Console.WriteLine($"  - {api.Data.DisplayName}");
      }
      ```
      
      ## Create Subscription
      
      ```csharp
      // Subscription to product
      var subscriptionData = new ApiManagementSubscriptionCreateOrUpdateContent
      {
          DisplayName = "Customer A Subscription",
          Scope = $"/products/premium",
          State = ApiManagementSubscriptionState.Active,
          AllowTracing = true
      };
      
      var subscription = await service.GetApiManagementSubscriptions()
          .CreateOrUpdateAsync(WaitUntil.Completed, "customer-a-sub", subscriptionData);
      
      // Subscription to specific API
      var apiSubscriptionData = new ApiManagementSubscriptionCreateOrUpdateContent
      {
          DisplayName = "API-specific Subscription",
          Scope = $"/apis/my-api",
          State = ApiManagementSubscriptionState.Active
      };
      ```
      
      ## Get Subscription Keys
      
      ```csharp
      var secrets = await subscription.Value.GetSecretsAsync();
      Console.WriteLine($"Primary Key: {secrets.Value.PrimaryKey}");
      Console.WriteLine($"Secondary Key: {secrets.Value.SecondaryKey}");
      ```
      
      ## Regenerate Subscription Keys
      
      ```csharp
      // Regenerate primary key
      await subscription.Value.RegeneratePrimaryKeyAsync();
      
      // Regenerate secondary key
      await subscription.Value.RegenerateSecondaryKeyAsync();
      ```
      
      ## List Subscriptions
      
      ```csharp
      await foreach (var sub in service.GetApiManagementSubscriptions())
      {
          Console.WriteLine($"{sub.Data.DisplayName}: {sub.Data.State}");
      }
      ```
      
      ## Suspend/Activate Subscription
      
      ```csharp
      // Suspend
      var patch = new ApiManagementSubscriptionPatch
      {
          State = ApiManagementSubscriptionState.Suspended
      };
      await subscription.Value.UpdateAsync(patch);
      
      // Reactivate
      patch.State = ApiManagementSubscriptionState.Active;
      await subscription.Value.UpdateAsync(patch);
      ```
      
      ## Create User
      
      ```csharp
      var userData = new ApiManagementUserCreateOrUpdateContent
      {
          Email = "user@contoso.com",
          FirstName = "John",
          LastName = "Doe",
          State = ApiManagementUserState.Active,
          Password = "SecurePassword123!"  // Optional, can send invite instead
      };
      
      var user = await service.GetApiManagementUsers()
          .CreateOrUpdateAsync(WaitUntil.Completed, "john-doe", userData);
      ```
      
      ## Create Group
      
      ```csharp
      var groupData = new ApiManagementGroupCreateOrUpdateContent
      {
          DisplayName = "Premium Users",
          Description = "Users with premium access",
          GroupContractType = ApiManagementGroupType.Custom
      };
      
      var group = await service.GetApiManagementGroups()
          .CreateOrUpdateAsync(WaitUntil.Completed, "premium-users", groupData);
      ```
      
      ## Add User to Group
      
      ```csharp
      await group.Value.GetGroupUsers()
          .CreateOrUpdateAsync(WaitUntil.Completed, "john-doe");
      ```
      
      ## Add Group to Product
      
      ```csharp
      await product.Value.GetProductGroups()
          .CreateOrUpdateAsync(WaitUntil.Completed, "premium-users");
      ```
      
      ## Delete Subscription
      
      ```csharp
      await subscription.Value.DeleteAsync(WaitUntil.Completed);
      ```
      
    • service-management.md 3.9 KB
      # Service Management
      
      Detailed patterns for managing API Management service instances.
      
      ## Get Existing Service
      
      ```csharp
      // By resource group
      var service = await resourceGroup.Value
          .GetApiManagementServiceAsync("my-apim-service");
      
      // By resource ID
      var serviceId = ApiManagementServiceResource.CreateResourceIdentifier(
          subscriptionId, "my-resource-group", "my-apim-service");
      var service = armClient.GetApiManagementServiceResource(serviceId);
      service = await service.GetAsync();
      ```
      
      ## List Services
      
      ```csharp
      // In resource group
      await foreach (var service in resourceGroup.Value.GetApiManagementServices())
      {
          Console.WriteLine($"{service.Data.Name}: {service.Data.Location}");
      }
      
      // In subscription
      await foreach (var service in subscription.GetApiManagementServicesAsync())
      {
          Console.WriteLine($"{service.Data.Name}: {service.Data.ResourceGroupName}");
      }
      ```
      
      ## Update Service
      
      ```csharp
      var patch = new ApiManagementServicePatch
      {
          PublisherName = "Updated Publisher",
          Tags = { ["environment"] = "production" }
      };
      
      var operation = await service.UpdateAsync(WaitUntil.Completed, patch);
      ```
      
      ## Delete Service
      
      ```csharp
      await service.DeleteAsync(WaitUntil.Completed);
      ```
      
      ## SKU Configuration
      
      ```csharp
      // Developer (for testing)
      var devSku = new ApiManagementServiceSkuProperties(
          ApiManagementServiceSkuType.Developer, capacity: 1);
      
      // Standard with multiple units
      var standardSku = new ApiManagementServiceSkuProperties(
          ApiManagementServiceSkuType.Standard, capacity: 2);
      
      // Premium with availability zones
      var premiumData = new ApiManagementServiceData(
          location: AzureLocation.EastUS,
          sku: new ApiManagementServiceSkuProperties(
              ApiManagementServiceSkuType.Premium, capacity: 3),
          publisherEmail: "admin@contoso.com",
          publisherName: "Contoso")
      {
          Zones = { "1", "2", "3" }
      };
      ```
      
      ## Virtual Network Integration
      
      ```csharp
      var serviceData = new ApiManagementServiceData(
          location: AzureLocation.EastUS,
          sku: new ApiManagementServiceSkuProperties(
              ApiManagementServiceSkuType.Premium, capacity: 1),
          publisherEmail: "admin@contoso.com",
          publisherName: "Contoso")
      {
          VirtualNetworkType = VirtualNetworkType.External,
          VirtualNetworkConfiguration = new VirtualNetworkConfiguration
          {
              SubnetResourceId = new ResourceIdentifier(
                  "/subscriptions/.../subnets/apim-subnet")
          }
      };
      ```
      
      ## Custom Domains
      
      ```csharp
      var serviceData = new ApiManagementServiceData(...)
      {
          HostnameConfigurations =
          {
              new HostnameConfiguration(HostnameType.Proxy)
              {
                  HostName = "api.contoso.com",
                  CertificateSource = CertificateSource.KeyVault,
                  KeyVaultSecretUri = new Uri("https://myvault.vault.azure.net/secrets/api-cert")
              },
              new HostnameConfiguration(HostnameType.DeveloperPortal)
              {
                  HostName = "developer.contoso.com",
                  CertificateSource = CertificateSource.KeyVault,
                  KeyVaultSecretUri = new Uri("https://myvault.vault.azure.net/secrets/portal-cert")
              }
          }
      };
      ```
      
      ## Managed Identity
      
      ```csharp
      var serviceData = new ApiManagementServiceData(...)
      {
          Identity = new ManagedServiceIdentity(ManagedServiceIdentityType.SystemAssigned)
      };
      
      // Or user-assigned
      var serviceData = new ApiManagementServiceData(...)
      {
          Identity = new ManagedServiceIdentity(ManagedServiceIdentityType.UserAssigned)
          {
              UserAssignedIdentities =
              {
                  [new ResourceIdentifier("/subscriptions/.../userAssignedIdentities/my-identity")] = 
                      new UserAssignedIdentity()
              }
          }
      };
      ```
      
      ## Get Service Information
      
      ```csharp
      // Get gateway URL
      Console.WriteLine($"Gateway: {service.Data.GatewayUri}");
      
      // Get portal URL
      Console.WriteLine($"Portal: {service.Data.DeveloperPortalUri}");
      
      // Get management API URL
      Console.WriteLine($"Management: {service.Data.ManagementApiUri}");
      
      // Get provisioning state
      Console.WriteLine($"State: {service.Data.ProvisioningState}");
      ```
      
  • SKILL.md 10.2 KB
    ---
    name: azure-mgmt-apimanagement-dotnet
    description: |
      Azure Resource Manager SDK for API Management in .NET. Use for MANAGEMENT PLANE operations: creating/managing APIM services, APIs, products, subscriptions, policies, users, groups, gateways, and backends via Azure Resource Manager. Triggers: "API Management", "APIM service", "create APIM", "manage APIs", "ApiManagementServiceResource", "API policies", "APIM products", "APIM subscriptions".
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: Azure.ResourceManager.ApiManagement
    ---
    
    # Azure.ResourceManager.ApiManagement (.NET)
    
    Management plane SDK for provisioning and managing Azure API Management resources via Azure Resource Manager.
    
    > **⚠️ Management vs Data Plane**
    > - **This SDK (Azure.ResourceManager.ApiManagement)**: Create services, APIs, products, subscriptions, policies, users, groups
    > - **Data Plane**: Direct API calls to your APIM gateway endpoints
    
    ## Installation
    
    ```bash
    dotnet add package Azure.ResourceManager.ApiManagement
    dotnet add package Azure.Identity
    ```
    
    **Current Version**: v1.3.0
    
    ## Environment Variables
    
    ```bash
    AZURE_SUBSCRIPTION_ID=<your-subscription-id> # Required: Azure subscription ID
    AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production
    AZURE_TENANT_ID=<tenant-id> # For service principal auth (optional)
    AZURE_CLIENT_ID=<client-id> # For service principal auth (optional)
    AZURE_CLIENT_SECRET=<client-secret> # For service principal auth (optional)
    ```
    
    ## Authentication
    
    ```csharp
    using Azure.Identity;
    using Azure.ResourceManager;
    using Azure.ResourceManager.ApiManagement;
    
    // 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 subscription
    var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
    var subscription = armClient.GetSubscriptionResource(
        new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
    ```
    
    ## Resource Hierarchy
    
    ```
    ArmClient
    └── SubscriptionResource
        └── ResourceGroupResource
            └── ApiManagementServiceResource
                ├── ApiResource
                │   ├── ApiOperationResource
                │   │   └── ApiOperationPolicyResource
                │   ├── ApiPolicyResource
                │   ├── ApiSchemaResource
                │   └── ApiDiagnosticResource
                ├── ApiManagementProductResource
                │   ├── ProductApiResource
                │   ├── ProductGroupResource
                │   └── ProductPolicyResource
                ├── ApiManagementSubscriptionResource
                ├── ApiManagementPolicyResource
                ├── ApiManagementUserResource
                ├── ApiManagementGroupResource
                ├── ApiManagementBackendResource
                ├── ApiManagementGatewayResource
                ├── ApiManagementCertificateResource
                ├── ApiManagementNamedValueResource
                └── ApiManagementLoggerResource
    ```
    
    ## Core Workflow
    
    ### 1. Create API Management Service
    
    ```csharp
    using Azure.ResourceManager.ApiManagement;
    using Azure.ResourceManager.ApiManagement.Models;
    
    // Get resource group
    var resourceGroup = await subscription
        .GetResourceGroupAsync("my-resource-group");
    
    // Define service
    var serviceData = new ApiManagementServiceData(
        location: AzureLocation.EastUS,
        sku: new ApiManagementServiceSkuProperties(
            ApiManagementServiceSkuType.Developer, 
            capacity: 1),
        publisherEmail: "admin@contoso.com",
        publisherName: "Contoso");
    
    // Create service (long-running operation - can take 30+ minutes)
    var serviceCollection = resourceGroup.Value.GetApiManagementServices();
    var operation = await serviceCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        "my-apim-service",
        serviceData);
    
    ApiManagementServiceResource service = operation.Value;
    ```
    
    ### 2. Create an API
    
    ```csharp
    var apiData = new ApiCreateOrUpdateContent
    {
        DisplayName = "My API",
        Path = "myapi",
        Protocols = { ApiOperationInvokableProtocol.Https },
        ServiceUri = new Uri("https://backend.contoso.com/api")
    };
    
    var apiCollection = service.GetApis();
    var apiOperation = await apiCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        "my-api",
        apiData);
    
    ApiResource api = apiOperation.Value;
    ```
    
    ### 3. Create a Product
    
    ```csharp
    var productData = new ApiManagementProductData
    {
        DisplayName = "Starter",
        Description = "Starter tier with limited access",
        IsSubscriptionRequired = true,
        IsApprovalRequired = false,
        SubscriptionsLimit = 1,
        State = ApiManagementProductState.Published
    };
    
    var productCollection = service.GetApiManagementProducts();
    var productOperation = await productCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        "starter",
        productData);
    
    ApiManagementProductResource product = productOperation.Value;
    
    // Add API to product
    await product.GetProductApis().CreateOrUpdateAsync(
        WaitUntil.Completed,
        "my-api");
    ```
    
    ### 4. Create a Subscription
    
    ```csharp
    var subscriptionData = new ApiManagementSubscriptionCreateOrUpdateContent
    {
        DisplayName = "My Subscription",
        Scope = $"/products/{product.Data.Name}",
        State = ApiManagementSubscriptionState.Active
    };
    
    var subscriptionCollection = service.GetApiManagementSubscriptions();
    var subOperation = await subscriptionCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        "my-subscription",
        subscriptionData);
    
    ApiManagementSubscriptionResource subscription = subOperation.Value;
    
    // Get subscription keys
    var keys = await subscription.GetSecretsAsync();
    Console.WriteLine($"Primary Key: {keys.Value.PrimaryKey}");
    ```
    
    ### 5. Set API Policy
    
    ```csharp
    var policyXml = @"
    <policies>
        <inbound>
            <rate-limit calls=""100"" renewal-period=""60"" />
            <set-header name=""X-Custom-Header"" exists-action=""override"">
                <value>CustomValue</value>
            </set-header>
            <base />
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>";
    
    var policyData = new PolicyContractData
    {
        Value = policyXml,
        Format = PolicyContentFormat.Xml
    };
    
    await api.GetApiPolicy().CreateOrUpdateAsync(
        WaitUntil.Completed,
        policyData);
    ```
    
    ### 6. Backup and Restore
    
    ```csharp
    // Backup
    var backupParams = new ApiManagementServiceBackupRestoreContent(
        storageAccount: "mystorageaccount",
        containerName: "apim-backups",
        backupName: "backup-2024-01-15")
    {
        AccessType = StorageAccountAccessType.SystemAssignedManagedIdentity
    };
    
    await service.BackupAsync(WaitUntil.Completed, backupParams);
    
    // Restore
    await service.RestoreAsync(WaitUntil.Completed, backupParams);
    ```
    
    ## Key Types Reference
    
    | Type | Purpose |
    |------|---------|
    | `ArmClient` | Entry point for all ARM operations |
    | `ApiManagementServiceResource` | Represents an APIM service instance |
    | `ApiManagementServiceCollection` | Collection for service CRUD |
    | `ApiResource` | Represents an API |
    | `ApiManagementProductResource` | Represents a product |
    | `ApiManagementSubscriptionResource` | Represents a subscription |
    | `ApiManagementPolicyResource` | Service-level policy |
    | `ApiPolicyResource` | API-level policy |
    | `ApiManagementUserResource` | Represents a user |
    | `ApiManagementGroupResource` | Represents a group |
    | `ApiManagementBackendResource` | Represents a backend service |
    | `ApiManagementGatewayResource` | Represents a self-hosted gateway |
    
    ## SKU Types
    
    | SKU | Purpose | Capacity |
    |-----|---------|----------|
    | `Developer` | Development/testing (no SLA) | 1 |
    | `Basic` | Entry-level production | 1-2 |
    | `Standard` | Medium workloads | 1-4 |
    | `Premium` | High availability, multi-region | 1-12 per region |
    | `Consumption` | Serverless, pay-per-call | N/A |
    
    ## Best Practices
    
    1. **Use `WaitUntil.Completed`** for operations that must finish before proceeding
    2. **Use `WaitUntil.Started`** for long operations like service creation (30+ min)
    3. **Always use `DefaultAzureCredential`** — never hardcode keys
    4. **Handle `RequestFailedException`** for ARM API errors
    5. **Use `CreateOrUpdateAsync`** for idempotent operations
    6. **Navigate hierarchy** via `Get*` methods (e.g., `service.GetApis()`)
    7. **Policy format** — Use XML format for policies; JSON is also supported
    8. **Service creation** — Developer SKU is fastest for testing (~15-30 min)
    
    ## Error Handling
    
    ```csharp
    using Azure;
    
    try
    {
        var operation = await serviceCollection.CreateOrUpdateAsync(
            WaitUntil.Completed, serviceName, serviceData);
    }
    catch (RequestFailedException ex) when (ex.Status == 409)
    {
        Console.WriteLine("Service already exists");
    }
    catch (RequestFailedException ex) when (ex.Status == 400)
    {
        Console.WriteLine($"Bad request: {ex.Message}");
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
    }
    ```
    
    ## Reference Files
    
    | File | When to Read |
    |------|--------------|
    | [references/service-management.md](references/service-management.md) | Service CRUD, SKUs, networking, backup/restore |
    | [references/apis-operations.md](references/apis-operations.md) | APIs, operations, schemas, versioning |
    | [references/products-subscriptions.md](references/products-subscriptions.md) | Products, subscriptions, access control |
    | [references/policies.md](references/policies.md) | Policy XML patterns, scopes, common policies |
    
    ## Related Resources
    
    | Resource | Purpose |
    |----------|---------|
    | [API Management Documentation](https://learn.microsoft.com/en-us/azure/api-management/) | Official Azure docs |
    | [Policy Reference](https://learn.microsoft.com/en-us/azure/api-management/api-management-policies) | Complete policy reference |
    | [SDK Reference](https://learn.microsoft.com/en-us/dotnet/api/azure.resourcemanager.apimanagement) | .NET API reference |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related