An Azure deployment promotes versioned application, configuration, and infrastructure changes through environments using repeatable automation.
Bicep or ARM templates describe Azure resources, while Azure DevOps, GitHub Actions, or another CI system can build, test, approve, and deploy artifacts.
A safe release defines identity, environment controls, health verification, database compatibility, observability, and rollback before production traffic changes.
Build once, test that exact package or image, and promote it by version. Rebuilding from the same branch in each environment can produce different dependencies or output.
Keep resource configuration in source control, preview changes with what-if, and use parameters for genuine environment differences. Protect stateful resources from accidental replacement or deletion.
Deployment slots, Container Apps revisions, AKS rollouts, and traffic routing can support rolling, blue-green, or canary releases. Choose according to compatibility, capacity, and failure cost.
Run smoke tests through the actual entry point, inspect Application Insights and platform health, and verify background processing. Rollback must restore behavior without losing or corrupting data.
For supported App Service plans, deploy to a staging slot, warm the application, run smoke checks through the slot URL, and then swap traffic. Mark environment-specific values such as production connection settings as deployment-slot settings so they remain with their slot.
A swap changes routing and configuration; it is not a database rollback. Confirm authentication redirects, custom domains, background jobs, and dependencies in the staging context before switching production traffic.
Use expand-and-contract migrations when old and new application versions overlap: add compatible schema first, deploy code that can handle both shapes, migrate data, then remove obsolete schema in a later release. A destructive migration bundled with application deployment can make rollback impossible.
Define who stops a rollout, which metric triggers the decision, and how queued work or partial writes are handled. Practice recovery with production-like data volume instead of treating a successful pipeline status as proof of application health.
Bicep declares Azure resources and properties and compiles to an ARM template for Resource Manager deployment. Use symbolic references so Resource Manager infers dependencies rather than adding unnecessary `dependsOn`. Select stable API versions whose properties are supported in the target cloud and Region, and review preview APIs before production use.
Split modules by ownership and lifecycle, not simply by resource type. Keep a workload entry file readable and publish reviewed modules or template specs when reuse is real. Parameters represent environment input; variables derive values; outputs expose only what another deployment genuinely needs. Never emit secrets as outputs.
Resource Manager stores deployed state, so Bicep does not need a separate state file. That does not eliminate drift or ownership: portal and CLI changes can still alter live resources. Keep templates, parameter files, module versions, and deployment scopes in version control.
Lint and build Bicep locally, validate deployment at the intended scope, and run Resource Manager what-if before change. What-if predicts create, modify, delete, ignore, and no-change results from available expansion and permissions; it is a review aid, not a guarantee that provider behavior or runtime migration is safe.
Inspect replacements, removals, public exposure, role assignments, Policy changes, network routes, diagnostic settings, and stateful resources. Reduce noisy false changes by using stable defaults and known property behavior, but do not train reviewers to ignore the output wholesale. Save important what-if evidence with the release.
Use incremental deployment mode intentionally and understand complete-mode or deployment-stack deletion behavior before adoption. Protect data through backup, locks, and service controls rather than relying on template semantics alone. A valid deployment can still remove application compatibility.
Build application artifacts once and promote the same package or image by immutable version. Use workload identity federation for GitHub Actions, Azure Pipelines, or another trusted issuer where supported instead of storing a service-principal secret. Bind issuer and subject to the exact repository, branch, environment, or pipeline trust required.
Separate build, infrastructure deployment, application release, migration, and runtime identities. Restrict Bicep deployment scope, role-assignment actions, Key Vault access, managed-identity attachment, and extension execution. Permission to change code or infrastructure often becomes permission to act as the workload.
Record commit, build, artifact digest, SBOM or scan evidence, Bicep and module versions, parameters, what-if, approvals, deployment ID, migration, feature flags, and result in a release manifest. Protect artifact and template registries against mutation and deletion.
Deployment slots, Container Apps revisions, AKS rollouts, Front Door routing, and feature flags provide different traffic and exposure controls. Choose rolling, blue-green, canary, or slot swap from capacity, startup, mixed-version compatibility, and rollback needs. Define candidate size, observation window, promotion signal, and abort condition before release.
Health checks must prove readiness without making a shared dependency outage recycle every instance. Use synthetic tests for rare paths and real traffic metrics for broad behavior. Publish deployment annotations into Azure Monitor so latency and failure changes align with the exact revision.
Keep the previous revision and configuration available until the data and event compatibility window closes. Feature flags need owners, safe defaults, audit, and deletion dates. Temporary parallel capacity, public routes, test slots, and elevated roles need explicit cleanup.
Use expand-and-contract database migrations: add compatible schema, deploy code that handles both forms, backfill with checkpoints and rate limits, switch reads and writes, then remove old structures after rollback no longer needs them. A destructive predeployment migration can make application rollback impossible.
Version events, APIs, configuration, secrets, certificates, and private DNS changes with the release. Queue messages can outlive code, and old replicas may retain old secrets. Coordinate rotation and schema changes across every active revision and background consumer.
Test production-like data volume, locks, transaction log, connection pools, backfill duration, and downstream quotas. Define a no-return point and decide whether recovery reverses data, disables new writes, restores backup, or rolls forward. Store migration evidence separately from application startup logs.
Rollback is another deployment of known application and infrastructure versions; it does not erase database writes, Policy remediation, external messages, or manual changes. Verify old code against current schema and configuration. Preserve failed artifacts, deployment operations, Activity Log events, what-if output, and telemetry for diagnosis.
Detect resource drift through Resource Graph, Policy, deployment history, what-if, and service-specific configuration evidence. Investigate emergency changes before overwriting them and feed legitimate fixes back into Bicep. Deployment stacks can manage resource lifecycle, but deletion semantics require careful review and staged adoption.
Rehearse application failure and infrastructure failure using the same pipeline identities, approvals, traffic control, alarms, and rollback commands as production. Measure decision and recovery time, verify data, then remove temporary access. A release process is ready when recovery does not depend on portal improvisation.
az deployment group create \
--resource-group rg-app-dev \
--template-file main.bicep \
--parameters environment=dev appName=orders
A deployment updates networking successfully but fails while creating the application resource.
Constraints: The deployment is incremental, existing resources contain data, and rollback must not delete unrelated infrastructure.
Decision: Inspect deployment operations, correct the failed declaration, preview with what-if, and redeploy the same desired state.
Verification: What-if shows only intended changes and the second deployment converges without duplicating resources.
Failure test: Reintroduce the invalid property in a test scope and confirm diagnostics identify the exact resource.
Expected evidence: What-if shows only intended changes and the second deployment converges without duplicating resources.
Explore 500+ free tutorials across 20+ languages and frameworks.