Generated banner for Azure Cloud Migrate
Generated logo for Azure Cloud Migrate

Azure Cloud Migrate

MicrosoftOfficialCreated by Microsoft

  • Skill
  • Workflow
  • Cloud and DevOps
  • MIT
  • Low risk

From the author

Assess and migrate cross-cloud workloads to Azure with reports and code conversion. Supports Lambda→Functions, Beanstalk/Heroku/App Engine→App Service, Fargate/Kubernetes/Cloud Run/Spring Boot→Container Apps. WHEN: migrate Lambda to Functions, AWS to Azure, migrate Beanstalk, migrate Heroku, migrate App Engine, Cloud Run migration, Fargate to ACA, ECS/Kubernetes/GKE/EKS to Container Apps, Spring Boot to Container Apps, cross-cloud migration.
— the description by Microsoft

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

Azure Cloud Migrate provides a structured, multi-phase workflow for transitioning applications from various cloud platforms to Azure. It focuses on assessing the current architecture, mapping services to Azure equivalents, and performing the necessary code and configuration conversions. The skill ensures a methodical approach by requiring an assessment report before any migration actions occur, and it provides specific guidance for common migration paths such as AWS Lambda to Azure Functions, Heroku to App Service, and Kubernetes to Container Apps.

What it does

  • Generates comprehensive migration assessment reports for cross-cloud workloads.
  • Maps source platform services, compute configurations, and dependencies to Azure equivalents.
  • Provides guidance for converting application code and configuration files.
  • Audits source code for platform-specific service discovery patterns.
  • Creates architecture diagrams for both current and target states.
  • Tracks migration progress and provides resource-level status updates.

When to use it

  • When planning to migrate workloads from AWS Lambda, Elastic Beanstalk, or Fargate to Azure.
  • When moving applications from Heroku or Google App Engine to Azure App Service.
  • When transitioning Kubernetes or Cloud Run deployments to Azure Container Apps.
  • When you need a structured assessment of migration readiness and effort.

Advantages

  • Ensures a consistent, step-by-step migration process.
  • Reduces risk by requiring a detailed assessment report before code changes.
  • Provides clear mapping between source platform features and Azure services.
  • Includes specific checks for common migration pitfalls like hardcoded service discovery.

Usage examples

“Assess my current AWS Lambda project for migration to Azure Functions.”
The agent will analyze the Lambda project, map the services to Azure Functions, and generate a migration assessment report in the output directory.
“Migrate my Heroku application to Azure App Service.”
The agent will perform an assessment, guide the conversion of configuration files, and assist in setting up the application for Azure App Service.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/microsoft/azure-cloud-migrate/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip azure-cloud-migrate.zip -d .agents/skills

Documentation by Microsoft

Azure Cloud Migrate

This skill handles assessment and code migration of existing cloud workloads to Azure.

