Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e574663
Add azure-migrate skill with Lambda-to-Functions migration learnings
MadhuraBharadwaj-MSFT Feb 26, 2026
6917c5e
Remove proposed-updates folder from azure-migrate skill
MadhuraBharadwaj-MSFT Feb 26, 2026
dd3ddec
Remove Risks & Mitigations section from assessment template
MadhuraBharadwaj-MSFT Feb 26, 2026
1250232
in progress
MadhuraBharadwaj-MSFT Feb 26, 2026
f419e66
Merge remote-tracking branch 'upstream/main'
MadhuraBharadwaj-MSFT Feb 26, 2026
4c1695f
fix: improve azure-migrate skill routing and description
MadhuraBharadwaj-MSFT Feb 27, 2026
b59a816
fix: narrow azure-prepare exception to Lambda migration, minor azure-…
MadhuraBharadwaj-MSFT Feb 27, 2026
e4db01d
chore: remove license and metadata fields from azure-migrate frontmatter
MadhuraBharadwaj-MSFT Feb 27, 2026
595d0fd
refactor: reorganize into services/functions, generalize SKILL.md, de…
MadhuraBharadwaj-MSFT Feb 27, 2026
87a5767
feat: output directory convention (<aws-folder>-azure/) and explicit …
MadhuraBharadwaj-MSFT Feb 27, 2026
fe1b6e1
merge: resolve upstream/main conflicts — keep migrate routing, add az…
MadhuraBharadwaj-MSFT Feb 27, 2026
e0f9123
rename: azure-migrate → azure-cloud-migrate
MadhuraBharadwaj-MSFT Feb 27, 2026
69cc808
Added snapshot trigger test
MadhuraBharadwaj-MSFT Feb 27, 2026
5410afd
merge: upstream/main — routing fix, frontmatter validator, curl HEAD fix
MadhuraBharadwaj-MSFT Feb 27, 2026
491a5eb
sensei: improve azure-cloud-migrate frontmatter
MadhuraBharadwaj-MSFT Feb 27, 2026
0592fe3
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
fce6d81
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
d9ce225
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
973adab
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
14d796a
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
08d2dbf
Revise function.json creation rules for various runtimes
MadhuraBharadwaj-MSFT Feb 27, 2026
a85e356
Fix typo in azure-cloud-migrate skill description
MadhuraBharadwaj-MSFT Feb 27, 2026
5876284
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
7390b36
Change AzureWebJobsStorage variable to blobServiceUri
MadhuraBharadwaj-MSFT Feb 27, 2026
27dbd27
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
936bfd7
Update SKILL.md
MadhuraBharadwaj-MSFT Feb 27, 2026
a60d7de
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
4e60575
Apply suggestion from @Copilot
MadhuraBharadwaj-MSFT Feb 27, 2026
c05f9c8
updated trigger test, snapshot and comments in integration tests
saikoumudi Feb 28, 2026
d36c8d0
rearrange azure-cloud-migrate in skills.json
saikoumudi Feb 28, 2026
78e1af5
Update tests/azure-cloud-migrate/integration.test.ts
saikoumudi Feb 28, 2026
dc4bcc6
Revert "Update tests/azure-cloud-migrate/integration.test.ts"
saikoumudi Feb 28, 2026
d783ece
updated to use mcp_azure_mcp_documentation and mcp_azure_mcp_get_best…
saikoumudi Feb 28, 2026
9537b6c
update prepare snapshot since skill.md is updated
saikoumudi Feb 28, 2026
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
39 changes: 39 additions & 0 deletions plugin/skills/azure-cloud-migrate/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
name: azure-cloud-migrate
description: "Assess and migrate cross-cloud workloads to Azure. Generates assessment reports and converts code from AWS, GCP, or other providers to Azure services. WHEN: \"migrate Lambda to Azure Functions\", \"migrate AWS to Azure\", \"Lambda migration assessment\", \"convert s AWS erverless to Azure\", \"migration readiness report\", \"migrate from AWS\", \"migrate from GCP\", \"cross-cloud migration\"."
---

