INSIGHTS
DevOps & Automation

Microsoft AZ-400: Container CI/CD with Azure Container Registry

In this article
  1. Treat the registry as part of the delivery control plane
  2. Build once and identify the image immutably
  3. Separate continuous integration from environment promotion
  4. Prefer short-lived identity over embedded registry credentials
  5. Scan images before broad deployment
  6. Design networking for both build and runtime access
  7. Use retention and immutability to support rollback
  8. Deploy the digest with environment-specific configuration
  9. Operate the container supply chain as a system

A container pipeline is reliable only when the image becomes a controlled software artifact instead of a side effect of a build. Azure Container Registry provides a private registry for storing and distributing container images, while Azure Pipelines or GitHub Actions can build, test, scan, publish, and deploy them. For the current AZ-400 scope, the important design skill is not memorizing one YAML task. It is building an artifact flow in which source, image, security evidence, deployment, and runtime telemetry remain traceable to one another. Always verify assumptions.

The safest model is simple to state: build once, identify the image immutably, promote the same artifact through environments, authenticate without unnecessary long-lived credentials, scan before broad exposure, and record which digest is running where. The implementation can vary across App Service, Azure Kubernetes Service, Container Apps, virtual machines, or other targets, but the supply-chain principles remain consistent.

Treat the registry as part of the delivery control plane

A registry is not just remote disk space for images. It defines the boundary between software creation and software deployment. Build systems push approved artifacts into the registry. Deployment systems pull exact versions from it. Security systems inspect what is stored. Retention and access policy determine how long old versions remain available for rollback and who can publish or consume them.

Azure Container Registry supports private repositories and role-based access. Design permissions around actions such as push, pull, administration, and automated deployment rather than granting broad control to every pipeline identity. The pipeline that produces images does not necessarily need the same permissions as the production environment that only pulls them.

Teams new to containers sometimes focus on the Dockerfile while overlooking the registry lifecycle. Understanding container image fundamentals is useful, but enterprise CI/CD also requires artifact ownership, provenance, vulnerability handling, retention, and deployment traceability.

Repository organization is part of registry governance. Decide whether teams receive separate registries, separate repositories inside a shared registry, or another segmentation model. The answer should consider administrative ownership, network boundaries, geo-replication needs, quota, naming, and how security findings are routed. A giant shared registry can be simple initially but difficult to delegate cleanly later.

Build once and identify the image immutably

Azure Pipelines can build a Docker image and push it to Azure Container Registry as part of continuous integration. The critical design choice is how that image is identified later. Mutable tags such as latest are convenient for humans but weak as a deployment record because the tag can point to a different digest after another build.

Use a version tag that maps to the source change, build number, release version, or another controlled identifier, and preserve the digest produced by the registry. A deployment record should answer exactly which image content ran in production. That improves rollback because the team can redeploy a known digest instead of hoping an old tag still refers to the same bytes.

The discipline behind building Docker images correctly also matters for repeatability. Pin important base-image versions, minimize unnecessary layers, avoid copying secrets into the image, and make the build deterministic enough that a source change has a predictable effect on the artifact.

Base images deserve their own update process. An application can remain unchanged while its operating-system packages become vulnerable. Track which repositories depend on important base images, rebuild when the base changes, and make rebuild provenance visible. That prevents teams from assuming an old image is safe simply because application source has not changed.

Separate continuous integration from environment promotion

The build pipeline should prove that source can become a deployable image. It compiles code when necessary, runs unit tests, creates the image, performs security checks, and pushes the resulting artifact. The deployment pipeline then promotes that existing artifact to environments. Rebuilding the image for test, staging, and production creates multiple artifacts that may have the same label but different content.

This separation also lets teams apply different permissions. CI needs access to source, package feeds, build infrastructure, and the registry push operation. CD needs access to the registry pull path and target environments. Production deployment does not need authority to rewrite source or rebuild an artifact.

Azure Pipelines artifacts, environment records, and deployment jobs can preserve the relationship between a run and a target environment. The same principle applies in GitHub Actions with workflow runs and environments. The goal is a chain of evidence from commit to image digest to deployment.

Keep build metadata with the artifact. OCI labels, registry annotations, release records, or an external software bill of materials can identify source revision, build time, repository, pipeline run, and dependency information. During an incident, that metadata shortens the path from a running container back to the code and process that created it.

Prefer short-lived identity over embedded registry credentials

Registry authentication is a common place where otherwise good pipelines accumulate secrets. Avoid placing registry passwords or service-principal secrets directly in YAML. Azure service connections and workload identity federation can give automation short-lived access without requiring a long-lived secret to be stored and rotated.

Use separate identities for separate trust boundaries. The build pipeline can have push rights to the appropriate registry repositories. A cluster or application runtime can have pull rights. Administrative actions such as changing registry networking or policy should be held by a smaller platform role. Least privilege reduces what an attacker can do if a runner or pipeline is compromised.

AZ-104 operational knowledge helps here because identities, role assignments, managed identities, private endpoints, DNS, and network restrictions often determine whether a deployment can reach ACR safely.

Registry identities should be monitored as well as scoped. Unexpected push activity, failed authentication bursts, or image deletion outside the normal pipeline can indicate credential misuse or an operational mistake. Audit logs and platform monitoring should make registry administration part of the security review, not a blind spot behind the pipeline.

Scan images before broad deployment

Container images bundle application code, runtime components, operating-system packages, and dependencies. That makes them valuable scanning targets. Microsoft Defender for Cloud can assess supported container images in Azure Container Registry and surface vulnerability recommendations. The pipeline can also use separate software composition analysis and code-scanning tools before an image is published or promoted.