Rules

  1. Follow phases sequentially — do not skip

  2. Generate assessment before any code migration

  3. Load the scenario reference and follow its rules

  4. Use mcp_azure_mcp_get_azure_bestpractices and mcp_azure_mcp_documentation MCP tools

  5. Use the latest supported runtime for the target service

  6. Destructive actions require ask_user — functions global-rules | app-service global-rules

  7. Report progress to user — During long-running operations (deployments, image pushes), provide resource-level status updates so the user is never left waiting without feedback — see workflow-details.md

  8. Audit service discovery in app code — Kubernetes DNS names (e.g., http://order-service:3001) do not resolve in Container Apps. During assessment, scan source code for hardcoded hostnames/ports in HTTP clients and flag them for env-var-driven URL injection

Migration Scenarios

SourceTargetReference
AWS LambdaAzure Functionslambda-to-functions.md (assessment, code-migration)
AWS Elastic BeanstalkAzure App Servicebeanstalk-to-app-service.md
HerokuAzure App Serviceheroku-to-app-service.md
Google App EngineAzure App Serviceapp-engine-to-app-service.md
AWS Fargate (ECS)Azure Container Appsfargate-to-container-apps.md (assessment, deployment)
Kubernetes (GKE/EKS/Self-hosted)Azure Container Appsk8s-to-container-apps.md
GCP Cloud RunAzure Container Appscloudrun-to-container-apps.md
Spring Boot (Azure Spring Apps/VMs)Azure Container Appsspring-apps-to-aca.md

No matching scenario? Use mcp_azure_mcp_documentation and mcp_azure_mcp_get_azure_bestpractices tools.

Output Directory

All output goes to <workspace-root-basename>-azure/ at workspace root, where <workspace-root-basename> is the name of the top-level workspace directory itself (NOT a subdirectory within it). Never modify the source directory.

Steps

  1. Create <workspace-root-basename>-azure/ at workspace root

  2. Assess — Analyze source, map services, generate report using the scenario-specific assessment guide → functions assessment | app-service assessment

  3. Migrate — Convert code/config using the scenario-specific migration guide → functions code-migration | app-service code-migration

  4. Ask User — "Migration complete. Test locally or deploy to Azure?"

  5. Hand off to azure-prepare for infrastructure, testing, and deployment

Track progress in migration-status.md — see workflow-details.md.

Files

references/services/container-apps/deployment-guide.md

Kubernetes to Azure Container Apps - Deployment Guide

Prerequisites

Azure CLI 2.53.0+, kubectl, Docker, Azure subscription, ACR, Key Vault, Log Analytics

Phase 1: Export Kubernetes Resources

kubectl get deployments,services,ingress -n <namespace> -o wide
kubectl get configmaps,secrets -n <namespace>
Export Script
#!/bin/bash
set -euo pipefail
NAMESPACE="${K8S_NAMESPACE:-<namespace>}"
OUTPUT_DIR="${OUTPUT_DIR:-k8s-export}"
mkdir -p "$OUTPUT_DIR"
kubectl get deploy,svc,ingress,configmap,secret -n "$NAMESPACE" -o yaml > "$OUTPUT_DIR/all-resources.yaml"
for deploy in $(kubectl get deploy -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}'); do
  kubectl get deployment "$deploy" -n "$NAMESPACE" -o yaml > "$OUTPUT_DIR/deploy-${deploy}.yaml"
done

Phase 2: Assess Compatibility

Load assessment-guide.md. Check: StatefulSets, DaemonSets, CRDs, resource limits (>4 vCPU/>8 GiB), PVCs, NetworkPolicies.

Phase 3: Migrate Images

⚠️ Warning: Azure Container Apps only runs linux/amd64 images. If you build on Apple Silicon or another ARM host, use docker buildx build --platform linux/amd64 or az acr build (which builds amd64 by default). Verify with docker inspect <image> --format '{{.Architecture}}'.

Bash
#!/bin/bash
set -euo pipefail
ACR_NAME="${ACR_NAME:-<acr>}"
SOURCE_REGISTRY="${SOURCE_REGISTRY:-<registry>}"
az acr login --name "$ACR_NAME"
az acr import --name "$ACR_NAME" --source "${SOURCE_REGISTRY}/app:v1.0" --image app:v1.0
PowerShell
$ACR_NAME = if ($env:ACR_NAME) { $env:ACR_NAME } else { "<acr>" }
$SOURCE_REGISTRY = if ($env:SOURCE_REGISTRY) { $env:SOURCE_REGISTRY } else { "<registry>" }
az acr login --name $ACR_NAME
az acr import --name $ACR_NAME --source "${SOURCE_REGISTRY}/app:v1.0" --image app:v1.0

Phase 4: Infrastructure

Bash
az group create --name myapp-rg --location eastus
az monitor log-analytics workspace create --resource-group myapp-rg --workspace-name myapp-logs --location eastus
LOG_ID=$(az monitor log-analytics workspace show --resource-group myapp-rg --workspace-name myapp-logs --query customerId -o tsv)
LOG_KEY=$(az monitor log-analytics workspace get-shared-keys --resource-group myapp-rg --workspace-name myapp-logs --query primarySharedKey -o tsv)
az containerapp env create --name myapp-env --resource-group myapp-rg --location eastus --logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY"
PowerShell
az group create --name myapp-rg --location eastus
az monitor log-analytics workspace create --resource-group myapp-rg --workspace-name myapp-logs --location eastus
$LOG_ID = az monitor log-analytics workspace show --resource-group myapp-rg --workspace-name myapp-logs --query customerId -o tsv
$LOG_KEY = az monitor log-analytics workspace get-shared-keys --resource-group myapp-rg --workspace-name myapp-logs --query primarySharedKey -o tsv
az containerapp env create --name myapp-env --resource-group myapp-rg --location eastus --logs-workspace-id $LOG_ID --logs-workspace-key $LOG_KEY

VNet: For VNet integration, create VNet first, get subnet ID, then use --infrastructure-subnet-resource-id with env create.

Phase 5: Secrets

Tip: Prefer piping decoded secret values directly to az keyvault secret set --value to avoid writing sensitive data to disk.

Bash
ACR_NAME="${ACR_NAME:-<acr>}"

# Create Key Vault and migrate secrets (pipe directly — no temp file)
az keyvault create --name myapp-kv --resource-group myapp-rg --location eastus
az keyvault secret set --vault-name myapp-kv --name password --value "$(kubectl get secret mysecret -n <namespace> -o jsonpath='{.data.password}' | base64 -d)"

# Create managed identity and grant permissions
az identity create --name myapp-id --resource-group myapp-rg --location eastus
IDENTITY_ID=$(az identity show --name myapp-id --resource-group myapp-rg --query id -o tsv)
PRINCIPAL_ID=$(az identity show --name myapp-id --resource-group myapp-rg --query principalId -o tsv)
KV_ID=$(az keyvault show --name myapp-kv --resource-group myapp-rg --query id -o tsv)
az role assignment create --assignee "$PRINCIPAL_ID" --role "Key Vault Secrets User" --scope "$KV_ID"
ACR_ID=$(az acr show --name "$ACR_NAME" --query id -o tsv)
az role assignment create --assignee "$PRINCIPAL_ID" --role AcrPull --scope "$ACR_ID"
PowerShell
$ACR_NAME = if ($env:ACR_NAME) { $env:ACR_NAME } else { "<acr>" }

# Create Key Vault and migrate secrets (pass directly — no temp file, no BOM issues)
az keyvault create --name myapp-kv --resource-group myapp-rg --location eastus
$secretValue = kubectl get secret mysecret -n <namespace> -o jsonpath='{.data.password}'
$decodedSecretValue = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secretValue))
az keyvault secret set --vault-name myapp-kv --name password --value $decodedSecretValue
Remove-Variable -Name decodedSecretValue, secretValue -ErrorAction SilentlyContinue

