All skills
microsoft avatar

/azure-kubernetes-app-deploy

@a8f19b4
by microsoftmicrosoft/skills3.1k stars
351

Use when deploying an existing web application or API to an already-running Azure Kubernetes Service cluster. Detects the framework, generates a Dockerfile and Kubernetes manifests, validates against AKS Deployment Safeguards, and deploys with verification. WHEN: deploy app to AKS, deploy to existing AKS cluster, containerize app for Kubernetes, generate K8s manifests for Azure, set up CI/CD for AKS, my AKS deployment is failing safeguard checks, I have a Django/Express/Spring Boot app to run on AKS. DO NOT USE FOR: creating or provisioning an AKS cluster (use azure-kubernetes), assessing migration to AKS Automatic (use azure-kubernetes-automatic-readiness), or deploying to non-AKS targets like Web Apps, Container Apps, or Functions.

Use this Skill: https://skilld.dev/gh/microsoft/skills/azure-kubernetes-app-deploy

This session only. Nothing lands on disk.

knowledge-packsframeworksfastapi.md

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

FastAPI Knowledge Pack

Applies to: Projects detected with requirements.txt, pyproject.toml, or Pipfile containing fastapi

Quick Reference

Property Value
Signal files requirements.txt/pyproject.toml/Pipfile containing fastapi
Default port 8000
Health path /health + /ready
Base template templates/dockerfiles/python.Dockerfile (+ references/base-images.md)

Health Endpoints

FastAPI health endpoints must be defined explicitly in application code:

Minimal health route

from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
async def health():
    return {"status": "ok"}

Readiness route with database check

from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

@app.get("/ready")
async def ready(db: AsyncSession = Depends(get_db)):
    try:
        await db.execute(text("SELECT 1"))
        return {"status": "ready"}
    except Exception:
        return JSONResponse(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            content={"status": "not ready"},
        )

Probe configuration in Deployment manifest

livenessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 15
  timeoutSeconds: 3
  failureThreshold: 3
readinessProbe:
  httpGet:
    path: /ready
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 3
  failureThreshold: 3

Note: FastAPI apps start quickly (typically <2s), so initialDelaySeconds: 5 is sufficient — much lower than JVM-based frameworks.


Database Profiles

FastAPI does not have a built-in profile system. Database configuration is typically driven by environment variables:

ORM / Driver Package(s) Connection String Format
SQLAlchemy async + asyncpg sqlalchemy[asyncio], asyncpg postgresql+asyncpg://user:pass@host:5432/db
Tortoise ORM tortoise-orm, asyncpg postgres://user:pass@host:5432/db
SQLModel sqlmodel, asyncpg postgresql+asyncpg://user:pass@host:5432/db
asyncpg direct asyncpg postgresql://user:pass@host:5432/db

Important: SQLAlchemy async requires the +asyncpg suffix in the connection URL scheme (postgresql+asyncpg://). Omitting it will default to the synchronous psycopg2 driver, which blocks the event loop.

Environment variables for PostgreSQL on AKS

env:
  - name: DATABASE_URL
    value: "postgresql+asyncpg://{{IDENTITY_NAME}}@{{PG_SERVER_NAME}}.postgres.database.azure.com:5432/{{DB_NAME}}?sslmode=require"

ConfigMap pattern

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{APP_NAME}}-config
data:
  DATABASE_URL: "postgresql+asyncpg://{{IDENTITY_NAME}}@{{PG_SERVER_NAME}}.postgres.database.azure.com:5432/{{DB_NAME}}?sslmode=require"
  UVICORN_WORKERS: "1"

Workload Identity with azure-identity

See references/workload-identity.md for connection patterns. Requires azure-identity package.


Writable Paths (DS012 Compliance)

When readOnlyRootFilesystem: true is set, FastAPI apps typically only need /tmp writable:

  • Uploaded files use /tmp as the default staging directory for UploadFile
  • Temporary processing may write intermediate results to /tmp

Required volume mount

volumes:
  - name: tmp
    emptyDir: {}
containers:
  - name: app
    volumeMounts:
      - name: tmp
        mountPath: /tmp

No other writable paths are typically needed for production FastAPI apps.


Resource Sizing

FastAPI with Uvicorn is async and lightweight. Size for workload concurrency.

Resource Request Limit
CPU 100m 500m
Memory 128Mi 256Mi

Port Configuration

  • Default port: 8000
  • CLI flag: --host 0.0.0.0 --port 8000 passed to uvicorn — must include --host 0.0.0.0 (uvicorn defaults to 127.0.0.1, unreachable from Kubernetes probes)
  • Workers: use --workers 1 for pure-async apps (async code uses a single event loop); 2 * CPU_CORES + 1 only for sync/blocking handlers
  • Env var override: PORT (read via uvicorn --port $PORT or int(os.environ.get("PORT", 8000)))

Uvicorn logs the port on startup: Uvicorn running on http://0.0.0.0:8000


Build Commands

Tool Install Command Output
pip pip install --no-cache-dir -r requirements.txt Packages in site-packages
Poetry poetry install --only main --no-interaction Packages in virtualenv
uv uv sync --frozen --no-dev Packages in virtualenv

The --no-cache-dir flag (pip) and --no-interaction flag (Poetry) suppress interactive prompts — important for CI/CD and Docker builds.


Common Issues on AKS

Issue Symptom Fix
Uvicorn workers misconfigured High latency under load, single-core CPU usage Set --workers to 2 * CPU_CORES + 1 for sync code, or 1 when using async handlers (async code uses a single event loop)
Async DB pool exhaustion asyncpg.exceptions.TooManyConnectionsError Configure pool size with create_async_engine(pool_size=5, max_overflow=10) and match PostgreSQL max_connections
Alpine build fails gcc errors installing cryptography, psycopg2, numpy Use the Debian-slim Python base (see references/base-images.md) instead of Alpine
Uvicorn binds to localhost Connection refused from Kubernetes probes Set --host 0.0.0.0 — uvicorn defaults to 127.0.0.1 which is unreachable from outside the container
Missing uvicorn in production ModuleNotFoundError: No module named 'uvicorn' Ensure uvicorn[standard] is in requirements.txt — it is often only in dev dependencies

Source: SKILL.md on GitHub

1 warning1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    This skill facilitates the deployment of applications to Azure Kubernetes Service (AKS) by automating Dockerfile generation and Kubernetes manifest creation. It incorporates security best practices such as AKS Deployment Safeguards and Azure Workload Identity. No significant security considerations were identified; external resource references and tool usage align with the skill's intended deployment purpose.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: MEDIUM · 2 issues

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

Last checked against GitHub 20 hours ago.

Activeupdated 2 months ago
metadata
{
  "author": "Microsoft",
  "version": "1.0.0"
}

README badge

README badge for microsoft/skills/azure-kubernetes-app-deploy