GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-resource-manager-redis-dotnet

Azure Resource Manager SDK for Redis in .NET. Use for MANAGEMENT PLANE operations: creating/managing Azure Cache for Redis instances, firewall rules, access keys, patch schedules, linked servers (geo-replication), and private endpoints via Azure Resource Manager. NOT for data pla

Ciza · 0 points · 14 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-resource-manager-redis-dotnet-e58528d.zip · 4 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-resource-manager-redis-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.Redis (.NET)

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

⚠️ Management vs Data Plane

  • This SDK (Azure.ResourceManager.Redis): Create caches, configure firewall rules, manage access keys, set up geo-replication
  • Data Plane SDK (StackExchange.Redis): Get/set keys, pub/sub, streams, Lua scripts

Installation

dotnet add package Azure.ResourceManager.Redis
dotnet add package Azure.Identity

Current Version: 1.5.1 (Stable)
API Version: 2024-11-01
Target Frameworks: .NET 8.0, .NET Standard 2.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.Redis;

// 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
        └── RedisResource
            ├── RedisFirewallRuleResource
            ├── RedisPatchScheduleResource
            ├── RedisLinkedServerWithPropertyResource
            ├── RedisPrivateEndpointConnectionResource
            └── RedisCacheAccessPolicyResource

Core Workflows

1. Create Redis Cache

using Azure.ResourceManager.Redis;
using Azure.ResourceManager.Redis.Models;

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

// Define cache configuration
var cacheData = new RedisCreateOrUpdateContent(
    location: AzureLocation.EastUS,
    sku: new RedisSku(RedisSkuName.Standard, RedisSkuFamily.BasicOrStandard, 1))
{
    EnableNonSslPort = false,
    MinimumTlsVersion = RedisTlsVersion.Tls1_2,
    RedisConfiguration = new RedisCommonConfiguration
    {
        MaxMemoryPolicy = "volatile-lru"
    },
    Tags =
    {
        ["environment"] = "production"
    }
};

// Create cache (long-running operation)
var cacheCollection = resourceGroup.Value.GetAllRedis();
var operation = await cacheCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    "my-redis-cache",
    cacheData);

RedisResource cache = operation.Value;
Console.WriteLine($"Cache created: {cache.Data.HostName}");

2. Get Redis Cache

// Get existing cache
var cache = await resourceGroup.Value
    .GetRedisAsync("my-redis-cache");

Console.WriteLine($"Host: {cache.Value.Data.HostName}");
Console.WriteLine($"Port: {cache.Value.Data.Port}");
Console.WriteLine($"SSL Port: {cache.Value.Data.SslPort}");
Console.WriteLine($"Provisioning State: {cache.Value.Data.ProvisioningState}");

3. Update Redis Cache

var patchData = new RedisPatch
{
    Sku = new RedisSku(RedisSkuName.Standard, RedisSkuFamily.BasicOrStandard, 2),
    RedisConfiguration = new RedisCommonConfiguration
    {
        MaxMemoryPolicy = "allkeys-lru"
    }
};

var updateOperation = await cache.Value.UpdateAsync(
    WaitUntil.Completed,
    patchData);

4. Delete Redis Cache

await cache.Value.DeleteAsync(WaitUntil.Completed);

5. Get Access Keys

var keys = await cache.Value.GetKeysAsync();
Console.WriteLine($"Primary Key: {keys.Value.PrimaryKey}");
Console.WriteLine($"Secondary Key: {keys.Value.SecondaryKey}");

6. Regenerate Access Keys

var regenerateContent = new RedisRegenerateKeyContent(RedisRegenerateKeyType.Primary);
var newKeys = await cache.Value.RegenerateKeyAsync(regenerateContent);
Console.WriteLine($"New Primary Key: {newKeys.Value.PrimaryKey}");

7. Manage Firewall Rules

// Create firewall rule
var firewallData = new RedisFirewallRuleData(
    startIP: System.Net.IPAddress.Parse("10.0.0.1"),
    endIP: System.Net.IPAddress.Parse("10.0.0.255"));

var firewallCollection = cache.Value.GetRedisFirewallRules();
var firewallOperation = await firewallCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    "allow-internal-network",
    firewallData);

// List all firewall rules
await foreach (var rule in firewallCollection.GetAllAsync())
{
    Console.WriteLine($"Rule: {rule.Data.Name} ({rule.Data.StartIP} - {rule.Data.EndIP})");
}

// Delete firewall rule
var ruleToDelete = await firewallCollection.GetAsync("allow-internal-network");
await ruleToDelete.Value.DeleteAsync(WaitUntil.Completed);

