All skills
microsoft avatar

/azure-app-onboard-prereq

@ae5e585
by microsoftmicrosoft/skills3.1k stars
351

Assess whether source code is ready to deploy to Azure — the check BEFORE infrastructure work. Evaluates build health, app completeness, dependencies and local services, stack compatibility, and deployment feasibility. Answers questions about what your app needs before it can be deployed — frameworks, dependencies, and configuration. Checks whether dependencies are compatible and identifies deployment blockers and unsupported frameworks. WHEN: "evaluate my repo", "is my app ready to deploy", "what does my app need to deploy", "what do I need before deploying", "does my app need", "can I ship this to Azure", "scan my repo for issues", "is this app deployable", "check if my app is ready for Azure", "do I need a Dockerfile", "what's blocking my deployment", "are there any blockers", "are my dependencies compatible", "does Azure support my framework", "what needs to change before deploying", "check my app configuration".

Use this Skill: https://skilld.dev/gh/microsoft/skills/azure-app-onboard-prereq

This session only. Nothing lands on disk.

referencesdependency-compatibility.md

≈2.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Dependency compatibility checks for Azure. Part of the deployability check.

EOL / Unsupported Runtimes

Verdict Condition
🔶 Major Migration .NET Framework 4.x, ASP.NET Core 2.1, Python 2.x
❌ FAIL or 🔶 Node.js < 18, Java < 11 — config-only upgrade → ❌ FAIL (fixable), API changes needed → 🔶

Quick test: ONE config value change, no import changes? → ❌ FAIL. Otherwise → 🔶.

Ecosystem-era check (Python): ALL pinned deps pre-2018, no Python 3.10+ wheels → ❌ FAIL. Signals: flask_script, werkzeug<1.0, itsdangerous<1.0, imports from werkzeug.contrib.* / flask.ext.*.

EOL / Unmaintained Frameworks

Verdict Condition
🔶 Major Migration Flask < 2.0, Django < 3.2, Express < 4.0, Rails < 6.0, Spring Boot < 2.7
⚠️ WARN React < 16, Angular < 14, Next.js < 13

Archived / Abandoned Repositories

Signal Verdict
archived: true + EOL stack 🔶 Major Migration
archived: true (current runtime) ⚠️ WARN
README "deprecated"/"unmaintained" + EOL 🔶 Major Migration
README "deprecated"/"unmaintained" (current) ⚠️ WARN

Remediation scope: Fixing all blockers requires major upgrade OR >5 files → 🔶 Major Migration.

Intentionally Vulnerable Applications

Detect via code structure first, metadata second. These apps are designed to be exploited — vulnerability IS the product.

Code signals (check first):

  • Directory vulnerabilities/ with subdirs like sqli/, xss/, csrf/, fi/ (file inclusion)
  • Security-level config toggling vulnerability severity (default_security_level, security.level, difficulty)
  • Source files with intentionally unsanitized $_GET/$_POST/$_REQUEST passed to SQL queries, shell commands (exec, shell_exec, system ), or eval/include -- that are systematic across 3+ files (not a single bug)
  • hackable//exploit/ directories, or files with names like command_injection.php, brute_force.php

Metadata signals (secondary check):

  • Project/package description or repo About containing: "deliberately vulnerable", "intentionally insecure", "vulnerable by design", "security training", "penetration testing", "do not deploy to production"
  • README/License warning against internet-facing deployment

Verdict: ≥2 code signals OR 1 code + 1 metadata → 🛑 HALT. Single metadata only → ⚠️ WARN (could be a disclosure).

⛔ 🛑 HALT is a verdict, not an exit. On 🛑 HALT your NEXT action MUST be the Step-4 write — persist all 3 artifacts (prereq-output.json, context.json, readiness-report.md) with overallHealth: "blocked" via the create tool, then read them back, BEFORE printing any halt summary to the user. A halt message with no prereq-output.json on disk is a failure — the deterministic blocked verdict must be persisted first, because the halt message can end the turn.

Non-Azure Cloud SDK Dependencies

Functional cloud SDK deps → 🔶 blockers; classification and observability carve-out in cloud-sdk-migration.md. The redirect gate (SKILL.md Step 2) and the deploy-blocking stop (SKILL.md Step 8 Row 2) own all routing — no routeToSkill decision happens here.

Platform-Specific Dependencies

