Azure Kubernetes App Deploy
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill streamlines the deployment of web applications and APIs to an existing Azure Kubernetes Service (AKS) cluster. It performs automated framework detection to identify the application stack, generates appropriate Dockerfiles and Kubernetes manifests, and validates the configuration against AKS Deployment Safeguards. The process includes verification steps to ensure the application is correctly deployed and configured for the target environment.
What it does
- Detects application frameworks and sub-frameworks from project signal files.
- Automatically generates Dockerfiles and Kubernetes manifests based on detected project requirements.
- Validates configurations against AKS Deployment Safeguards (DS001–DS013).
- Resolves base image tags using floating major versions to maintain security and stability.
- Detects application ports and health endpoints to configure Kubernetes probes.
- Provides recovery procedures for deployment failures.
When to use it
- When you need to deploy an existing web application or API to an active AKS cluster.
- When you need to containerize a project for Kubernetes deployment.
- When you need to generate Kubernetes manifests tailored for Azure.
- When your deployment is failing due to AKS Deployment Safeguard checks.
- When setting up CI/CD pipelines for applications running on AKS.
Advantages
- Reduces manual effort in creating container and orchestration configurations.
- Ensures deployments adhere to established AKS Deployment Safeguards.
- Maintains up-to-date base images through automated major version resolution.
- Standardizes health probe and port configuration across different frameworks.
Usage examples
- “Deploy my Express application to the existing AKS cluster.”
- The agent detects the Node.js framework, generates a Dockerfile and Kubernetes manifests, validates them against AKS safeguards, and initiates the deployment.
- “My Spring Boot app deployment is failing AKS safeguard checks.”
- The agent analyzes the current configuration against the DS001-DS013 checklist to identify and resolve the specific safeguard violations.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-kubernetes-app-deploy/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-kubernetes-app-deploy.zip -d .agents/skills
Documentation by Microsoft
Deploy to AKS
Use when: deploying a web app/API to AKS; containerizing for Kubernetes; generating manifests; AKS CI/CD; DS001–DS013 failures.
Not for: provisioning clusters (azure-kubernetes), AKS Automatic readiness (azure-kubernetes-automatic-readiness), non-AKS targets.
Workflow
Requires: existing AKS cluster, az login, kubectl configured. Follow phases/quick-deploy.md. On failure: references/rollback.md.
References
detection.md — framework/port/health detection
safeguards.md — DS001-DS013 checklist
workload-identity.md — Workload Identity setup
rollback.md — recovery procedures
base-images.md — base image policy and
<LATEST_STABLE_*>resolution
Knowledge Packs
Load knowledge-packs/frameworks/<framework>.md per detected framework. Available: spring-boot, express, nextjs, fastapi, django, nestjs, aspnet-core, go, flask
Templates
templates/ (dockerfiles/, k8s/, github-actions/, mermaid/).
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md2.0 KiB
- knowledge-packs/frameworks/aspnet-core.md7.3 KiB
- knowledge-packs/frameworks/django.md6.0 KiB
- knowledge-packs/frameworks/express.md6.7 KiB
- knowledge-packs/frameworks/fastapi.md5.8 KiB
- knowledge-packs/frameworks/flask.md6.2 KiB
- knowledge-packs/frameworks/go.md6.8 KiB
- knowledge-packs/frameworks/nestjs.md6.7 KiB
- knowledge-packs/frameworks/nextjs.md7.1 KiB
- knowledge-packs/frameworks/spring-boot.md6.0 KiB
- phases/quick-deploy.md7.8 KiB
- references/base-images.md3.6 KiB
- references/detection.md3.5 KiB
- references/rollback.md2.0 KiB
- references/safeguards.md2.9 KiB
- references/workload-identity.md7.4 KiB
- templates/dockerfiles/dotnet.Dockerfile2.6 KiB
- templates/dockerfiles/dotnet.dockerignore125 B
- templates/dockerfiles/go.Dockerfile2.1 KiB
- templates/dockerfiles/go.dockerignore128 B
- templates/dockerfiles/java.Dockerfile3.0 KiB
- templates/dockerfiles/java.dockerignore156 B
- templates/dockerfiles/node.Dockerfile3.0 KiB
- templates/dockerfiles/node.dockerignore173 B
- templates/dockerfiles/python.Dockerfile2.6 KiB
- templates/dockerfiles/python.dockerignore201 B
- templates/dockerfiles/rust.Dockerfile3.2 KiB
- templates/dockerfiles/rust.dockerignore87 B
- templates/github-actions/deploy.yml7.4 KiB
- templates/k8s/configmap.yaml1.0 KiB
- templates/k8s/deployment.yaml3.4 KiB
- templates/k8s/gateway.yaml1.5 KiB
- templates/k8s/hpa.yaml1.4 KiB
- templates/k8s/httproute.yaml1.3 KiB
- templates/k8s/ingress.yaml1.9 KiB
- templates/k8s/namespace.yaml734 B
- templates/k8s/networkpolicy.yaml1.6 KiB
- templates/k8s/pdb.yaml758 B
- templates/k8s/service.yaml864 B
- templates/k8s/serviceaccount.yaml1.4 KiB
- templates/mermaid/architecture-diagram.md1.6 KiB
- templates/mermaid/summary-dashboard.md1.7 KiB
knowledge-packs/frameworks/flask.md
Flask Knowledge Pack
Applies to: Projects detected with
requirements.txt,pyproject.toml, orPipfilecontainingflask
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"), 200Readiness 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"), 503Probe 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: 3Note: 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-keySecret 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
/tmpas the default staging directory forrequest.filesTemporary processing may write intermediate results to
/tmp
Required volume mount
volumes:
- name: tmp
emptyDir: {}
containers:
- name: app
volumeMounts:
- name: tmp
mountPath: /tmpNo 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 rundefault — do not use in production)Production port: 8000 (gunicorn convention)
CLI flag:
--bind 0.0.0.0:8000passed togunicornEnv var override:
PORT(read viagunicorn --bind 0.0.0.0:$PORTor in app codeint(os.environ.get("PORT", 8000)))Workers formula:
2 * CPU_CORES + 1— override at runtime viaWEB_CONCURRENCYenv varEntry point variants:
gunicorn "app:app"(module-level) orgunicorn "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 |
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.
Security
What our scanner noticed· Low risk
- Instructions that use the network
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/azure-kubernetes/azure-kubernetes-app-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.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-kubernetes-app-deploy.zip