Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 104 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,104 @@
# MigratingToAMR
Support for migrating Azure Redis workloads into Azure Managed Redis
# Migrating to Azure Managed Redis

Support for migrating Azure Cache for Redis workloads into Azure Managed Redis (AMR).

## Overview

This repository provides tooling to migrate an existing **Azure Cache for Redis** instance to **Azure Managed Redis** using the ARM REST API. The migration is a DNS-switchover-based, live migration that keeps your endpoint and credentials intact — clients reconnect automatically without needing configuration changes.

## Contents

| Path | Description |
| ---- | ----------- |
| [Scripts/Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1](Scripts/Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1) | PowerShell script for driving the full migration lifecycle via ARM REST APIs |

## Prerequisites

- [Az PowerShell module](https://learn.microsoft.com/powershell/azure/install-azps-windows) installed
- An existing **Azure Cache for Redis** instance (source)
- An existing **Azure Managed Redis** instance (target) in the same subscription
- Sufficient RBAC permissions on both resources

## Script: Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1

The script supports four actions that map to the migration lifecycle:

| Action | Description |
| ------ | ----------- |
| `Validate` | Checks whether the source and target caches are compatible for migration and reports any disparities |
| `Migrate` | Initiates the migration (DNS switchover; data migration is skipped by default) |
| `Status` | Retrieves the current state of an in-progress or completed migration |
| `Cancel` | Cancels an in-progress migration |

### Parameters

| Parameter | Required | Default | Description |
| --------- | -------- | ------- | ----------- |
| `-Action` | Yes | — | One of `Validate`, `Migrate`, `Status`, `Cancel` |
| `-TargetResourceId` | Yes | — | Full ARM resource ID of the target Azure Managed Redis cluster |
| `-SourceResourceId` | For `Validate` / `Migrate` | — | Full ARM resource ID of the source Azure Cache for Redis instance |
| `-ForceMigrate` | No | `$false` | When `$true`, proceeds with migration even if parity validation returns warnings |
| `-TrackMigration` | No | `$false` | When set, blocks until the long-running operation completes |
| `-Environment` | No | `AzureCloud` | Azure environment. Allowed values: `AzureCloud`, `AzureChinaCloud`, `AzureUSGovernment`, `AzureGermanCloud` |
| `-Help` | No | `$false` | Displays full help for the script |

### Usage Examples

**Validate compatibility before migrating:**

```powershell
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 `
-Action Validate `
-SourceResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/Redis/<source>" `
-TargetResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/redisEnterprise/<target>"
```

**Start migration and wait for completion:**

```powershell
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 `
-Action Migrate `
-SourceResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/Redis/<source>" `
-TargetResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/redisEnterprise/<target>" `
-TrackMigration
```

**Start migration, ignoring parity warnings:**

```powershell
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 `
-Action Migrate `
-SourceResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/Redis/<source>" `
-TargetResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/redisEnterprise/<target>" `
-ForceMigrate $true
```

**Check migration status:**

```powershell
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 `
-Action Status `
-TargetResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/redisEnterprise/<target>"
```

**Cancel an in-progress migration:**

```powershell
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 `
-Action Cancel `
-TargetResourceId "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Cache/redisEnterprise/<target>"
```

## Migration Flow

```mermaid
flowchart LR
Validate --> Migrate --> Status
Status -.-> Cancel
style Cancel stroke-dasharray: 5 5
```

1. **Validate** — confirm the source and target are compatible.
2. **Migrate** — triggers the ARM long-running operation. DNS is switched so the source hostname begins resolving to the AMR endpoint.
3. **Status** — poll until the migration reports a terminal state (`Succeeded` or `Failed`).
4. **Cancel** — available while migration is still in progress.
29 changes: 26 additions & 3 deletions Scripts/Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
If set to $false (default), migration is blocked when validation returns any warning.
.PARAMETER Environment
The Azure environment to use (default is the public "AzureCloud").
Some possible values: "AzureCloud", "AzureChinaCloud", "AzureUSGovernment", "AzureGermanCloud".
.PARAMETER TrackMigration
If set, the script will wait for the migration operation to complete (default is $false).
.PARAMETER Verbose
Expand All @@ -25,6 +26,8 @@
Initiates a migration and tracks its progress.
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 -Action Migrate -SourceResourceId "/subscriptions/xxxxx/resourceGroups/rg1/providers/Microsoft.Cache/Redis/redis1" -TargetResourceId "/subscriptions/xxxxx/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/amr1" -ForceMigrate $true
Initiates a migration and forces migration when parity validation returns warnings.
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 -Action Validate -SourceResourceId "/subscriptions/xxxxx/resourceGroups/rg1/providers/Microsoft.Cache/Redis/redis1" -TargetResourceId "/subscriptions/xxxxx/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/amr1"
Validates whether a migration can be performed between the source and target caches.
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 -Action Status -TargetResourceId "/subscriptions/xxxxx/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/amr1"
Checks the status of the migration.
.\Azure-Redis-Migration-Arm-Rest-Api-Utility.ps1 -Action Cancel -TargetResourceId "/subscriptions/xxxxx/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/amr1"
Expand All @@ -37,7 +40,7 @@
param
(
[Parameter()]
[ValidateSet("Migrate", "Status", "Cancel")]
[ValidateSet("Migrate", "Validate", "Status", "Cancel")]
[string] $Action,

[Parameter()]
Expand Down Expand Up @@ -77,7 +80,7 @@ if ($Help)
}

# Parse the TargetResourceId (Azure Managed Redis resourceId)
$pattern = '(?i)^/subscriptions/(?<SubscriptionId>[^/]+)/resourceGroups/(?<ResourceGroupName>[^/]+)/providers/[^/]+/redisEnterprise/(?<AmrCacheName>[^/]+)(?:/.*)?/?$'
$pattern = '(?i)^/subscriptions/(?<SubscriptionId>[^/]+)/resourceGroups/(?<ResourceGroupName>[^/]+)/providers/Microsoft\.Cache/redisEnterprise/(?<AmrCacheName>[^/]+)(?:/.*)?/?$'

if ($TargetResourceId -match $pattern) {
$SubscriptionId = $Matches.SubscriptionId
Expand Down Expand Up @@ -226,8 +229,28 @@ switch ($Action)
break
}

"Validate"
{
$payload = @{
properties = @{
sourceResourceId = $SourceResourceId;
skipDataMigration = $true;
};
} | ConvertTo-Json -Depth 3

Write-Host "This command will validate whether a migration can be performed between the source and target caches."
$response = Invoke-AzRestMethod `
-Method POST `
-Path "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Cache/RedisEnterprise/$AmrCacheName/migrations/default/validate?api-version=$ArmApiVersion" `
-Payload $payload

Print-Response $response

break
}

Default
{
throw "Invalid action specified. Please use one of the following: 'Migrate', 'Status', 'Cancel'."
throw "Invalid action specified. Please use one of the following: 'Migrate', 'Validate', 'Status', 'Cancel'."
}
}