All skills
microsoft avatar

/azure-kubernetes

@a8f19b4
by microsoftmicrosoft/skills3.1k stars
351

Plan, create, and configure production-ready Azure Kubernetes Service (AKS) clusters. Covers Day-0 checklist, SKU selection (Automatic vs Standard), networking options (private API server, Azure CNI Overlay, egress configuration), security, and operations (autoscaling, upgrade strategy, cost analysis). WHEN: create AKS environment, provision AKS, enable AKS observability, design AKS networking, choose AKS SKU, secure AKS, optimize AKS, AKS spot nodes, AKS cluster-autoscaler, rightsize AKS pod, pod rightsizing, over-provisioned AKS pod, pod resource requests and limits, Vertical Pod Autoscaler, VPA recommendations.

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

This session only. Nothing lands on disk.

azure-kubernetes-app-deployknowledge-packsframeworksflask.md

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

Flask Knowledge Pack

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

Quick Reference

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

Health Endpoints

Flask does not include health check endpoints — they must be defined explicitly in application code:

Minimal health route

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/health")
def health():
    return jsonify(status="ok"), 200

Readiness route with database check

from flask import jsonify
from sqlalchemy import text

@app.route("/ready")
def ready():
    try:
        db.session.execute(text("SELECT 1"))
        return jsonify(status="ready"), 200
    except Exception:
        return jsonify(status="not ready"), 503

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: Flask apps behind gunicorn start quickly (typically <3s), so initialDelaySeconds: 5 is sufficient — much lower than JVM-based frameworks.


Database Profiles

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

ORM / Driver Package(s) Connection String Env Var
Flask-SQLAlchemy flask-sqlalchemy, psycopg2-binary SQLALCHEMY_DATABASE_URI
SQLAlchemy direct sqlalchemy, psycopg2-binary DATABASE_URL
psycopg2 direct psycopg2-binary DATABASE_URL

Important: Flask-SQLAlchemy reads the connection string from app.config["SQLALCHEMY_DATABASE_URI"], which is typically set via os.environ.get("SQLALCHEMY_DATABASE_URI") or os.environ.get("DATABASE_URL"). Ensure the env var name matches what the app expects.

Environment variables for PostgreSQL on AKS

env:
  - name: SQLALCHEMY_DATABASE_URI
    value: "postgresql://{{IDENTITY_NAME}}@{{PG_SERVER_NAME}}.postgres.database.azure.com:5432/{{DB_NAME}}?sslmode=require"
  - name: SECRET_KEY
    valueFrom:
      secretKeyRef:
        name: {{APP_NAME}}-secrets
        key: secret-key

Secret for SECRET_KEY

Flask requires SECRET_KEY for session signing, CSRF tokens, and any use of flask.session. Never hardcode it — store it in a Kubernetes Secret:

apiVersion: v1
kind: Secret
metadata:
  name: {{APP_NAME}}-secrets
type: Opaque
stringData:
  secret-key: "<generate-a-random-string>"

ConfigMap pattern

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

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, Flask apps typically only need /tmp writable:

  • Uploaded files use /tmp as the default staging directory for request.files
  • 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 Flask apps.


Resource Sizing

Flask with Gunicorn runs multiple worker processes. Size for the number of workers (default: 2-4).

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

Port Configuration

  • Development port: 5000 (flask run default — do not use in production)
  • Production port: 8000 (gunicorn convention)
  • CLI flag: --bind 0.0.0.0:8000 passed to gunicorn
  • Env var override: PORT (read via gunicorn --bind 0.0.0.0:$PORT or in app code int(os.environ.get("PORT", 8000)))
  • Workers formula: 2 * CPU_CORES + 1 — override at runtime via WEB_CONCURRENCY env var
  • Entry point variants: gunicorn "app:app" (module-level) or gunicorn "myapp:create_app()" (application factory)

Gunicorn logs the port on startup: Listening at: http://0.0.0.0:8000


Build Commands

Tool Install Command
pip pip install --no-cache-dir -r requirements.txt
Poetry poetry install --only main --no-interaction

Ensure gunicorn is listed in requirements.txt or pyproject.toml production dependencies.


Common Issues on AKS

Issue Symptom Fix
Running dev server in production Single-threaded, poor performance, WARNING: This is a development server in logs Use gunicorn as the ENTRYPOINT — never use flask run or app.run() in production containers
SECRET_KEY not set RuntimeError: The session is unavailable because no secret key was set, CSRF failures Set SECRET_KEY via a Kubernetes Secret and reference it as an env var in the Deployment manifest
Flask binds to localhost Connection refused from Kubernetes probes Pass --bind 0.0.0.0:8000 to gunicorn — the Flask dev server defaults to 127.0.0.1 which is unreachable from outside the container
Gunicorn not installed ModuleNotFoundError: No module named 'gunicorn' Ensure gunicorn is in requirements.txt or pyproject.toml main dependencies — it is often only in dev dependencies or missing entirely
DB connections not closed sqlalchemy.exc.TimeoutError: QueuePool limit, PostgreSQL max_connections exhaustion Configure pool size with SQLALCHEMY_ENGINE_OPTIONS = {"pool_size": 5, "max_overflow": 10, "pool_recycle": 300} and match PostgreSQL max_connections

Source: SKILL.md on GitHub

No alerts9d3 checks · Risk SAFE
  • Gen Agent Trust Hub9d

    This skill provides comprehensive, production-grade guidance for Azure Kubernetes Service (AKS) with a strong emphasis on security best practices, including Workload Identity, hardened container configurations, and automated readiness assessments.

  • Socket9d

    No alerts

  • Snyk9d

    Risk: LOW · No 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 yesterday.

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

README badge

README badge for microsoft/skills/azure-kubernetes