Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
GitHub Copilot for Azure plugin providing Azure service management and development assistance inside Claude Code and IDEs.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/app-service/code-migration.md
1# Code Migration Phase23Migrate source platform web application code to Azure App Service.45## Prerequisites67- Assessment report completed8- Best practices loaded via `mcp_azure_mcp_get_azure_bestpractices` tool910## Rules1112- Create all output in `<source-folder>-azure/` — never modify the source directory13- Use latest GA runtime stack for the target language14- Prefer managed identity over connection strings or API keys15- Use App Configuration for shared settings, Key Vault for secrets16- Always configure health check endpoint1718## Steps19201. **Load Best Practices** — Use `mcp_azure_mcp_get_azure_bestpractices` tool for App Service guidance212. **Create Project Structure** — Set up the project inside the output directory223. **Migrate Application Code** — Adapt source code for App Service runtime234. **Update Dependencies** — Replace platform-specific SDKs with Azure equivalents245. **Configure Startup** — Set startup command or create Dockerfile256. **Migrate Environment Variables** — Map to App Settings / App Configuration / Key Vault267. **Configure Database Connections** — Switch to Azure database services with managed identity278. **Add Health Check** — Implement `/healthz` endpoint for App Service health monitoring289. **Set Up Logging** — Integrate Application Insights SDK2930## Key Configuration Files3132### Startup Command3334For non-Docker deployments, configure the startup command in App Service:3536| Runtime | Default Start | Custom Start |37|---------|--------------|--------------|38| Node.js | `npm start` | Set in Configuration → General Settings |39| Python | `gunicorn app:app` | `gunicorn --bind=0.0.0.0 --timeout 600 app:app` |40| Java | Auto-detected | `-Dserver.port=80` |41| .NET | Auto-detected | `dotnet myapp.dll` |4243### Dockerfile (When Needed)4445Use a Dockerfile when the app requires custom system dependencies or multi-process setups:4647```dockerfile48FROM node:20-slim49WORKDIR /app50COPY package*.json ./51RUN npm ci --omit=dev52COPY . .53EXPOSE 808054CMD ["node", "server.js"]55```5657> ⚠️ **Port**: App Service injects `PORT` env var. Always bind to `process.env.PORT || 8080`.5859### Application Insights Integration6061```javascript62// Add as FIRST import in entry point63const appInsights = require('applicationinsights');64appInsights.setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)65.setAutoCollectRequests(true)66.setAutoCollectExceptions(true)67.start();68```6970## Database Migration Patterns7172| Source | Azure Target | Connection Pattern |73|--------|--------------|--------------------|74| RDS PostgreSQL | Azure Database for PostgreSQL Flexible Server | Managed identity + `@azure/identity` |75| RDS MySQL | Azure Database for MySQL Flexible Server | Managed identity + `@azure/identity` |76| RDS SQL Server | Azure SQL Database | Managed identity + `@azure/identity` |77| Heroku Postgres | Azure Database for PostgreSQL Flexible Server | Managed identity |78| Cloud SQL | Azure SQL / PostgreSQL Flexible Server | Managed identity |79| MongoDB Atlas | Azure Cosmos DB for MongoDB | Connection string → managed identity |8081### Managed Identity Database Connection (Node.js)8283```javascript84const { DefaultAzureCredential } = require('@azure/identity');85const { Client } = require('pg');8687async function main() {88const credential = new DefaultAzureCredential({89managedIdentityClientId: process.env.AZURE_CLIENT_ID90});91const token = await credential.getToken('https://ossrdbms-aad.database.windows.net/.default');9293const client = new Client({94host: process.env.PGHOST,95database: process.env.PGDATABASE,96user: process.env.PGUSER,97password: token.token,98ssl: { rejectUnauthorized: true },99port: 5432100});101await client.connect();102// ... use client103}104105main().catch(console.error);106```107108> ⚠️ Wrap in `async function main()` — top-level `await` is not supported in CommonJS or many Node.js entrypoints. For ESM, top-level await works only with `"type": "module"` in `package.json`.109110## Static Assets & CDN111112If the source app serves static assets, consider:1131. **Azure Blob Storage + CDN** for static files1142. **Azure Front Door** for global distribution1153. **App Service built-in static file serving** for simple cases116117## Background Workers118119| Source Pattern | Azure Equivalent |120|---------------|------------------|121| Heroku Worker dyno | WebJobs (continuous) or separate Container App |122| Beanstalk Worker tier | WebJobs or Azure Functions |123| App Engine service (worker) | WebJobs or Azure Functions |124| Cron jobs | WebJobs (triggered) or Azure Functions Timer trigger |125126## Handoff to azure-prepare127128After code migration is complete:1291301. Update `migration-status.md` — mark Code Migration as ✅ Complete1312. Invoke **azure-prepare** — pass the assessment report context so it can:132- Use the service mapping as requirements input133- Generate IaC (Bicep/Terraform) for the mapped Azure services134- Create `azure.yaml` and `.azure/preparation-manifest.md`135- Apply security hardening1363. azure-prepare will then chain to **azure-validate** → **azure-deploy**137