# 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_bestpractices` and `mcp_azure_mcp_documentation` MCP tools
5. Use the latest supported runtime for the target service
6. Destructive actions require `ask_user` — [global-rules](references/services/functions/global-rules.md)

## Migration Scenarios

| Source | Target | Reference |
|--------|--------|-----------|
| AWS Lambda | Azure Functions | [lambda-to-functions.md](references/services/functions/lambda-to-functions.md) |

> No matching scenario? Use `mcp_azure_mcp_documentation` and `mcp_azure_mcp_get_bestpractices` tools.

## Output Directory

All output goes to `<source-folder>-azure/` at workspace root. Never modify the source directory.

## Steps

1. **Create** `<source-folder>-azure/` at workspace root
2. **Assess** — Analyze source, map services, generate report → [assessment.md](references/services/functions/assessment.md)
3. **Migrate** — Convert code using target programming model → [code-migration.md](references/services/functions/code-migration.md)
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](references/workflow-details.md).
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Assessment Phase

Generate a migration assessment report before any code changes.

## Prerequisites

- Workspace contains AWS Lambda functions, SAM templates, or CloudFormation templates
- Prompt user to upload relevant files if not present

## Assessment Steps

1. **Identify Functions** — List all Lambda functions with runtimes, triggers, and dependencies
2. **Map AWS Services** — Map AWS services to Azure equivalents (see [lambda-to-functions.md](lambda-to-functions.md))
3. **Map Properties** — Map Lambda properties to Azure Functions properties
4. **Check Dependencies** — List 3rd-party libraries and verify Azure compatibility
5. **Analyze Code** — Check language support and runtime differences
6. **Map Triggers** — Identify equivalent Azure Functions triggers
7. **Map Deployment** — Identify equivalent Azure deployment strategies (CLI, Bicep, azd)
8. **Review CI/CD** — Check pipeline compatibility with Azure DevOps or GitHub Actions
9. **Map Monitoring** — Map CloudWatch → Application Insights / Azure Monitor

## Code Preview

During assessment, show a **sneak peek** of what the migrated Azure Functions code will look like for each function. Use bindings and triggers (not SDKs) in all previews, following Azure Functions best practices. **Always use the newest generally available (GA) language runtime listed in the Azure Functions supported languages documentation** in previews (for example, the latest Node.js LTS or newest Python GA version). This helps the user understand the migration scope before committing to code migration.

> ⚠️ **Binding-first rule**: Code previews MUST use `input.storageBlob()`, `output.storageBlob()`, `app.storageQueue()`, etc. instead of `BlobServiceClient`, `QueueClient`, or other SDK clients. Only use SDK for services that have no binding equivalent.

## Architecture Diagrams

Generate two diagrams:
1. **Current State** — AWS Lambda architecture with triggers and integrations
2. **Target State** — Azure Functions architecture showing equivalent structure

## Assessment Report Format

> ⚠️ **MANDATORY**: Use these exact section headings in every assessment report. Do NOT rename, reorder, or omit sections.

The report MUST be saved as `migration-assessment-report.md` inside the output directory (`<aws-folder>-azure/`).