# Create managed identity and grant permissions
az identity create --name myapp-id --resource-group myapp-rg --location eastus
$IDENTITY_ID = az identity show --name myapp-id --resource-group myapp-rg --query id -o tsv
$PRINCIPAL_ID = az identity show --name myapp-id --resource-group myapp-rg --query principalId -o tsv
$KV_ID = az keyvault show --name myapp-kv --resource-group myapp-rg --query id -o tsv
az role assignment create --assignee $PRINCIPAL_ID --role "Key Vault Secrets User" --scope $KV_ID
$ACR_ID = az acr show --name $ACR_NAME --query id -o tsv
az role assignment create --assignee $PRINCIPAL_ID --role AcrPull --scope $ACR_ID

Phase 6: Deploy

⚠️ Warning: Service Discovery Changes — In Kubernetes, pods reach other services by short DNS name (e.g., http://order-service:3001). In Container Apps, internal services use HTTPS FQDNs (e.g., https://order-service.internal.<env-domain>). Audit application code for hardcoded Kubernetes hostnames/ports in HTTP clients, proxy logic, or connection strings — these must be replaced with env-var-driven URLs that point to the Container Apps internal FQDN.

Mapping: spec.containers[].image → template.containers[].image; spec.containers[].ports[].containerPort → ingress.targetPort; spec.replicas → scale.minReplicas. Service types: ClusterIP → external: false; LoadBalancer/NodePort → external: true.

# Get Key Vault secret URI and deploy
SECRET_URI=$(az keyvault secret show --vault-name myapp-kv --name password --query id -o tsv)
az containerapp create --name my-app --resource-group myapp-rg --environment myapp-env \
  --image $ACR_NAME.azurecr.io/app:v1.0 --target-port 8080 --ingress external \
  --cpu 1.0 --memory 2Gi --min-replicas 2 --max-replicas 10 \
  --user-assigned $IDENTITY_ID --registry-identity $IDENTITY_ID --registry-server $ACR_NAME.azurecr.io \
  --secrets password=keyvaultref:$SECRET_URI,identityref:$IDENTITY_ID \
  --env-vars ENV=prod DB_PASSWORD=secretref:password \
  --scale-rule-name http --scale-rule-type http --scale-rule-http-concurrency 80
$SECRET_URI = az keyvault secret show --vault-name myapp-kv --name password --query id -o tsv
az containerapp create --name my-app --resource-group myapp-rg --environment myapp-env `
  --image "$ACR_NAME.azurecr.io/app:v1.0" --target-port 8080 --ingress external `
  --cpu 1.0 --memory 2Gi --min-replicas 2 --max-replicas 10 `
  --user-assigned $IDENTITY_ID --registry-identity $IDENTITY_ID --registry-server "$ACR_NAME.azurecr.io" `
  --secrets "password=keyvaultref:$SECRET_URI,identityref:$IDENTITY_ID" `
  --env-vars ENV=prod DB_PASSWORD=secretref:password `
  --scale-rule-name http --scale-rule-type http --scale-rule-http-concurrency 80

Phase 7: Validation

# Get app FQDN and test
FQDN=$(az containerapp show --name my-app --resource-group myapp-rg --query properties.configuration.ingress.fqdn -o tsv)
echo "App URL: https://$FQDN"
curl https://$FQDN/health

# View logs
az containerapp logs show --name my-app --resource-group myapp-rg --follow
$FQDN = az containerapp show --name my-app --resource-group myapp-rg --query properties.configuration.ingress.fqdn -o tsv
Write-Host "App URL: https://$FQDN"
Invoke-WebRequest -Uri "https://$FQDN/health" -Method Head

# View logs
az containerapp logs show --name my-app --resource-group myapp-rg --follow

Troubleshooting

IssueSolution
Image pullVerify ACR: az acr check-health --name $ACR_NAME; check AcrPull role
Wrong architectureACA requires linux/amd64. Check: docker inspect <image> --format '{{.Architecture}}'. Rebuild with --platform linux/amd64
Port mismatchVerify targetPort matches app port
OOMIncrease memory limit (up to 4 vCPU / 8 GiB max per container)
DNSRetrieve FQDN: az containerapp show --name <app> -g <rg> --query properties.configuration.ingress.fqdn -o tsv
NSG blocking provisioningIf VNet-integrated, ensure NSG does not have a custom DenyAllInbound at low priority — it blocks Azure Load Balancer probes and VNet-internal traffic. The default rules (65000-65500) handle deny. Add explicit AllowAzureLoadBalancer rule
SecretRef not found--env-vars KEY=secretref:name requires --secrets name=value (or keyvaultref) in the same az containerapp create command
ARM deployment locksIf a Bicep deployment is stuck with Container Apps InProgress, run az deployment group cancel -g <rg> -n <deployment> before attempting CLI updates or deletes
Service-to-service timeoutKubernetes DNS names (http://svc:port) don't work in ACA. Ensure app code reads ORDER_SERVICE_URL (or equivalent) env var pointing to the internal FQDN

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

What our scanner noticed· Low risk

  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Microsoft
Publisher
Microsoft (Official)
Source
microsoft/skills · .github/plugins/azure-skills/skills/azure-cloud-migrate · commit 0696600
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from .github/plugins/azure-skills/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
microsoft/azure-skills

AutoGineer is not affiliated with or endorsed by Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-cloud-migrate.zip