Diagnosing azure deployment failures
Skill alexpizarro/azure-lean-stack-skills/skills/diagnosing-azure-deployment-failures
Azure apps that cost nothing when nobody's using them. A Claude Code skill pack — 14 composable skills, 37+ documented gotchas, branch-per-env CI/CD.
npx -y skills add alexpizarro/azure-lean-stack-skills --skill diagnosing-azure-deployment-failuresAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Matches Azure deploy / CI / runtime failures against 37+ documented gotchas with verified fixes (BCP258, AADSTS70021, sqlcmd-not-found, FC1-CLI-silent-fallback, ACS dataLocation quirks, SSE timeouts, and more). Delegates to Microsoft's azure-diagnostics for live log/metric queries. Use when a deploy fails, a deployed app misbehaves, or a CI step errors.
SKILL.md
7.1 KB, as published. Nobody here has run it
Diagnosing Azure Deployment Failures
Lookup-first triage against documented gotchas. If the symptom doesn't match a known entry, escalate to Microsoft's azure-diagnostics for live log/metric queries.
How to use this skill
- Get the failing symptom (error code, stack trace, observed behaviour)
- Match against the table below
- Apply the documented fix
- If no match, see references/gotchas.md for the full catalogue
- If still no match, capture a new gotcha via curating-azure-deployment-learnings
Quick symptom table
| Symptom | Likely cause | Fix |
|---|---|---|
BCP258: sqlAdminPassword missing | Using .bicepparam instead of .parameters.json | Keep params as .parameters.json; use @ prefix |
LocationNotAvailableForResourceType for SWA | australiaeast not supported | Hard-code swaLocation = 'eastasia' |
Multiple files found matching pattern *.sql | azure/sql-action accepts only one file | Replace with sqlcmd bash loop |
sqlcmd: command not found (exit 127) | Not pre-installed on ubuntu-24.04 | Install mssql-tools18 via Microsoft apt repo |
gpg: cannot open /dev/tty | gpg --dearmor without --batch in CI | Use gpg --batch --yes --dearmor | sudo tee |
OIDC fails AADSTS70021 | Federated credential subject mismatch | Must match repo:owner/repo:ref:refs/heads/branch exactly |
AZURE_CREDENTIALS auth fails silently | WARNING: text prepended to SP JSON | Strip with 2>/dev/null | python3 pipeline |
| Bicep runs on every push (slow) | No change detection | Add git diff check, conditional steps |
error TS7016: no declaration for 'mssql' | @types/mssql missing | Add "@types/mssql": "^9.1.5" |
| New function returns 404 after deploy | Not imported in api/src/index.ts | Add import './functions/{name}' |
| Functions return 500 on first request | SQL serverless auto-paused | Wait 30–60s, retry |
| Placeholder strings cause cryptic errors | Non-empty placeholders fool if (!value) | Use "" in example files |
az functionapp create creates wrong plan | CLI silently falls back to Y1/Dynamic | Use ARM REST API or Bicep for FC1 |
az appservice plan create --sku FC1 fails | CLI doesn't support FC1 reliably | Use ARM REST API |
| ARM PUT doesn't change hosting plan | Can't migrate existing app | Delete and recreate |
FUNCTIONS_WORKER_RUNTIME causes failure | Forbidden on FC1 | Remove from app settings |
az functionapp cors add returns Bad Request | CLI CORS broken on FC1 | Use ARM REST API |
"main": "dist/functions/*.js" doesn't work | Glob not resolved | Use "main": "dist/index.js" |
Missing package-lock.json breaks CI | cache-dependency-path points to missing file | Commit lock file |
| Publish profile auth 401 on FC1 | Kudu auth different on FC1 | Use SP auth with azure/login@v2 |
| Cold start 15-30s on ACA | Large Docker image | Use Alpine, prune devDeps |
| SSE connections drop after 4 min | Default 240s request timeout | --request-timeout 1800 |
az containerapp update has no effect | Unchanged secret values skip restart | az containerapp revision restart |
| Secrets not available in app | Env var not linked | --set-env-vars "VAR=secretref:secret-name" |
| Docker Hub image not pulled | Rate limit (100/6h anonymous) | Authenticated pulls or move to GHCR/ACR |
DeploymentModelNotSupported (Azure OpenAI) | Model version not available in region | Verify: az cognitiveservices model list --location ... |
EMAIL_FROM unknown before first deploy | Azure-managed domain hash auto-generated | Retrieve post-deploy with az communication email domain show |
| Email send crashes HTTP handler | pollUntilDone() throws | Use safeSend() wrapper |
| ACS resources fail with location error | Microsoft.Communication/* requires location: 'global' | Hardcode location: 'global' |
ACS dataLocation fails | Uses plain English, not region IDs | dataLocation: 'Australia' |
| ACS circular dependency | linkedDomains + dependsOn conflict | Declare order: emailService → domain → acs |
403 on roleAssignments | OIDC SP only has Contributor | Grant User Access Administrator at RG scope |
listSecrets output warning | Bicep linter flags secrets in outputs | #disable-next-line outputs-should-not-contain-secrets |
| SWA self-referencing URL needed | APP_BASE_URL unknown before first deploy | Use 'https://${swa.properties.defaultHostname}' |
| Can't test before Azure provisioned | No mock pattern | Check if (!process.env.KEY) → return mock |
local.settings.json placeholder strings | Fake strings are truthy | Use "" for all user-input values |
| SQL Serverless bill higher than expected; DB never pauses | Health endpoint or scheduler polls the DB, keeping it awake 24/7 | DB-free shallow health check; or switch to flat Basic tier (~$5/mo). See cost-guardrails Guardrail #11 |
For the full catalogue with explanations, see references/gotchas.md.
When to delegate to Microsoft's azure-diagnostics
This skill is a static catalogue — known failure modes with known fixes. For dynamic failures, delegate:
| Symptom | Use Microsoft's skill |
|---|---|
| "My deployed app returns 500 — what's in the logs?" | azure-diagnostics + Azure MCP for live log queries |
| "Performance is slow — what's the bottleneck?" | azure-diagnostics + appinsights-instrumentation |
| "What's running in my subscription right now?" | azure-resource-lookup |
| "Why is this resource costing so much?" | azure-cost |
See composition-with-azure-diagnostics.md.
General rules
- Template + architecture must stay in sync — when behaviour changes, update the templates in the same commit.
- Always add
@types/*for packages that don't bundle their own.d.tsfiles. - GPG in CI always needs
--batch --yesand pipe throughsudo tee. - Verify Azure OpenAI / Cognitive model versions per region before writing Bicep.
- Every new SWA function must be imported in
index.ts— compilation and deployment alone are insufficient. - ACS resources are always
location: 'global'regardless of where the RG is. - Email failures should log, not crash — use
safeSend()wrapper. - Conditional Bicep saves 3–5 min per code-only deploy.
Composes with
- curating-azure-deployment-learnings — capture new gotchas as you find them
- Microsoft's
azure-diagnostics— live log/metric queries - Microsoft's
appinsights-instrumentation— adding telemetry to a running app - Microsoft's
azure-resource-lookup— "what's actually deployed"