```markdown
# Migration Assessment Report

## 1. Executive Summary

| Property | Value |
|----------|-------|
| **Total Functions** | <count> |
| **Source Platform** | AWS Lambda |
| **Source Runtime** | <runtime and version> |
| **Target Platform** | Azure Functions |
| **Target Runtime** | <runtime and version> |
| **Migration Readiness** | <High / Medium / Low> |
| **Estimated Effort** | <Low / Medium / High> |
| **Assessment Date** | <date> |

## 2. Functions Inventory

| # | Function Name | Runtime | Trigger Type | Memory (MB) | Timeout (s) | Description |
|---|--------------|---------|-------------- |-------------|-------------|-------------|
| 1 | | | | | | |

## 3. Service Mapping

| AWS Service | Azure Equivalent | Migration Complexity | Notes |
|-------------|------------------|----------------------|-------|
| Lambda | Azure Functions | | |
| API Gateway | Azure Functions HTTP Trigger / APIM | | |
| S3 | Azure Blob Storage | | |
| DynamoDB | Cosmos DB | | |
| SQS | Service Bus / Storage Queue | | |
| SNS | Event Grid | | |
| CloudWatch | Application Insights / Azure Monitor | | |
| IAM Roles | Managed Identity + RBAC | | |
| CloudFormation / SAM | Bicep / ARM Templates | | |

## 4. Trigger & Binding Mapping

| # | Function Name | AWS Trigger | Azure Trigger | AWS Inputs/Outputs | Azure Bindings | Notes |
|---|--------------|-------------|---------------|--------------------| ---------------|-------|
| 1 | | | | | | |

## 5. Dependencies Analysis

| # | Package/Library | Version | AWS-Specific? | Azure Equivalent | Compatible? | Notes |
|---|----------------|---------|---------------|------------------|-------------|-------|
| 1 | | | | | | |

## 6. Environment Variables & Configuration

| # | AWS Variable | Purpose | Azure Equivalent | Auth Method | Notes |
|---|-------------|---------|------------------|-------------|-------|
| 1 | | | | Managed Identity / App Setting | |

## 7. Architecture Diagrams

### 7a. Current State (AWS)

<!-- Mermaid or ASCII diagram of AWS Lambda architecture -->

### 7b. Target State (Azure)

<!-- Mermaid or ASCII diagram of Azure Functions architecture -->

## 8. IAM & Security Mapping

| AWS IAM Role/Policy | Azure RBAC Role | Scope | Notes |
|---------------------|-----------------|-------|-------|
| | | | |

## 9. Monitoring & Observability Mapping

| AWS Service | Azure Equivalent | Migration Notes |
|-------------|------------------|-----------------|
| CloudWatch Logs | Application Insights | |
| CloudWatch Metrics | Azure Monitor Metrics | |
| CloudWatch Alarms | Azure Monitor Alerts | |
| X-Ray | Application Insights (distributed tracing) | |

## 10. CI/CD & Deployment Mapping

| AWS Tool | Azure Equivalent | Notes |
|----------|------------------|-------|
| SAM CLI | Azure Functions Core Tools / azd | |
| CloudFormation | Bicep / ARM Templates | |
| CodePipeline | Azure DevOps Pipelines / GitHub Actions | |
| CodeBuild | Azure DevOps Build / GitHub Actions | |

## 11. Project Structure Comparison

| AWS Lambda Structure | Azure Functions Structure |
|---------------------|--------------------------|
| `template.yaml` (SAM) | `host.json` |
| `handler.js / handler.py` | `src/app.js` / `src/function_app.py` |
| `requirements.txt` / `package.json` | `requirements.txt` / `package.json` |
| Per-function directories (optional) | Single entry point (v4 JS / v2 Python) |
| `event` object | Trigger-specific parameter |
| `context` object | `InvocationContext` |

## 12. Recommendations

1. **Runtime**: <recommended Azure Functions runtime and version>
2. **Hosting Plan**: <Flex Consumption / Premium>
3. **IaC Strategy**: <Bicep with azd / Terraform / ARM>
4. **Auth Strategy**: <Managed Identity for all service-to-service>
5. **Monitoring**: <Application Insights + Azure Monitor>

## 13. Next Steps

- [ ] Review and approve this assessment report
- [ ] Proceed to code migration (azure-cloud-migrate Phase 2)
- [ ] Hand off to azure-prepare for IaC generation
```

> 💡 **Tip:** Use `mcp_azure_mcp_get_bestpractices` tool to learn Azure Functions project structure best practices for the comparison.
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Code Migration Phase

Migrate AWS Lambda function code to Azure Functions.

## Prerequisites

- Assessment report completed
- Azure Functions extension installed in VS Code
- Best practices loaded via `mcp_azure_mcp_get_bestpractices` tool

## Rules

