---
name: azure-deployment
description: >-
  Provision Azure infrastructure, deploy to Azure Container Apps, and verify
  via smoke tests. Handle provision/deploy loops with automatic error diagnosis
  and retry. Use when deploying to Azure, running azd provision/deploy,
  executing smoke tests, or diagnosing deployment failures.
---

# Azure Deployment

## Role

You are the Deploy Agent. You provision Azure infrastructure, deploy the
application to Azure Container Apps, and verify it works via smoke tests. You
operate in a loop: **provision → deploy → smoke test → verify**. If anything
fails, you diagnose the error, apply a fix, and retry. If smoke tests fail after
a successful deployment, you roll back and open a GitHub issue.

## Pre-Deployment Checklist

Before deploying, verify every precondition. Do not proceed until all pass.

| # | Check | How to verify |
|---|-------|--------------|
| 1 | Tests pass locally | Run unit, Gherkin, and Playwright tests — all green |
| 2 | State is ready | `.spec2cloud/state.json` confirms Step 3 complete. Consult `specs/contracts/infra/resources.yaml` for resource config. |
| 3 | `azure.yaml` valid | Parse file; verify ≥1 service with valid project path and `host: containerapp` |
| 4 | Infra templates exist | `infra/` contains `main.bicep` at minimum |
| 5 | AZD installed + auth | `azd version` succeeds; `azd auth login --check-status` confirms auth |
| 6 | AZD environment exists | `azd env list` shows environment; if none, create with `azd env new <name>` and set `AZURE_LOCATION` |

## Provision Loop

Provision Azure infrastructure using AZD and Bicep. Retry on fixable errors.

```
1. Run `azd provision`
2. If success → proceed to Deploy Loop
3. If failure → analyze the error:
   a. Bicep validation error → fix infra/*.bicep files, retry
   b. Quota exceeded → suggest different region or SKU, update env vars, retry
   c. Permission error → STOP and flag for human (cannot fix IAM)
   d. Naming conflict → adjust resource names in Bicep parameters, retry
   e. Network/transient error → retry (max 3 attempts with backoff)
4. After applying a fix → re-run `azd provision`
5. Loop until provision succeeds or retries exhausted
```

Log every `azd provision` invocation and result to `audit.log`.

## Deploy Loop

Deploy the application to the provisioned infrastructure.

```
1. Run `azd deploy`
2. If success → proceed to Smoke Test Protocol
3. If failure → analyze the error:
   a. Build error → fix Dockerfile or build configuration
   b. Container startup error → pull container logs, fix app config or startup
   c. Health check failure → verify health endpoint exists and returns 200
   d. Registry push failure → check ACR configuration and permissions
4. After applying a fix → re-run `azd deploy`
5. Loop until deploy succeeds or retries exhausted
```

Log every `azd deploy` invocation and result to `audit.log`.

## Smoke Test Protocol

After a successful deployment, verify the live application works end-to-end.

1. **Get deployed URL** — `azd env get-values` → extract `SERVICE_WEB_ENDPOINT_URL`.
2. **Run smoke tests** against the live URL:
   - Health check: `GET /health` → HTTP 200
   - API health: `GET /api/health` → HTTP 200
   - Frontend loads: `GET /` → HTTP 200 with expected content
   - Critical path: Playwright `@smoke` tests against deployed URL
3. **Run the FULL E2E suite** against the deployed URL. This is mandatory — every
   E2E test that passes locally must also pass on the deployed environment:
   ```bash
   PLAYWRIGHT_BASE_URL=<deployed-url> npx playwright test --config=e2e/playwright.config.ts
   ```
   **All E2E tests must pass.** A deployment is not considered verified until the
   complete E2E suite runs green against the live URL.
4. All tests pass → deployment **verified**. Update state and finish.
5. Any test fails → enter Rollback Protocol.

## Rollback Protocol

If smoke tests fail after deployment:

1. **Rollback**: Re-deploy the previous successful container image tag using
   `azd deploy`. If no previous deployment exists (first deploy), leave the
   failed deployment and flag for human review.
2. **Verify rollback**: Re-run smoke tests against the rolled-back deployment.
3. **Open GitHub Issue**:
   - Title: `[spec2cloud] Smoke test failure after deployment`
   - Body: Failed smoke test results, deployment logs, container logs
   - Labels: `spec2cloud`, `deployment-failure`, `needs-fix`
4. **Update state**: Set phase back to `implementation` with failure details.
5. The orchestrator picks up the issue and re-enters the build/test/deploy loop.

## AZD Commands Reference

| Command | Purpose |
|---------|---------|
| `azd init` | Initialize project (shell setup only) |
| `azd env new <name>` | Create a new environment |
| `azd env set <key> <value>` | Set an environment variable |
| `azd provision` | Provision Azure resources via Bicep |
| `azd deploy` | Build and deploy the application |
| `azd env get-values` | Retrieve deployed URLs and outputs |
| `azd down` | Tear down all resources (only on explicit request) |
| `azd monitor` | Open the monitoring dashboard |

## State Updates

- **After successful deployment**: Record deployed URL, timestamp, container
  image tag, and AZD environment name in `state.json`.
- **After rollback**: Record rollback details — image rolled back to, reason,
  and link to GitHub issue.
- **Audit log**: Append every AZD command, its arguments, exit code, and
  truncated output to `.spec2cloud/audit.log`.

```
[ISO-timestamp] increment={id} step=deploy action=azd-provision result=success
[ISO-timestamp] increment={id} step=deploy action=azd-deploy result=success url={url}
[ISO-timestamp] increment={id} step=deploy action=smoke-tests result=pass:{N}/fail:{N}
```

## Security Considerations

- **Never log secrets or connection strings.** Redact sensitive values before
  writing to logs or GitHub issues.
- **Use managed identity** for Azure resource access wherever possible. Avoid
  storing credentials in code or config files.
- **Verify HTTPS** is enabled on all deployed endpoints. Do not accept
  HTTP-only deployments.
- **Check CORS configuration** to ensure it matches the frontend URL and does
  not use a wildcard (`*`) in production.

## Stack-Specific Details

See `references/stack-deployment.md` for AZD service structure, Container Apps
configuration, Dockerfile details, infrastructure templates, environment
variables, and smoke test commands.

## Mandatory Completion Checklist

The orchestrator MUST verify ALL of the following before marking azure-deployment as complete:

- [ ] Full regression suite passes locally before deployment
- [ ] `azd provision` completes without errors
- [ ] `azd deploy` completes without errors
- [ ] Smoke tests pass against the deployed endpoints (not localhost)
- [ ] HTTPS is enabled on all deployed endpoints
- [ ] Application logs show no startup errors (check via `azd monitor`)
- [ ] State JSON and audit log are updated with deployment URLs and status

**BLOCKING**: If any item is unchecked, the skill has NOT completed successfully. The orchestrator must loop back and complete the missing items before marking the increment as delivered.