8. Configure Patch Schedule (Premium SKU)

// Patch schedules require Premium SKU
var scheduleData = new RedisPatchScheduleData(
    new[]
    {
        new RedisPatchScheduleSetting(RedisDayOfWeek.Saturday, 2) // 2 AM Saturday
        {
            MaintenanceWindow = TimeSpan.FromHours(5)
        },
        new RedisPatchScheduleSetting(RedisDayOfWeek.Sunday, 2) // 2 AM Sunday
        {
            MaintenanceWindow = TimeSpan.FromHours(5)
        }
    });

var scheduleCollection = cache.Value.GetRedisPatchSchedules();
await scheduleCollection.CreateOrUpdateAsync(
    WaitUntil.Completed,
    RedisPatchScheduleDefaultName.Default,
    scheduleData);

9. Import/Export Data (Premium SKU)

// Import data from blob storage
var importContent = new ImportRdbContent(
    files: new[] { "https://mystorageaccount.blob.core.windows.net/container/dump.rdb" },
    format: "RDB");

await cache.Value.ImportDataAsync(WaitUntil.Completed, importContent);

// Export data to blob storage
var exportContent = new ExportRdbContent(
    prefix: "backup",
    container: "https://mystorageaccount.blob.core.windows.net/container?sastoken",
    format: "RDB");

await cache.Value.ExportDataAsync(WaitUntil.Completed, exportContent);

10. Force Reboot

var rebootContent = new RedisRebootContent
{
    RebootType = RedisRebootType.AllNodes,
    ShardId = 0 // For clustered caches
};

await cache.Value.ForceRebootAsync(rebootContent);

SKU Reference

SKU Family Capacity Features
Basic C 0-6 Single node, no SLA, dev/test only
Standard C 0-6 Two nodes (primary/replica), SLA
Premium P 1-5 Clustering, geo-replication, VNet, persistence

Capacity Sizes (Family C - Basic/Standard):

  • C0: 250 MB
  • C1: 1 GB
  • C2: 2.5 GB
  • C3: 6 GB
  • C4: 13 GB
  • C5: 26 GB
  • C6: 53 GB

Capacity Sizes (Family P - Premium):

  • P1: 6 GB per shard
  • P2: 13 GB per shard
  • P3: 26 GB per shard
  • P4: 53 GB per shard
  • P5: 120 GB per shard

Key Types Reference

Type Purpose
ArmClient Entry point for all ARM operations
RedisResource Represents a Redis cache instance
RedisCollection Collection for cache CRUD operations
RedisFirewallRuleResource Firewall rule for IP filtering
RedisPatchScheduleResource Maintenance window configuration
RedisLinkedServerWithPropertyResource Geo-replication linked server
RedisPrivateEndpointConnectionResource Private endpoint connection
RedisCacheAccessPolicyResource RBAC access policy
RedisCreateOrUpdateContent Cache creation payload
RedisPatch Cache update payload
RedisSku SKU configuration (name, family, capacity)
RedisAccessKeys Primary and secondary access keys
RedisRegenerateKeyContent Key regeneration request

Best Practices

  1. Use WaitUntil.Completed for operations that must finish before proceeding
  2. Use WaitUntil.Started when you want to poll manually or run operations in parallel
  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., cache.GetRedisFirewallRules())
  7. Use Premium SKU for production workloads requiring geo-replication, clustering, or persistence
  8. Enable TLS 1.2 minimum — set MinimumTlsVersion = RedisTlsVersion.Tls1_2
  9. Disable non-SSL port — set EnableNonSslPort = false for security
  10. Rotate keys regularly — use RegenerateKeyAsync and update connection strings

Error Handling

using Azure;

try
{
    var operation = await cacheCollection.CreateOrUpdateAsync(
        WaitUntil.Completed, cacheName, cacheData);
}
catch (RequestFailedException ex) when (ex.Status == 409)
{
    Console.WriteLine("Cache already exists");
}
catch (RequestFailedException ex) when (ex.Status == 400)
{
    Console.WriteLine($"Invalid configuration: {ex.Message}");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}

Common Pitfalls

  1. SKU downgrades not allowed — You cannot downgrade from Premium to Standard/Basic
  2. Clustering requires Premium — Shard configuration only available on Premium SKU
  3. Geo-replication requires Premium — Linked servers only work with Premium caches
  4. VNet injection requires Premium — Virtual network support is Premium-only
  5. Patch schedules require Premium — Maintenance windows only configurable on Premium
  6. Cache name globally unique — Redis cache names must be unique across all Azure subscriptions
  7. Long provisioning times — Cache creation can take 15-20 minutes; use WaitUntil.Started for async patterns