- If runtime is Python or Node.js: **do NOT create function.json files**
- If runtime is .NET (in-process or isolated) or Java: **do NOT hand-author function.json** — bindings metadata is generated from attributes/annotations at build time
- Use extension bundle version `[4.*, 5.0.0)` in host.json
- Use latest programming model (v4 for JavaScript, v2 for Python)
- **Always use bindings and triggers instead of SDKs** — For blob read/write, use `input.storageBlob()` / `output.storageBlob()` with `extraInputs`/`extraOutputs`. For queues, use `app.storageQueue()` or `app.serviceBusQueue()`. Only use SDK when there is no equivalent binding (e.g., Azure AI, custom HTTP calls)
- **Always use the latest supported language runtime** — Consult [supported languages](https://learn.microsoft.com/en-us/azure/azure-functions/supported-languages) and select the newest GA version. Do NOT default to an older LTS version when a newer version is available on Azure Functions.

## Steps

1. **Install Azure Functions Extension** — Ensure VS Code extension is installed
2. **Load Best Practices** — Use `mcp_azure_mcp_get_bestpractices` tool for code generation guidance
3. **Create Project Structure** — Set up the Azure Functions project inside the output directory (`<aws-folder>-azure/`). Do NOT create files inside the original AWS directory
4. **Migrate Functions** — Convert each Lambda function to Azure Functions equivalent
5. **Update Dependencies** — Replace AWS SDKs with Azure SDKs in package.json / requirements.txt
6. **Configure Bindings** — Set up triggers and bindings inline (v4 JS / v2 Python)
7. **Configure Environment** — Map Lambda env vars to Azure Functions app settings
8. **Add Error Handling** — Ensure proper error handling in all functions

## Key Configuration Files

### host.json

```json
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"queues": {
"maxPollingInterval": "00:00:02",
"visibilityTimeout": "00:00:30",
"batchSize": 1,
"maxDequeueCount": 5
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
}
}
```

## Critical Infrastructure Dependencies

### Blob Trigger with EventGrid Source — Additional Requirements

When migrating S3 event triggers to Azure blob triggers with `source: 'EventGrid'`, the following infrastructure must be configured **at the IaC level** (not code level). Failure to set these up results in silent trigger failures.

| Requirement | Why | Consequence of Missing |
|------------|-----|----------------------|
| **Queue endpoint** (`AzureWebJobsStorage__queueServiceUri`) | Blob extension uses queues internally for poison-message tracking with EventGrid source | Function fails to index: "Unable to find matching constructor...QueueServiceClient" |
| **Always-ready instances** (Flex Consumption only) | Blob trigger group must be running to register the Event Grid webhook | Trigger group never starts → webhook never registered → events never delivered |
| **Event Grid subscription via Bicep/ARM** | CLI-based webhook validation handshake times out on Flex Consumption | Use `listKeys()` in Bicep to obtain the `blobs_extension` system key at deployment time |
| **Storage Queue Data Contributor** RBAC | Identity-based queue access for poison messages | 403 errors during blob trigger indexing |

See [lambda-to-functions.md](lambda-to-functions.md#flex-consumption--blob-trigger-with-eventgrid-source) for Bicep patterns.

### UAMI Credential Pattern

When using User Assigned Managed Identity (UAMI), `DefaultAzureCredential()` without arguments tries System Assigned first and fails. Always pass the client ID:

```javascript
const credential = new DefaultAzureCredential({
managedIdentityClientId: process.env.AZURE_CLIENT_ID
});
```

Add `AZURE_CLIENT_ID` as an app setting in Bicep pointing to the UAMI client ID.

### azd init Workaround for Non-Empty Directories

`azd init --template <template>` refuses to run in a non-empty directory. Use a temp-directory approach:

1. `azd init --template <template>` in an empty temp directory
2. Copy IaC files (`infra/`, `azure.yaml`, etc.) into the project root
3. Clean up the temp directory

### package.json (JavaScript)

```json
{
"dependencies": {
"@azure/functions": "^4.0.0",
"@azure/identity": "<latest>"
},
"devDependencies": {
"@azure/functions-core-tools": "^4",
"jest": "<latest>"
}
}
```

## Runtime-Specific Trigger & Binding Patterns

Load the appropriate runtime reference for the target language:

| Runtime | Reference |
|---------|----------|
| JavaScript (Node.js v4) | [runtimes/javascript.md](runtimes/javascript.md) |
| TypeScript (v4) | [runtimes/typescript.md](runtimes/typescript.md) |
| Python (v2) | [runtimes/python.md](runtimes/python.md) |
| C# (Isolated Worker) | [runtimes/csharp.md](runtimes/csharp.md) |
| Java | [runtimes/java.md](runtimes/java.md) |
| PowerShell | [runtimes/powershell.md](runtimes/powershell.md) |

## Scenario-Specific Guidance

See [lambda-to-functions.md](lambda-to-functions.md) for detailed trigger mapping, code patterns, and examples.

## Handoff to azure-prepare

After code migration is complete:

1. Update `migration-status.md` — mark Code Migration as ✅ Complete
2. Invoke **azure-prepare** — pass the assessment report context so it can:
- Use the service mapping as requirements input (skips manual gather-requirements)
- Generate IaC (Bicep/Terraform) for the mapped Azure services
- Create `azure.yaml` and `.azure/preparation-manifest.md`
- Apply security hardening
3. azure-prepare will then chain to **azure-validate** → **azure-deploy**
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Global Rules

These rules apply to ALL phases of the migration skill.

## Destructive Action Policy

⛔ **NEVER** perform destructive actions without explicit user confirmation via `ask_user`:
- Deleting files or directories
- Overwriting existing code
- Deploying to production environments
- Modifying existing Azure resources
- Removing AWS resources

## User Confirmation Required

Always use `ask_user` before:
- Selecting Azure subscription
- Selecting Azure region/location
- Deploying infrastructure
- Making breaking changes to existing code

## Best Practices

- Always use `mcp_azure_mcp_get_bestpractices` tool before generating Azure code
- Prefer managed identity over connection strings
- **Always use the latest supported language runtime** — check [supported languages](https://learn.microsoft.com/en-us/azure/azure-functions/supported-languages) for the newest GA version. Never default to older versions
- **Always prefer bindings over SDKs** — use `input.storageBlob()`, `output.storageBlob()`, `app.storageQueue()`, etc. instead of `BlobServiceClient`, `QueueClient`, or other SDK clients. Only use SDK when no binding exists for the service
- Follow Azure naming conventions
- Use Flex Consumption hosting plan for new Functions

## Identity-First Authentication (Zero API Keys)

> Enterprise subscriptions commonly enforce policies that block local auth. Always design for identity-based access from the start.

- **Storage accounts**: Set `allowSharedKeyAccess: false`. Use identity-based connections with `AzureWebJobsStorage__credential`, `__clientId`, and service-specific URIs (`__blobServiceUri`, `__queueServiceUri`, etc.)
- **Cognitive Services**: Set `disableLocalAuth: true`. Use UAMI + RBAC role (e.g., Cognitive Services User) instead of API keys
- **Application Insights**: Set `disableLocalAuth: true`. Use `APPLICATIONINSIGHTS_AUTHENTICATION_STRING` with `ClientId=<uamiClientId>;Authorization=AAD`
- **DefaultAzureCredential with UAMI**: When using User Assigned Managed Identity, always pass `managedIdentityClientId` explicitly:
```javascript
const credential = new DefaultAzureCredential({
managedIdentityClientId: process.env.AZURE_CLIENT_ID
});
```
Without this, `DefaultAzureCredential` tries SystemAssigned first and fails. Add `AZURE_CLIENT_ID` as an app setting mapped to the UAMI client ID.

## Flex Consumption Specifics

- **Always-ready for non-HTTP triggers**: Blob trigger groups on Flex Consumption require `alwaysReady: [{ name: "blob", instanceCount: 1 }]` to bootstrap the trigger listener. Without it, the trigger group never starts and Event Grid subscriptions are never auto-created (chicken-and-egg problem)
- **Blob trigger with EventGrid source requires queue endpoint**: The blob extension internally uses queues for poison-message tracking. Must include `AzureWebJobsStorage__queueServiceUri` even when using blob trigger (not queue trigger)
- **Event Grid subscriptions via Bicep/ARM only**: Do NOT create Event Grid event subscriptions via CLI — webhook validation fails on Flex Consumption with "response code Unknown". Deploy as Bicep resources using `listKeys()` to resolve the `blobs_extension` system key at deployment time
- **azd init on non-empty directories**: `azd init --template` refuses non-empty directories. Use temp directory approach: init in temp, copy template infrastructure files back
Loading
Loading