Generated banner for Python Appservice Deploy
Generated logo for Python Appservice Deploy

Python Appservice Deploy

MicrosoftOfficialCreated by Microsoft

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

From the author

Deploy Python (Flask/Django/FastAPI) code to Azure App Service Linux. WHEN: "Flask App Service", "Django App Service", "FastAPI App Service", "deploy Python to App Service". DO NOT USE FOR: Container Apps, Functions, non-Python, Terraform/Bicep/IaC, full infra — use azure-prepare.
— the description by Microsoft

AutoGineer summary

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

This skill provides a structured, idempotent workflow for deploying Python applications (Flask, Django, FastAPI) to Azure App Service on Linux. It handles the creation of necessary Azure resources—including Resource Groups, App Service Plans (P0v3), and Web Apps—while enforcing best practices like server-side builds and proper startup configuration. The process includes automated normalization of shell scripts to ensure compatibility and provides a reliable path for both standard CLI-based deployments and those utilizing Azure Developer CLI (azd) configurations.

What it does

  • Automatically creates or validates Azure Resource Groups, App Service Plans, and Web Apps.
  • Configures server-side builds via SCM_DO_BUILD_DURING_DEPLOYMENT.
  • Normalizes Linux shell scripts to prevent line-ending issues during deployment.
  • Sets appropriate startup commands for FastAPI applications.
  • Packages the application code into a clean ZIP archive, excluding unnecessary files.
  • Supports both standard Azure CLI and azd-based deployment workflows.

When to use it

  • When you need to deploy a Python Flask, Django, or FastAPI application to Azure App Service Linux.
  • When you want to automate the provisioning of the required Azure infrastructure alongside the code deployment.
  • When you need a repeatable, error-checked deployment process for Python web apps.
  • When you are working with a standard Python project structure and require a reliable deployment pipeline.

Advantages

  • Reduces manual configuration by deriving sensible defaults for resource names and regions.
  • Ensures cross-platform compatibility by normalizing line endings in scripts.
  • Prevents common deployment failures through pre-packaging validation.
  • Provides a consistent, idempotent approach to resource creation.
  • Integrates seamlessly with existing Azure CLI and azd workflows.

Usage examples

“Deploy my Flask app to Azure App Service.”
The agent will prompt for an app name, then automatically create the necessary Resource Group, P0v3 Linux App Service Plan, and Web App, finally deploying the code.
“Deploy my FastAPI project to Azure.”
The agent will configure the Web App with the required uvicorn startup command and deploy the code to an Azure App Service Linux instance.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/microsoft/python-appservice-deploy/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip python-appservice-deploy.zip -d .agents/skills

Documentation by Microsoft

Python on Azure App Service — Code Deploy

Deploys Python (Flask, Django, FastAPI, generic) code to Azure App Service Linux (P0v3, Python 3.14). Creates RG + Plan + Web App if missing. Hand off to azure-prepare for VNet, Key Vault, databases, or IaC.

MCP tools used: mcp_azure_mcp_subscription_list, mcp_azure_mcp_group_list, mcp_azure_mcp_appservice, mcp_azure_mcp_azd (when azure.yaml is present).

Workflow

Prerequisite: Verify the latest stable Azure CLI; update with approval and recheck if needed.

  1. Resolve context — smart defaults, minimal prompts. Only the app name is interactive; RG (<app>-rg), Plan (<app>-plan), region (current az default or eastus2), subscription are derived. create-app.md §1.

  2. Detect framework (advisory, never blocks). detect.md.

  3. Choose path — azure.yaml host: appservice → deploy-azd.md; else deploy-azcli.md.

  4. Ensure RG → Plan (P0v3 --is-linux) → Web App (--runtime "PYTHON:3.14") exist. Before creating a plan, invoke azure-quotas to check quota availability. On transient ARM errors, follow transient-retry.md. create-app.md.

  5. Set startup — Flask/Django: none (Oryx auto-detects). FastAPI: always python -m uvicorn main:app --host 0.0.0.0. Other: warn. startup-commands.md.

  6. Set SCM_DO_BUILD_DURING_DEPLOYMENT=true.

  7. Deploy — azd deploy or az webapp deploy --type zip --track-status false --enriched-errors true.

  8. STOP. Print the post-deploy message (post-deploy-message.md) and end the turn.

Hard rules
  • LINUX SCRIPTS — normalize selected shell/startup files to LF, then verify no CR bytes remain. Stop on normalization, validation or packaging failure; deploy only a fresh package.

  • DJANGO REMOTE BUILDS — require STATIC_ROOT and successful system/collectstatic checks before packaging.

  • ⛔ NO POST-DEPLOY VERIFICATION — after deploy returns, do not run az webapp log tail, curl, Invoke-WebRequest, or any health probe. App Service needs 2–3 min to warm; a quiet log or early 5xx is not failure.

  • ⛔ SHELL SAFETY — for --runtime always use "PYTHON:3.14" (colon). Never "PYTHON|3.14" (pipe is a shell operator).

  • ⛔ NEVER az webapp up — deprecated. Use Step 7 commands.

  • ✅ URL FORMAT — present endpoints as https://... URLs.

Error Handling

See errors.md for the full symptom → cause → fix matrix. Quick triage: missing plan/app → re-run Step 4; container ping timeout on 8000 → fix startup (Step 5); ModuleNotFoundError after deploy → ensure Step 6 ran, redeploy.

Files

references/create-app.md

Create RG + App Service Plan + Web App (Linux, P0v3)

Creates resources only when missing — every step is show || create (idempotent against existing user-supplied names).