Connecting with StackExchange.Redis (Data Plane)

After creating the cache with this management SDK, use StackExchange.Redis for data operations:

using StackExchange.Redis;

// Get connection info from management SDK
var cache = await resourceGroup.Value.GetRedisAsync("my-redis-cache");
var keys = await cache.Value.GetKeysAsync();

// Connect with StackExchange.Redis
var connectionString = $"{cache.Value.Data.HostName}:{cache.Value.Data.SslPort},password={keys.Value.PrimaryKey},ssl=True,abortConnect=False";
var connection = ConnectionMultiplexer.Connect(connectionString);
var db = connection.GetDatabase();

// Data operations
await db.StringSetAsync("key", "value");
var value = await db.StringGetAsync("key");

Related SDKs

SDK Purpose Install
StackExchange.Redis Data plane (get/set, pub/sub, streams) dotnet add package StackExchange.Redis
Azure.ResourceManager.Redis Management plane (this SDK) dotnet add package Azure.ResourceManager.Redis
Microsoft.Azure.StackExchangeRedis Azure-specific Redis extensions dotnet add package Microsoft.Azure.StackExchangeRedis
Files (skills)
  • SKILL.md 11.9 KB
    ---
    name: azure-resource-manager-redis-dotnet
    description: |
      Azure Resource Manager SDK for Redis in .NET. Use for MANAGEMENT PLANE operations: creating/managing Azure Cache for Redis instances, firewall rules, access keys, patch schedules, linked servers (geo-replication), and private endpoints via Azure Resource Manager. NOT for data plane operations (get/set keys, pub/sub) - use StackExchange.Redis for that. Triggers: "Redis cache", "create Redis", "manage Redis", "ARM Redis", "RedisResource", "provision Redis", "Azure Cache for Redis".
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: Azure.ResourceManager.Redis
    ---
    
    # Azure.ResourceManager.Redis (.NET)
    
    Management plane SDK for provisioning and managing Azure Cache for Redis resources via Azure Resource Manager.
    
    > **⚠️ Management vs Data Plane**
    > - **This SDK (Azure.ResourceManager.Redis)**: Create caches, configure firewall rules, manage access keys, set up geo-replication
    > - **Data Plane SDK (StackExchange.Redis)**: Get/set keys, pub/sub, streams, Lua scripts
    
    ## Installation
    
    ```bash
    dotnet add package Azure.ResourceManager.Redis
    dotnet add package Azure.Identity
    ```
    
    **Current Version**: 1.5.1 (Stable)  
    **API Version**: 2024-11-01  
    **Target Frameworks**: .NET 8.0, .NET Standard 2.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.Redis;
    
    // 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
            └── RedisResource
                ├── RedisFirewallRuleResource
                ├── RedisPatchScheduleResource
                ├── RedisLinkedServerWithPropertyResource
                ├── RedisPrivateEndpointConnectionResource
                └── RedisCacheAccessPolicyResource
    ```
    
    ## Core Workflows
    
    ### 1. Create Redis Cache
    
    ```csharp
    using Azure.ResourceManager.Redis;
    using Azure.ResourceManager.Redis.Models;
    
    // Get resource group
    var resourceGroup = await subscription
        .GetResourceGroupAsync("my-resource-group");
    
    // Define cache configuration
    var cacheData = new RedisCreateOrUpdateContent(
        location: AzureLocation.EastUS,
        sku: new RedisSku(RedisSkuName.Standard, RedisSkuFamily.BasicOrStandard, 1))
    {
        EnableNonSslPort = false,
        MinimumTlsVersion = RedisTlsVersion.Tls1_2,
        RedisConfiguration = new RedisCommonConfiguration
        {
            MaxMemoryPolicy = "volatile-lru"
        },
        Tags =
        {
            ["environment"] = "production"
        }
    };
    
    // Create cache (long-running operation)
    var cacheCollection = resourceGroup.Value.GetAllRedis();
    var operation = await cacheCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        "my-redis-cache",
        cacheData);
    
    RedisResource cache = operation.Value;
    Console.WriteLine($"Cache created: {cache.Data.HostName}");
    ```
    
    ### 2. Get Redis Cache
    
    ```csharp
    // Get existing cache
    var cache = await resourceGroup.Value
        .GetRedisAsync("my-redis-cache");
    
    Console.WriteLine($"Host: {cache.Value.Data.HostName}");
    Console.WriteLine($"Port: {cache.Value.Data.Port}");
    Console.WriteLine($"SSL Port: {cache.Value.Data.SslPort}");
    Console.WriteLine($"Provisioning State: {cache.Value.Data.ProvisioningState}");
    ```
    
    ### 3. Update Redis Cache
    
    ```csharp
    var patchData = new RedisPatch
    {
        Sku = new RedisSku(RedisSkuName.Standard, RedisSkuFamily.BasicOrStandard, 2),
        RedisConfiguration = new RedisCommonConfiguration
        {
            MaxMemoryPolicy = "allkeys-lru"
        }
    };
    
    var updateOperation = await cache.Value.UpdateAsync(
        WaitUntil.Completed,
        patchData);
    ```
    
    ### 4. Delete Redis Cache
    
    ```csharp
    await cache.Value.DeleteAsync(WaitUntil.Completed);
    ```
    
    ### 5. Get Access Keys
    
    ```csharp
    var keys = await cache.Value.GetKeysAsync();
    Console.WriteLine($"Primary Key: {keys.Value.PrimaryKey}");
    Console.WriteLine($"Secondary Key: {keys.Value.SecondaryKey}");
    ```
    
    ### 6. Regenerate Access Keys
    
    ```csharp
    var regenerateContent = new RedisRegenerateKeyContent(RedisRegenerateKeyType.Primary);
    var newKeys = await cache.Value.RegenerateKeyAsync(regenerateContent);
    Console.WriteLine($"New Primary Key: {newKeys.Value.PrimaryKey}");
    ```
    
    ### 7. Manage Firewall Rules
    
    ```csharp
    // Create firewall rule
    var firewallData = new RedisFirewallRuleData(
        startIP: System.Net.IPAddress.Parse("10.0.0.1"),
        endIP: System.Net.IPAddress.Parse("10.0.0.255"));
    
    var firewallCollection = cache.Value.GetRedisFirewallRules();
    var firewallOperation = await firewallCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        "allow-internal-network",
        firewallData);
    
    // List all firewall rules
    await foreach (var rule in firewallCollection.GetAllAsync())
    {
        Console.WriteLine($"Rule: {rule.Data.Name} ({rule.Data.StartIP} - {rule.Data.EndIP})");
    }
    
    // Delete firewall rule
    var ruleToDelete = await firewallCollection.GetAsync("allow-internal-network");
    await ruleToDelete.Value.DeleteAsync(WaitUntil.Completed);
    ```
    
    ### 8. Configure Patch Schedule (Premium SKU)
    
    ```csharp
    // Patch schedules require Premium SKU
    var scheduleData = new RedisPatchScheduleData(
        new[]
        {
            new RedisPatchScheduleSetting(RedisDayOfWeek.Saturday, 2) // 2 AM Saturday
            {
                MaintenanceWindow = TimeSpan.FromHours(5)
            },
            new RedisPatchScheduleSetting(RedisDayOfWeek.Sunday, 2) // 2 AM Sunday
            {
                MaintenanceWindow = TimeSpan.FromHours(5)
            }
        });
    
    var scheduleCollection = cache.Value.GetRedisPatchSchedules();
    await scheduleCollection.CreateOrUpdateAsync(
        WaitUntil.Completed,
        RedisPatchScheduleDefaultName.Default,
        scheduleData);
    ```
    
    ### 9. Import/Export Data (Premium SKU)
    
    ```csharp
    // Import data from blob storage
    var importContent = new ImportRdbContent(
        files: new[] { "https://mystorageaccount.blob.core.windows.net/container/dump.rdb" },
        format: "RDB");
    
    await cache.Value.ImportDataAsync(WaitUntil.Completed, importContent);
    
    // Export data to blob storage
    var exportContent = new ExportRdbContent(
        prefix: "backup",
        container: "https://mystorageaccount.blob.core.windows.net/container?sastoken",
        format: "RDB");
    
    await cache.Value.ExportDataAsync(WaitUntil.Completed, exportContent);
    ```
    
    ### 10. Force Reboot
    
    ```csharp
    var rebootContent = new RedisRebootContent
    {
        RebootType = RedisRebootType.AllNodes,
        ShardId = 0 // For clustered caches
    };
    
    await cache.Value.ForceRebootAsync(rebootContent);
    ```
    
    ## SKU Reference
    
    | SKU | Family | Capacity | Features |
    |-----|--------|----------|----------|
    | Basic | C | 0-6 | Single node, no SLA, dev/test only |
    | Standard | C | 0-6 | Two nodes (primary/replica), SLA |
    | Premium | P | 1-5 | Clustering, geo-replication, VNet, persistence |
    
    **Capacity Sizes (Family C - Basic/Standard)**:
    - C0: 250 MB
    - C1: 1 GB
    - C2: 2.5 GB
    - C3: 6 GB
    - C4: 13 GB
    - C5: 26 GB
    - C6: 53 GB
    
    **Capacity Sizes (Family P - Premium)**:
    - P1: 6 GB per shard
    - P2: 13 GB per shard
    - P3: 26 GB per shard
    - P4: 53 GB per shard
    - P5: 120 GB per shard
    
    ## Key Types Reference
    
    | Type | Purpose |
    |------|---------|
    | `ArmClient` | Entry point for all ARM operations |
    | `RedisResource` | Represents a Redis cache instance |
    | `RedisCollection` | Collection for cache CRUD operations |
    | `RedisFirewallRuleResource` | Firewall rule for IP filtering |
    | `RedisPatchScheduleResource` | Maintenance window configuration |
    | `RedisLinkedServerWithPropertyResource` | Geo-replication linked server |
    | `RedisPrivateEndpointConnectionResource` | Private endpoint connection |
    | `RedisCacheAccessPolicyResource` | RBAC access policy |
    | `RedisCreateOrUpdateContent` | Cache creation payload |
    | `RedisPatch` | Cache update payload |
    | `RedisSku` | SKU configuration (name, family, capacity) |
    | `RedisAccessKeys` | Primary and secondary access keys |
    | `RedisRegenerateKeyContent` | Key regeneration request |
    
    ## Best Practices
    
    1. **Use `WaitUntil.Completed`** for operations that must finish before proceeding
    2. **Use `WaitUntil.Started`** when you want to poll manually or run operations in parallel
    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., `cache.GetRedisFirewallRules()`)
    7. **Use Premium SKU** for production workloads requiring geo-replication, clustering, or persistence
    8. **Enable TLS 1.2 minimum** — set `MinimumTlsVersion = RedisTlsVersion.Tls1_2`
    9. **Disable non-SSL port** — set `EnableNonSslPort = false` for security
    10. **Rotate keys regularly** — use `RegenerateKeyAsync` and update connection strings
    
    ## Error Handling
    
    ```csharp
    using Azure;
    
    try
    {
        var operation = await cacheCollection.CreateOrUpdateAsync(
            WaitUntil.Completed, cacheName, cacheData);
    }
    catch (RequestFailedException ex) when (ex.Status == 409)
    {
        Console.WriteLine("Cache already exists");
    }
    catch (RequestFailedException ex) when (ex.Status == 400)
    {
        Console.WriteLine($"Invalid configuration: {ex.Message}");
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
    }
    ```
    
    ## Common Pitfalls
    
    1. **SKU downgrades not allowed** — You cannot downgrade from Premium to Standard/Basic
    2. **Clustering requires Premium** — Shard configuration only available on Premium SKU
    3. **Geo-replication requires Premium** — Linked servers only work with Premium caches
    4. **VNet injection requires Premium** — Virtual network support is Premium-only
    5. **Patch schedules require Premium** — Maintenance windows only configurable on Premium
    6. **Cache name globally unique** — Redis cache names must be unique across all Azure subscriptions
    7. **Long provisioning times** — Cache creation can take 15-20 minutes; use `WaitUntil.Started` for async patterns
    
    ## Connecting with StackExchange.Redis (Data Plane)
    
    After creating the cache with this management SDK, use StackExchange.Redis for data operations:
    
    ```csharp
    using StackExchange.Redis;
    
    // Get connection info from management SDK
    var cache = await resourceGroup.Value.GetRedisAsync("my-redis-cache");
    var keys = await cache.Value.GetKeysAsync();
    
    // Connect with StackExchange.Redis
    var connectionString = $"{cache.Value.Data.HostName}:{cache.Value.Data.SslPort},password={keys.Value.PrimaryKey},ssl=True,abortConnect=False";
    var connection = ConnectionMultiplexer.Connect(connectionString);
    var db = connection.GetDatabase();
    
    // Data operations
    await db.StringSetAsync("key", "value");
    var value = await db.StringGetAsync("key");
    ```
    
    ## Related SDKs
    
    | SDK | Purpose | Install |
    |-----|---------|---------|
    | `StackExchange.Redis` | Data plane (get/set, pub/sub, streams) | `dotnet add package StackExchange.Redis` |
    | `Azure.ResourceManager.Redis` | Management plane (this SDK) | `dotnet add package Azure.ResourceManager.Redis` |
    | `Microsoft.Azure.StackExchangeRedis` | Azure-specific Redis extensions | `dotnet add package Microsoft.Azure.StackExchangeRedis` |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related