Deploying containers, binaries and scripts
Implement application deployment by using containers, binaries, and scripts
Build once, deploy many
The artifact produced by the build stage is what every environment receives. Rebuilding per environment breaks the guarantee that what you tested is what you shipped.
stages:
- stage: Build
jobs:
- job: Package
steps:
- publish: $(Build.ArtifactStagingDirectory)
artifact: drop
- stage: Deploy
dependsOn: Build
jobs:
- deployment: DeployApp
environment: production
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: drop
- task: AzureWebApp@1
inputs:
appName: $(appName)
package: $(Pipeline.Workspace)/drop/**/*.zipEnvironment differences belong in configuration — variable groups, slot settings, App Configuration — not in separate builds.
The three shapes
| Shape | Identity | Dependencies and lifecycle |
|---|---|---|
| Container image | A manifest digest guarantees the pulled image version; a unique, never-reused deployment tag can also be locked | External configuration, secrets, mounts, orchestrator settings, and the host kernel remain outside the image identity |
| Binary / package | An exact package version fixes the payload; a Pipeline Artifact identifies files from a specific run | Package versions are permanently reserved, while Pipeline Artifacts follow run retention; both still depend on target runtime and configuration |
| Script | A version-controlled script can have an immutable commit identity | Imperative effects can depend on prior target state, tools, runtime, and inputs; handle retries idempotently |
Containers
Avoid reused stable tags such as latest: they can resolve to a different image by production deployment time. Deploy by digest when possible. An alternative is a unique, never-reused tag that is locked after deployment.
Scripts
An imperative script can produce a different result when prior or partial target state differs. Make its handling idempotent so a retry is safe, and select or control tool/runtime versions when they affect behavior. A pipeline retry does not supply idempotency.
Compact implementation paths
- Container: publish one image, then deploy the same explicit image reference through environments; prefer its digest, or a unique never-reused and locked tag.
- Binary: publish the package as
dropin the build stage, download that same Pipeline Artifact in a dependent deployment stage, and deploy it with a task such asAzureWebApp@1. - Script: publish the version-controlled script as an artifact, download it in the dependent deployment job, and invoke it with environment-specific inputs. Make prior/partial-state handling idempotent.
Pipeline Artifacts belong to pipeline runs and are deleted with a deleted run. Azure Artifacts and GitHub Packages host versioned packages under their own version and retention contracts; do not treat these stores as interchangeable.
Primary sources
- https://learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-400
- https://learn.microsoft.com/en-us/azure/well-architected/operational-excellence/workload-supply-chain
- https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/publishing-workflows
- https://learn.microsoft.com/en-us/azure/devops/pipelines/artifacts/pipeline-artifacts
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/create-multistage-pipeline
- https://learn.microsoft.com/en-us/azure/azure-app-configuration/faq
- https://learn.microsoft.com/en-us/azure/container-registry/container-registry-image-tag-version
- https://learn.microsoft.com/en-us/azure/container-registry/container-registry-concepts
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/tasks
- https://learn.microsoft.com/en-us/azure/well-architected/operational-excellence/maturity-model
- https://learn.microsoft.com/en-us/azure/devops/artifacts/artifacts-key-concepts
- https://docs.github.com/en/packages/learn-github-packages/introduction-to-github-packages