Scanning should produce an actionable policy, not only a dashboard. Decide which severity levels block release, how exploitability and workload exposure affect prioritization, who owns remediation, and how approved exceptions expire. A blanket “zero vulnerabilities” rule can become unusable, while no blocking threshold leaves serious findings disconnected from delivery decisions.

Repository scanning and image scanning answer different questions. GitHub Advanced Security for Azure DevOps can detect exposed secrets, vulnerable dependencies, and code issues in source. Registry vulnerability assessment evaluates what has actually been packaged into the image. The security design should connect both layers, especially for workloads where GH-500-style repository security controls are relevant.

Scanning cadence matters because vulnerability knowledge changes after an image is built. A release may have passed all checks on Monday and become affected by a newly disclosed vulnerability on Thursday. Registry and runtime scanning help teams reassess stored and running images without waiting for another source commit.

Design networking for both build and runtime access

A private registry can be protected with network controls, but those controls must still allow legitimate builders and deployment targets to reach it. Microsoft-hosted agents originate outside your private virtual network, while self-hosted agents can be placed inside controlled network boundaries. Private endpoints change DNS and routing requirements, so registry access should be tested from the actual pipeline execution environment.

Do not solve a connectivity problem by opening the registry broadly without understanding the consequence. If private access is required, build agent placement becomes part of the architecture. If public network access remains enabled, limit authentication and authorization so network reachability does not equal registry permission.

Deployment targets also need reliable pull connectivity. A cluster that cannot resolve or reach the private registry may fail only when it scales out or replaces a node, long after the original deployment appeared successful. Include image-pull validation in operational testing.

Private connectivity also needs a bootstrap plan. If a self-hosted build agent is created from infrastructure code but its initialization depends on pulling an image from the private registry it cannot yet resolve, the platform can deadlock. Document which foundational components must exist first and how DNS, firewall rules, and identity become available in the correct order.

Use registry scopes and repository naming to make automated cleanup safe. Cleanup logic should be able to distinguish ephemeral development images from releases that are still referenced by production or disaster-recovery environments. Deleting by age alone is risky when a rarely changed service can legitimately run an older digest for months.

Use retention and immutability to support rollback

Rollback depends on the previous artifact still existing. Aggressive cleanup can save storage but remove the exact image required during an incident. Retention policy should reflect release frequency, rollback windows, compliance needs, and the time required to rebuild an old version safely if necessary.

Protect release tags or digests from accidental overwrite where your process supports it. Mutable tags can be useful for development channels, but production references should be stable enough that a deployment record remains true weeks later. The organization should know which images are active, which are rollback candidates, and which can be deleted.

Keep provenance metadata outside the image as well. Build number, source commit, dependency lock state, test result, scan result, and deployment history can all help investigators understand an artifact without unpacking it manually.

Promotion metadata should distinguish environments from tags. Avoid inventing a new image copy such as myapp:staging and myapp:production if that process obscures whether the content changed. It is often clearer to keep one immutable digest and let environment deployment records say where that digest has been promoted.

Deploy the digest with environment-specific configuration

The image should contain the application, not production secrets or environment identity. Configuration that differs by environment belongs in platform configuration, secret stores, manifests, or deployment parameters. That allows the same image to move from staging to production without rebuilding it.

Kubernetes makes this distinction visible because the image reference is only one part of a deployment manifest. Environment variables, ConfigMaps, Secrets, service accounts, networking, resource limits, and probes define how the image runs. Understanding the relationship between pods and containers helps teams reason about why an image can be healthy in one environment and fail in another.

Database and messaging dependencies still need version compatibility. A container rollback cannot restore a schema that the new version changed destructively, and a newly published event format can outlive the container that emitted it. Artifact immutability helps only when stateful dependencies support the same recovery window.

Record environment deployment history and make rollback explicit. If a new digest fails health checks, the deployment process should know the prior known-good digest and how to restore it without searching a registry manually during an incident.

Disaster recovery for the registry should match the applications that depend on it. If a region fails and workloads move elsewhere, the recovery environment still needs access to required images. Geo-replication, secondary registries, export procedures, or guaranteed rebuild capability can all be valid, but the choice should be tested before an outage makes image availability a deployment blocker.

Operate the container supply chain as a system

Keep a controlled process for emergency image promotion. During a severe incident, teams may need to deploy an older known-good digest quickly. That path should still preserve authorization, traceability, and environment history rather than requiring an administrator to edit the workload manually in the portal.

Pipeline health is more than whether the last build turned green. Track build duration, image size trends, failed pushes, vulnerability findings, pull failures, deployment duration, rollback frequency, and runtime errors tied to a new digest. These signals expose both engineering inefficiency and supply-chain risk.

Standardize the repeatable parts through templates, reusable workflows, or shared tasks. The broader Azure DevOps toolchain becomes more valuable when teams do not reinvent authentication, tagging, scanning, and deployment logic in every repository.

Review the registry as the software estate grows. Repository naming, retention, permissions, network rules, scan coverage, and replication choices that worked for ten services may become fragile for hundreds. Platform teams should treat ACR conventions as a product with versioned standards and migration guidance rather than letting each repository evolve independently.

Finally, test the complete path from a clean agent. Cached Docker layers, credentials, and local base images can hide dependencies. A clean build verifies that the pipeline really can restore dependencies, authenticate, build, scan, push, and deploy using only the systems that the documented design says it needs.

That clean-build exercise is also a useful continuity test. If a hosted agent image changes or a self-hosted pool is rebuilt, the team should not discover undocumented local dependencies only when an urgent release is required.

A strong ACR pipeline therefore creates more than an image. It creates a trustworthy relationship among source control, automated tests, security evidence, immutable artifacts, controlled identity, environment promotion, and runtime feedback. When that relationship is preserved, containers become easier to deploy quickly without sacrificing the ability to explain exactly what reached production and why.

Filed under DevOps & Automation