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
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-cloud-migrate/downloadUnzip 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
Follow phases sequentially — do not skip
Generate assessment before any code migration
Load the scenario reference and follow its rules
Use
mcp_azure_mcp_get_azure_bestpracticesandmcp_azure_mcp_documentationMCP toolsUse the latest supported runtime for the target service
Destructive actions require
ask_user— functions global-rules | app-service global-rulesReport 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
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
| Source | Target | Reference |
|---|---|---|
| AWS Lambda | Azure Functions | lambda-to-functions.md (assessment, code-migration) |
| AWS Elastic Beanstalk | Azure App Service | beanstalk-to-app-service.md |
| Heroku | Azure App Service | heroku-to-app-service.md |
| Google App Engine | Azure App Service | app-engine-to-app-service.md |
| AWS Fargate (ECS) | Azure Container Apps | fargate-to-container-apps.md (assessment, deployment) |
| Kubernetes (GKE/EKS/Self-hosted) | Azure Container Apps | k8s-to-container-apps.md |
| GCP Cloud Run | Azure Container Apps | cloudrun-to-container-apps.md |
| Spring Boot (Azure Spring Apps/VMs) | Azure Container Apps | spring-apps-to-aca.md |
No matching scenario? Use
mcp_azure_mcp_documentationandmcp_azure_mcp_get_azure_bestpracticestools.
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
Create
<workspace-root-basename>-azure/at workspace rootAssess — Analyze source, map services, generate report using the scenario-specific assessment guide → functions assessment | app-service assessment
Migrate — Convert code/config using the scenario-specific migration guide → functions code-migration | app-service code-migration
Ask User — "Migration complete. Test locally or deploy to Azure?"
Hand off to azure-prepare for infrastructure, testing, and deployment
Track progress in migration-status.md — see workflow-details.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer989 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md4.3 KiB
- references/services/app-service/app-engine-to-app-service.md7.1 KiB
- references/services/app-service/assessment.md5.2 KiB
- references/services/app-service/beanstalk-to-app-service.md6.4 KiB
- references/services/app-service/code-migration.md5.0 KiB
- references/services/app-service/global-rules.md2.8 KiB
- references/services/app-service/heroku-to-app-service.md7.5 KiB
- references/services/container-apps/assessment-guide.md7.0 KiB
- references/services/container-apps/cloudrun-assessment-guide.md2.5 KiB
- references/services/container-apps/cloudrun-deployment-guide.md7.9 KiB
- references/services/container-apps/cloudrun-to-container-apps.md2.2 KiB
- references/services/container-apps/deployment-guide.md9.6 KiB
- references/services/container-apps/fargate-assessment-guide.md2.4 KiB
- references/services/container-apps/fargate-deployment-guide.md10.1 KiB
- references/services/container-apps/fargate-to-container-apps.md4.0 KiB
- references/services/container-apps/k8s-to-container-apps.md4.9 KiB
- references/services/container-apps/spring-apps-to-aca.md3.8 KiB
- references/services/container-apps/spring-assessment-guide.md5.2 KiB
- references/services/container-apps/spring-dependency-patterns.md1.2 KiB
- references/services/container-apps/spring-deployment-guide.md15.1 KiB
- references/services/functions/assessment.md6.3 KiB
- references/services/functions/code-migration.md6.0 KiB
- references/services/functions/global-rules.md3.3 KiB
- references/services/functions/lambda-to-functions.md10.2 KiB
- references/services/functions/runtimes/csharp.md5.5 KiB
- references/services/functions/runtimes/java.md6.4 KiB
- references/services/functions/runtimes/javascript.md8.5 KiB
- references/services/functions/runtimes/powershell.md5.0 KiB
- references/services/functions/runtimes/python.md6.4 KiB
- references/services/functions/runtimes/typescript.md3.5 KiB
- references/workflow-details.md2.3 KiB
references/services/container-apps/spring-deployment-guide.md
Deployment Guide: Spring Boot to Azure Container Apps
Phase 1: Create Container Apps Environment
Bash:
#!/bin/bash
set -euo pipefail
az group create --name spring-rg --location eastus
az monitor log-analytics workspace create --resource-group spring-rg --workspace-name spring-logs --location eastus
LOG_ID=$(az monitor log-analytics workspace show --resource-group spring-rg --workspace-name spring-logs --query customerId -o tsv)
LOG_KEY=$(az monitor log-analytics workspace get-shared-keys --resource-group spring-rg --workspace-name spring-logs --query primarySharedKey -o tsv)
az containerapp env create --name spring-env --resource-group spring-rg --location eastus --logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY"PowerShell:
az group create --name spring-rg --location eastus
az monitor log-analytics workspace create --resource-group spring-rg --workspace-name spring-logs --location eastus
$LOG_ID = az monitor log-analytics workspace show --resource-group spring-rg --workspace-name spring-logs --query customerId -o tsv
$LOG_KEY = az monitor log-analytics workspace get-shared-keys --resource-group spring-rg --workspace-name spring-logs --query primarySharedKey -o tsv
az containerapp env create --name spring-env --resource-group spring-rg --location eastus --logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY"Phase 2: Configure Logging
Update application.properties:
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%nConfigure diagnostic settings: Azure Monitor Log Analytics (recommended), Event Hubs, or third-party solutions.
Phase 3: Containerize Application
Dockerfile:
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]Build and push (Bash):
ACR_NAME="${ACR_NAME:-<acr>}"
az acr create --name "$ACR_NAME" --resource-group spring-rg --sku Basic --location eastus
az acr login --name "$ACR_NAME"
docker build -t "${ACR_NAME}.azurecr.io/spring-app:v1.0" .
docker push "${ACR_NAME}.azurecr.io/spring-app:v1.0"Build and push (PowerShell):
$ACR_NAME = if ($env:ACR_NAME) { $env:ACR_NAME } else { "<acr>" }
az acr create --name "$ACR_NAME" --resource-group spring-rg --sku Basic --location eastus
az acr login --name "$ACR_NAME"
docker build -t "${ACR_NAME}.azurecr.io/spring-app:v1.0" .
docker push "${ACR_NAME}.azurecr.io/spring-app:v1.0"Phase 4: Configure Storage (if needed)
Azure Files for persistent storage (Bash):
STORAGE_ACCOUNT="${STORAGE_ACCOUNT:-<storage-account>}"
az storage account create --name "$STORAGE_ACCOUNT" --resource-group spring-rg --location eastus --sku Standard_LRS
STORAGE_KEY=$(az storage account keys list --account-name "$STORAGE_ACCOUNT" --resource-group spring-rg --query "[0].value" -o tsv)
az storage share create --name spring-data --account-name "$STORAGE_ACCOUNT" --account-key "$STORAGE_KEY"
az containerapp env storage set --name spring-env --resource-group spring-rg --storage-name spring-storage \
--azure-file-account-name "$STORAGE_ACCOUNT" --azure-file-account-key "$STORAGE_KEY" \
--azure-file-share-name spring-data --access-mode ReadWriteAzure Files for persistent storage (PowerShell):
$STORAGE_ACCOUNT = if ($env:STORAGE_ACCOUNT) { $env:STORAGE_ACCOUNT } else { "<storage-account>" }
az storage account create --name "$STORAGE_ACCOUNT" --resource-group spring-rg --location eastus --sku Standard_LRS
$STORAGE_KEY = az storage account keys list --account-name "$STORAGE_ACCOUNT" --resource-group spring-rg --query "[0].value" -o tsv
az storage share create --name spring-data --account-name "$STORAGE_ACCOUNT" --account-key "$STORAGE_KEY"
az containerapp env storage set --name spring-env --resource-group spring-rg --storage-name spring-storage `
--azure-file-account-name "$STORAGE_ACCOUNT" --azure-file-account-key "$STORAGE_KEY" `
--azure-file-share-name spring-data --access-mode ReadWritePhase 5: Migrate Secrets to Key Vault
Security Note: Avoid passing secrets via
--valueon the command line (leaks via shell history). Use--filewith a protected temp file or prompt securely instead.
Bash:
ACR_NAME="${ACR_NAME:-<acr>}" # From Phase 3
KEY_VAULT="${KEY_VAULT:-<keyvault>}"
az keyvault create --name "$KEY_VAULT" --resource-group spring-rg --location eastus
IDENTITY_ID=$(az identity create --name spring-id --resource-group spring-rg --location eastus --query id -o tsv)
PRINCIPAL_ID=$(az identity show --ids "$IDENTITY_ID" --query principalId -o tsv)
az keyvault set-policy --name "$KEY_VAULT" --object-id "$PRINCIPAL_ID" --secret-permissions get list
# Secure approach using temp file
SECRET_FILE=$(mktemp)
trap 'shred -u "$SECRET_FILE" 2>/dev/null || rm -f "$SECRET_FILE"' EXIT
read -s -p "Enter database password: " DB_PASSWORD
echo -n "$DB_PASSWORD" > "$SECRET_FILE"
az keyvault secret set --vault-name "$KEY_VAULT" --name db-password --file "$SECRET_FILE"
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>" } # From Phase 3
$KEY_VAULT = if ($env:KEY_VAULT) { $env:KEY_VAULT } else { "<keyvault>" }
az keyvault create --name "$KEY_VAULT" --resource-group spring-rg --location eastus
$IDENTITY_ID = az identity create --name spring-id --resource-group spring-rg --location eastus --query id -o tsv
$PRINCIPAL_ID = az identity show --ids "$IDENTITY_ID" --query principalId -o tsv
az keyvault set-policy --name "$KEY_VAULT" --object-id "$PRINCIPAL_ID" --secret-permissions get list
# Secure approach using temp file
$SECRET_FILE = [System.IO.Path]::GetTempFileName()
try {
$SecurePassword = Read-Host "Enter database password" -AsSecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
try {
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[System.IO.File]::WriteAllText($SECRET_FILE, $PlainPassword)
az keyvault secret set --vault-name "$KEY_VAULT" --name db-password --file "$SECRET_FILE"
} finally {
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
}
} finally {
Remove-Item $SECRET_FILE -Force -ErrorAction SilentlyContinue
}
$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 Container App
Bash:
ACR_NAME="${ACR_NAME:-<acr>}" # From Phase 3
KEY_VAULT="${KEY_VAULT:-<keyvault>}" # From Phase 5
IDENTITY_ID="${IDENTITY_ID:?Set IDENTITY_ID from Phase 5}"
SECRET_URI=$(az keyvault secret show --vault-name "$KEY_VAULT" --name db-password --query id -o tsv)
az containerapp create --name spring-app --resource-group spring-rg --environment spring-env \
--image "${ACR_NAME}.azurecr.io/spring-app:v1.0" --target-port 8080 --ingress external \
--cpu 2.0 --memory 4Gi --min-replicas 2 --max-replicas 10 \
--user-assigned "$IDENTITY_ID" --registry-identity "$IDENTITY_ID" --registry-server "${ACR_NAME}.azurecr.io" \
--secrets db-password=keyvaultref:"${SECRET_URI}",identityref:"${IDENTITY_ID}" \
--env-vars SPRING_DATASOURCE_PASSWORD=secretref:db-password SPRING_PROFILES_ACTIVE=prodPowerShell:
$ACR_NAME = if ($env:ACR_NAME) { $env:ACR_NAME } else { "<acr>" } # From Phase 3
$KEY_VAULT = if ($env:KEY_VAULT) { $env:KEY_VAULT } else { "<keyvault>" } # From Phase 5
$IDENTITY_ID = if ($env:IDENTITY_ID) { $env:IDENTITY_ID } else { throw "Set IDENTITY_ID from Phase 5" }
$SECRET_URI = az keyvault secret show --vault-name "$KEY_VAULT" --name db-password --query id -o tsv
az containerapp create --name spring-app --resource-group spring-rg --environment spring-env `
--image "${ACR_NAME}.azurecr.io/spring-app:v1.0" --target-port 8080 --ingress external `
--cpu 2.0 --memory 4Gi --min-replicas 2 --max-replicas 10 `
--user-assigned "$IDENTITY_ID" --registry-identity "$IDENTITY_ID" --registry-server "${ACR_NAME}.azurecr.io" `
--secrets db-password=keyvaultref:"${SECRET_URI}",identityref:"${IDENTITY_ID}" `
--env-vars SPRING_DATASOURCE_PASSWORD=secretref:db-password SPRING_PROFILES_ACTIVE=prodWith storage mount: Export the app configuration, add volumeMounts, and update:
Bash:
az containerapp show --name spring-app --resource-group spring-rg -o yaml > app.yaml
# Edit app.yaml: add volumeMounts under containers[0] and volumes at template level
az containerapp update --name spring-app --resource-group spring-rg --yaml app.yamlPowerShell:
az containerapp show --name spring-app --resource-group spring-rg -o yaml | Out-File -Encoding utf8 app.yaml
# Edit app.yaml: add volumeMounts under containers[0] and volumes at template level
az containerapp update --name spring-app --resource-group spring-rg --yaml app.yamlHealth Probes (recommended for Spring Boot apps): Export configuration, add probes, and update:
Bash:
az containerapp show --name spring-app --resource-group spring-rg -o yaml > app.yaml
# Edit app.yaml: add probes under containers[0]
# probes:
# - type: Startup
# httpGet:
# path: /actuator/health
# port: 8080
# failureThreshold: 30
# periodSeconds: 2
# - type: Liveness
# httpGet:
# path: /actuator/health/liveness
# port: 8080
# - type: Readiness
# httpGet:
# path: /actuator/health/readiness
# port: 8080
az containerapp update --name spring-app --resource-group spring-rg --yaml app.yamlPowerShell:
az containerapp show --name spring-app --resource-group spring-rg -o yaml | Out-File -Encoding utf8 app.yaml
# Edit app.yaml: add probes under containers[0]
# probes:
# - type: Startup
# httpGet:
# path: /actuator/health
# port: 8080
# failureThreshold: 30
# periodSeconds: 2
# - type: Liveness
# httpGet:
# path: /actuator/health/liveness
# port: 8080
# - type: Readiness
# httpGet:
# path: /actuator/health/readiness
# port: 8080
az containerapp update --name spring-app --resource-group spring-rg --yaml app.yamlPhase 7: Validation
Bash:
FQDN=$(az containerapp show --name spring-app --resource-group spring-rg --query properties.configuration.ingress.fqdn -o tsv)
echo "Application URL: https://${FQDN}"
curl "https://${FQDN}/actuator/health"
az containerapp logs show --name spring-app --resource-group spring-rg --tail 50PowerShell:
$FQDN = az containerapp show --name spring-app --resource-group spring-rg --query properties.configuration.ingress.fqdn -o tsv
Write-Host "Application URL: https://${FQDN}"
Invoke-WebRequest "https://${FQDN}/actuator/health"
az containerapp logs show --name spring-app --resource-group spring-rg --tail 50Phase 8: Post-Migration Optimization
Add Spring Cloud Config Server
Bash:
az containerapp env java-component config-server-for-spring create \
--environment spring-env --resource-group spring-rg --name config-server \
--min-replicas 1 --max-replicas 1 \
--configuration spring.cloud.config.server.git.uri=https://github.com/your-org/config-repo
az containerapp update --name spring-app --resource-group spring-rg --bind config-serverPowerShell:
az containerapp env java-component config-server-for-spring create `
--environment spring-env --resource-group spring-rg --name config-server `
--min-replicas 1 --max-replicas 1 `
--configuration spring.cloud.config.server.git.uri=https://github.com/your-org/config-repo
az containerapp update --name spring-app --resource-group spring-rg --bind config-serverAdd Eureka Service Registry
Bash:
az containerapp env java-component eureka-server-for-spring create \
--environment spring-env --resource-group spring-rg --name eureka-server \
--min-replicas 1 --max-replicas 1
az containerapp update --name spring-app --resource-group spring-rg --bind eureka-serverPowerShell:
az containerapp env java-component eureka-server-for-spring create `
--environment spring-env --resource-group spring-rg --name eureka-server `
--min-replicas 1 --max-replicas 1
az containerapp update --name spring-app --resource-group spring-rg --bind eureka-serverAdd dependency (pom.xml):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>Add Spring Cloud Gateway
Bash:
az containerapp create --name spring-gateway --resource-group spring-rg --environment spring-env \
--image "${ACR_NAME}.azurecr.io/gateway:v1.0" --target-port 8080 --ingress external \
--cpu 1.0 --memory 2Gi --min-replicas 1 --max-replicas 5 \
--bind eureka-server config-serverPowerShell:
az containerapp create --name spring-gateway --resource-group spring-rg --environment spring-env `
--image "${ACR_NAME}.azurecr.io/gateway:v1.0" --target-port 8080 --ingress external `
--cpu 1.0 --memory 2Gi --min-replicas 1 --max-replicas 5 `
--bind eureka-server config-serverAdd Spring Boot Admin
Bash:
az containerapp env java-component admin-for-spring create \
--environment spring-env --resource-group spring-rg --name admin-server \
--min-replicas 1 --max-replicas 1
az containerapp update --name spring-app --resource-group spring-rg --bind admin-serverPowerShell:
az containerapp env java-component admin-for-spring create `
--environment spring-env --resource-group spring-rg --name admin-server `
--min-replicas 1 --max-replicas 1
az containerapp update --name spring-app --resource-group spring-rg --bind admin-serverTroubleshooting
| Issue | Solution |
|---|---|
| Image pull fails | Verify ACR role: az role assignment list --assignee $PRINCIPAL_ID --scope $ACR_ID |
| App won't start | Check logs: az containerapp logs show --name spring-app -g spring-rg --tail 100 |
| Health check fails | Verify port 8080 matches server.port in application.properties |
| Secrets not accessible | Check Key Vault policy: az keyvault show --name $KEY_VAULT --query properties.accessPolicies |
| Storage mount fails | Verify storage configuration: az containerapp env storage list --name spring-env -g spring-rg |
| High memory usage | Reduce max heap: add --env-vars JAVA_OPTS="-Xmx2g" to container app |
CI/CD Integration
GitHub Actions example:
- name: Build and push to ACR
run: |
az acr build --registry ${{ secrets.ACR_NAME }} --image spring-app:${{ github.sha }} .
- name: Deploy to Container Apps
run: |
az containerapp update --name spring-app -g spring-rg --image ${{ secrets.ACR_NAME }}.azurecr.io/spring-app:${{ github.sha }}Azure Pipelines example:
- task: AzureCLI@2
inputs:
azureSubscription: 'AzureConnection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az acr build --registry $(ACR_NAME) --image spring-app:$(Build.BuildId) .
az containerapp update --name spring-app -g spring-rg --image $(ACR_NAME).azurecr.io/spring-app:$(Build.BuildId)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