azure-resource-manager-redis-dotnet — Claude Code skill: manage Azure
A skill for provisioning and managing Azure Cache for Redis through Azure Resource Manager in .NET: caches, firewall rules, access keys, geo-replication.
npx skills add microsoft/skills --skill azure-resource-manager-redis-dotnet -a claude-codeWhat azure-resource-manager-redis-dotnet does
The skill covers the Azure.ResourceManager.Redis management plane SDK for .NET. With it the agent creates and deletes Azure Cache for Redis instances, sets firewall rules, reads and regenerates access keys, configures patch schedules, links servers for geo-replication and wires up private endpoints. The resource hierarchy runs from ArmClient to a subscription, a resource group and then RedisResource.
Authentication needs Azure.Identity and the AZURE_SUBSCRIPTION_ID variable; in production DefaultAzureCredential expects AZURE_TOKEN_CREDENTIALS=prod, and a service principal also needs AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET. Packages come in with dotnet add package Azure.ResourceManager.Redis and dotnet add package Azure.Identity. Target frameworks are .NET 8.0 and .NET Standard 2.0.
One boundary matters: this is a resource-management SDK only. Key get/set, pub/sub, streams and Lua scripts are out of scope — those go through StackExchange.Redis. Patch schedules and data import via ImportRdbContent require the Premium SKU, so on a basic tier those calls fail.
What it helps with
- create an Azure Cache for Redis instance from .NET code
- set firewall rules on a cache
- read and regenerate access keys
- link two caches for geo-replication
- configure a patch schedule on Premium SKU
Example prompts for the agent
- Create an Azure Cache for Redis in
my-resource-groupusingAzure.ResourceManager.Redis - Add a firewall rule
allow-internal-networkto the cachemy-redis-cache - Regenerate the primary access key for
my-redis-cache
How to install azure-resource-manager-redis-dotnet
1Skills CLI (Vercel)
npx skills add microsoft/skills --skill azure-resource-manager-redis-dotnet -a claude-code2Manually: put the files in place
~/.claude/skills/azure-resource-manager-redis-dotnet/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/azure-resource-manager-redis-dotnet/
Manually: put the files in place
.agents/skills/azure-resource-manager-redis-dotnet/SKILL.mdFor all projects use ~/.agents/skills/
Manually: put the files in place
.cursor/skills/azure-resource-manager-redis-dotnet/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install microsoft/skills azure-resource-manager-redis-dotnet2Manually: put the files in place
.github/skills/azure-resource-manager-redis-dotnet/SKILL.mdPlatform CLI
gemini skills install https://github.com/microsoft/skills --path .github/plugins/azure-sdk-dotnet/skills/azure-resource-manager-redis-dotnetManually: put the files in place
.devin/skills/azure-resource-manager-redis-dotnet/SKILL.mdThe legacy .windsurf/skills/ path still works
Claude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about azure-resource-manager-redis-dotnet
How do I install azure-resource-manager-redis-dotnet in Claude Code?
Run npx skills add microsoft/skills --skill azure-resource-manager-redis-dotnet -a claude-code. The skill lands at ~/.claude/skills/azure-resource-manager-redis-dotnet/SKILL.md.
What does azure-resource-manager-redis-dotnet do?
It helps the agent write code that manages Azure Cache for Redis through Azure Resource Manager: cache creation, firewall rules, access keys, patch schedules, geo-replication and private endpoints.
Can this skill read and write Redis keys?
No. It is a management plane SDK; data operations such as get/set, pub/sub, streams and Lua go through StackExchange.Redis.
Source text
SKILL.md · MIT
---
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` |
© Microsoft · MIT · microsoft/skills