💡 Shell note: Bash blocks below use \ line continuation, ||, 2>/dev/null, $(…). PowerShell equivalents are shown alongside where the bash form doesn't round-trip — substitute ` for \, 2>$null for 2>/dev/null, and $LASTEXITCODE checks for ||.

1. Resolve Azure context — minimize prompts

Ask the user at most ONE question (the app name). Derive everything else. If the user's request already names an RG / Plan / region / subscription (e.g. "deploy to my-team-rg in westus3"), use those values verbatim and skip the corresponding derivation — the show || create flow below works against existing resources.

1a. Subscription
az account show --query id -o tsv

If unset, prompt the user to az login. Only call ask_user if multiple subscriptions are configured and no default is set.

1b. App name

Ask the user once:

"What name would you like for your App Service? (Press Enter to auto-generate one.)"

If empty / "any" / "you choose", call the generator script — it implements the slug rules (lowercase, hyphen-collapse, ≤ 40 chars, ^[a-z][a-z0-9-]{1,38}[a-z0-9]$) and an 8-hex-char GUID suffix:

Example: folder my-flask-app/ → my-flask-app-a3f9c1d2.

1c. Derived names (use only when user did not specify)
ResourceDefault
Resource group<app-name>-rg
App Service Plan<app-name>-plan
1d. Region
  1. If user specified a region, use it.

  2. Else read the CLI default. Suppress the "Configuration is not set" stderr line only when paired with an exit-code check — never blindly drop stderr, since it would also swallow auth/transport errors:

    REGION=$(az config get defaults.location -o tsv 2>/dev/null) || REGION=""
    $region = az config get defaults.location -o tsv 2>$null; if ($LASTEXITCODE -ne 0) { $region = "" }
  3. Else default to eastus2.

  4. Before creating a plan, invoke azure-quotas to check quota and regional availability. Ask before changing a user-specified region; stop if quota is unavailable or unverifiable rather than switching SKU.

1e. Show the defaults summary BEFORE creating

Print one concise block so the user can interrupt to override.

Example (illustrative — substitute the actual derived values, do not print verbatim):

Using these defaults for your Python App Service deployment:
  • App name        : flask-app-demo-27may
  • Resource group  : flask-app-demo-27may-rg     (auto-derived)
  • App Service Plan: flask-app-demo-27may-plan   (auto-derived)
  • Region          : eastus2                     (CLI default)
  • Plan SKU        : P0v3 Linux
  • Runtime         : PYTHON:3.14

Proceeding with create. Reply "stop" within the next message to change any value.

Do not call ask_user for confirmation here — just print and proceed.

1f. Transient error handling

On connection-level or 429/5xx errors from any az ... create in §§2–4, see transient-retry.md. Configuration errors (AuthorizationFailed, SkuNotAvailable, QuotaExceeded, etc.) must not be retried — surface them.

2. Resource Group

az group show -n <rg> --only-show-errors 2>/dev/null || \
  az group create -n <rg> -l <region>
az group show -n <rg> --only-show-errors 2>$null
if ($LASTEXITCODE -ne 0) { az group create -n <rg> -l <region> }

3. App Service Plan — Linux, P0v3 by default

⚠️ MANDATORY: Use --is-linux and --sku P0v3. Do not change OS or SKU unless the user explicitly requests it.

az appservice plan show -n <plan> -g <rg> --only-show-errors 2>/dev/null || \
  az appservice plan create -n <plan> -g <rg> --is-linux --sku P0v3 -l <region>
az appservice plan show -n <plan> -g <rg> --only-show-errors 2>$null
if ($LASTEXITCODE -ne 0) {
  az appservice plan create -n <plan> -g <rg> --is-linux --sku P0v3 -l <region>
}

4. Web App — Python 3.14 runtime (Linux)

⚠️ Shell safety: Always use the colon form PYTHON:3.14 — never the pipe form PYTHON|3.14. The pipe character is a shell operator in PowerShell, Bash, and cmd, and breaks the command even when quoted in some contexts. The colon form is fully supported by az webapp create --runtime and is shell-safe everywhere.

az webapp show -n <app> -g <rg> --only-show-errors 2>/dev/null || \
  az webapp create -n <app> -g <rg> -p <plan> --runtime "PYTHON:3.14"
az webapp show -n <app> -g <rg> --only-show-errors 2>$null
if ($LASTEXITCODE -ne 0) {
  az webapp create -n <app> -g <rg> -p <plan> --runtime "PYTHON:3.14"
}

The 8-hex-char GUID suffix from §1b is sufficient for global hostname uniqueness; the optional --domain-name-scope TenantReuse flag (Azure CLI ≥ 2.76, July 2025) is intentionally omitted to stay compatible with older CLIs.

Discover available runtimes

If PYTHON:3.14 is unavailable in the region:

az webapp list-runtimes --os linux --query "[?contains(@, 'PYTHON')]" -o tsv

The output uses the pipe form (e.g., PYTHON|3.14) — convert to colon form before passing to --runtime. Prefer 3.14; fall back to 3.13, then 3.12.

5. Verify

az webapp show -n <app> -g <rg> --query "{name:name, state:state, host:defaultHostName, linuxFx:siteConfig.linuxFxVersion}" -o table

Expected: state: Running, linuxFx: PYTHON|3.14 (Azure stores it in pipe form internally — normal), host: <app>.azurewebsites.net.

Notes

  • ⛔ Never use az webapp up — deprecated. See deploy-azcli.md.

  • If the user requests a different SKU (e.g. B1 for dev/test), respect it but warn that P0v3 is the documented default.

  • If a Windows plan is requested, hand off to azure-prepare.

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.

Needs: Needs Python

Security

What our scanner noticed· Low risk

  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

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/python-appservice-deploy · 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 or Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download python-appservice-deploy.zip