Dependency Type Verdict
Native OS binaries (.so, .dll) ⚠️ WARN
Native Node.js addons on free/low-tier SKUs ⚠️ WARN
GPU-required libraries (CUDA) ⚠️ WARN
Local file system writes, file-based DBs ⚠️ WARN — ephemeral on PaaS
BuildKit Dockerfile syntax (--mount, # syntax=) ⚠️ WARN W-BUILDKIT — set buildRequirements.hasBuildKitSyntax: true. ACR az acr build does NOT support BuildKit — scaffold must generate Dockerfile.azure. fix: "Generate ACR-compatible Dockerfile.azure" fixPhase: scaffold
Jib container build (no Dockerfile) ⚠️ WARN — note Jib path for scaffold
Redis client without TLS config ⚠️ WARN W-REDIS-TLS — fix: "Add TLS config" fixPhase: prereq. Config key registration: if the app uses a config library that requires keys to be pre-registered before env var override (Go/Viper Unmarshal(), Spring @ConfigurationProperties), the config file must also declare the TLS key (e.g., add tlsEnabled: false to YAML) — otherwise the env var is silently ignored. Detection: grep for viper.Unmarshal, mapstructure, @ConfigurationProperties.
PostgreSQL client with SSL disabled ⚠️ WARN W-PG-SSL — fix: "Set SSL mode env var" fixPhase: scaffold
MySQL client without TLS config ⚠️ WARN W-MYSQL-SSL — fix: "Enable client TLS for Azure MySQL" fixPhase: prereq. Most MySQL drivers/ORMs need an in-code SSL option (no SSL env var like Postgres has), so this is a client-config change → prereq remediation batch (like W-REDIS-TLS), not IaC-only scaffold. Detection: MySQL in the plan (mysql:* in compose, or a MySQL driver/ORM — e.g. mysql2, sequelize dialect mysql, typeorm, prisma, knex) with no SSL/TLS option in the client config.
Go Viper without env key replacer ⚠️ WARN W-VIPER-ENV — fix: "Add SetEnvKeyReplacer call" fixPhase: prereq
Licensed/proprietary SDKs ⚠️ WARN

Hardcoded Localhost URLs

Pattern Verdict ID fixPhase
localhost, 127.0.0.1, 0.0.0.0 in API base URLs, CORS origins, webhook URLs, service discovery ⚠️ WARN W-LOCALHOST-URL scaffold

Exclude: database connection strings, dev-only files, test files.

Dockerfile Analysis

Pattern Verdict ID fixPhase
CMD.*uv run / ENTRYPOINT.*uv run ⚠️ WARN W-UV-RUN prereq
CMD.*poetry run / ENTRYPOINT.*poetry run ⚠️ WARN W-POETRY-RUN prereq

Also check docker-compose.yml command: overrides.

Native Module Detection

Static lockfile analysis only.

Language Signal Where
Node.js "node-gyp" in lockfile package-lock.json, yarn.lock, pnpm-lock.yaml
Python numpy, pandas, grpcio, Pillow, bcrypt, psycopg2 (not -binary), cryptography, lxml, scipy, scikit-learn requirements.txt, pyproject.toml
.NET [DllImport], NativeLibrary.Load .cs files
Go import "C" (cgo) .go files
PHP ext-* requirements composer.json

⛔ Lockfile grep is the ONLY valid evidence. Do NOT set hasNativeModules from package name alone. prebuild-install without node-gyp = prebuilt → hasNativeModules: false. Key: bcrypt ✅ native, bcryptjs ❌ JS. psycopg2 ✅, psycopg2-binary ❌. sharp v0.33+ ❌ prebuilt. canvas ✅ always. No lockfile → "unknown", ⚠️ WARN.

When hasNativeModules: true: f1Viable: false, f1BlockReason: "native modules ({signal})".

F1 Viability — Beyond Native Modules

Condition f1BlockReason
Large dep tree (Python >10, Node lockfile >500KB, .NET >20 NuGet) "large dependency tree"
Build-time compilation (tsconfig.json + "build" script) "build-time compilation"
WSGI/ASGI server (gunicorn/uvicorn/daphne) "WSGI/ASGI server"
🔶 Major Migration (>5 files) "major migration"

When f1Viable: false: prepare selects B1 (~$13/mo) minimum.

First-Run Initialization

Detect init steps needed before first HTTP request — run automatically in dev but cause 500s on Azure.

Framework Signal Init command
Flask-Migrate/Alembic flask_migrate/alembic + migrations/ flask db upgrade
Django django + manage.py + */migrations/ python manage.py migrate
Prisma @prisma/client + prisma/schema.prisma npx prisma migrate deploy
TypeORM typeorm + migrations//ormconfig npx typeorm migration:run
Sequelize sequelize + migrations/ npx sequelize-cli db:migrate
EF Core EntityFrameworkCore.Tools in csproj dotnet ef database update

Seed/bootstrap: Flask @app.cli.command('deploy') → flask deploy. Django fixtures/ → manage.py loaddata. Seed commands: required: false.

Migration framework + migrations/ dir → ⚠️ WARN, write to prereq-output.json.initCommands[] (schema in prereq-schemas.ts). ORM without migrations/ dir → ✅ PASS. Prepare prepends required initCommands to deployStrategy.startupCommand; scaffold encodes in appCommandLine. Migrations are idempotent — safe on every cold start.

Database & Storage

Found Assessment
File-based DB (SQLite, LevelDB, DuckDB) ⚠️ WARN — ephemeral on PaaS. Deploy as-is, suggest managed DB in postDeployRecommendations[]
Local file storage Needs Azure Blob Storage
In-memory cache only Consider Redis
Managed DB connection string Ready — update connection

Source: SKILL.md on GitHub

1 warning1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    This skill is an Azure deployment readiness evaluator authored by Microsoft. It performs static analysis of repositories to identify deployment blockers and can offer to fix them or generate starter code. While the skill has capabilities to execute build commands and modify files, these actions are strictly protected by user consent gates and are limited to the skill's intended purpose of onboarding applications to Azure.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: MEDIUM · 1 issue

Signed by skilld at ae5e585. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last month
metadata
{
  "author": "Microsoft",
  "version": "1.2.2"
}

README badge

README badge for microsoft/skills/azure-app-onboard-prereq