EXAMTOPICS / TECHNOLOGY INSIGHTS

Microsoft AZ-400: Infrastructure as Code Pipelines

Infrastructure as code becomes operationally valuable when every proposed change can be reviewed, previewed, approved, applied, and reconciled through a delivery pipeline. For AZ-400, the important distinction is between authoring infrastructure and operating infrastructure changes safely at scale. Bicep and Terraform use different engines, but a strong pipeline gives both a predictable path from source control to production.

The administrative perspective in AZ-104 matters because the pipeline ultimately changes real Azure resources, identities, networks, and policy. The workflow should therefore protect credentials, produce a reviewable preview, separate planning from application, enforce environment controls, and detect drift after deployment rather than assuming a successful pipeline means the environment remains compliant forever.

Treat infrastructure code as a production change artifact

IaC repositories should use the same source-control discipline as application code: pull requests, reviewers, protected branches, automated validation, and traceable commits. Add path ownership for high-risk modules such as networking, IAM, policy, or shared landing-zone code so the right specialists review changes that can affect many subscriptions or resource groups. A configuration file can create public network exposure or tenant-wide permissions with fewer lines than an application feature, so infrastructure changes deserve deliberate ownership. Map each production subscription, resource group, or landing-zone component to a team that can approve and support changes after hours; orphaned infrastructure code is a long-term operational risk.

Keep reusable modules versioned and reviewed separately from environment composition. If every application team copies a networking or identity block into its own repository, security fixes become inconsistent. A governed module can encode defaults while still exposing the parameters teams genuinely need.

Validate before creating a cloud plan

The first pipeline stage should catch cheap defects: formatting, syntax, schema errors, linter findings, missing variables, invalid module versions, and policy violations that do not require cloud execution. Fast local-style checks give developers feedback before a service connection or provider call is needed.

Add security and policy-as-code checks for controls the organization can express deterministically, such as prohibited public exposure, missing encryption, disallowed regions, or excessive privilege. Do not turn every recommendation into a hard gate; blocking rules should map to requirements that have an owner and an exception process.

Use what-if and plan as reviewable change previews

Bicep and ARM deployments can use Azure what-if to preview resource changes, while Terraform plan compares configuration, state, and provider data to propose actions. These previews help reviewers distinguish creates, updates, replacements, and deletions before the pipeline changes production.

Treat the preview as evidence, not decoration. Summarize resource counts, replacements, deletions, public endpoint changes, role assignments, and policy exceptions in a form reviewers can consume quickly. Reviewers should not need to scan thousands of raw JSON lines to discover that a production database will be replaced. Save it with the pipeline run or pull request, highlight destructive actions, and review unexpected replacements carefully. A plan with hundreds of unrelated changes is difficult to trust; split unrelated infrastructure work so the person approving the change can understand its blast radius. When a provider or module upgrade creates widespread noise, isolate that upgrade from business changes so reviewers can distinguish mechanical differences from intentional architecture modifications.

Separate plan and apply without letting them diverge

A common pipeline pattern produces a reviewed plan, waits for approval, then applies that reviewed result. For Terraform, saved plans can help ensure the apply corresponds to what was inspected. For Bicep, teams should control the code revision, parameters, scope, and deployment environment so the final deployment does not silently differ from the reviewed what-if.

Long approval delays increase the chance that live infrastructure changes between preview and apply. Add an expiration or freshness policy to approved plans for high-risk environments. If the plan is stale, regenerate and reapprove it rather than pretending the old approval still describes the current environment. Revalidate when necessary and fail safely if the environment changed materially. The objective is not to freeze production; it is to prevent an approval from authorizing a different change than the reviewer saw.

Use environment checks for deployment authority

Repository merge rights should not automatically equal production deployment rights. Separate build, plan, and apply permissions, and require the production apply identity to be inaccessible from untrusted pull-request jobs. This limits the damage if a contributor modifies pipeline code in a branch that has not yet passed review. Azure Pipelines environments and checks can provide approval, branch control, business-hours, external-policy, or other gates before a deployment reaches a protected environment. Keep production service connections separate from lower environments and restrict who can use or administer them.

Approvals should answer a real risk question. Environment checks can also enforce branch, business-hours, external policy, or exclusive-lock conditions so two incompatible production changes do not run concurrently. Use these controls where the failure mode justifies them instead of making every deployment wait on every possible gate. A manual click adds little if the approver has no preview, change context, or health evidence. Present the IaC plan, ticket, affected resources, policy results, and rollback expectations together so approval becomes an informed decision rather than ritual.

Protect Terraform state and pipeline credentials

Terraform state maps code to real resources and may contain sensitive values. Keep separate state boundaries for environments or ownership domains where one state file would create excessive blast radius. A state operation should not require broad write access to unrelated production systems merely because they share one repository. Use a remote backend with encryption, access control, locking, and backup. Validate state-lock behavior during pipeline cancellation and agent failure because abandoned locks can delay recovery while missing locks can permit concurrent writers to corrupt assumptions about resource ownership. Pipeline identities should have the minimum Azure and backend permissions needed for the stage, and production credentials should not be exposed to pull-request jobs that execute untrusted code.

The practices in Terraform secret management remain relevant because secrets can appear in variables, outputs, plan files, state, and logs even when source files are clean. Prefer workload identity or managed federation to long-lived service-principal secrets when the platform and organization support it.

Promote patterns, not copied configuration drift

Environment promotion should keep the implementation pattern consistent while allowing intentional differences such as SKU, region, scale, or approved policy. Pin module and provider versions so a production deployment does not unexpectedly consume a newer dependency than the build validated in lower environments. Use parameter files, environment-specific variable sets, or composition layers instead of maintaining separate hand-edited copies of the same infrastructure definition.

If production code differs from test code in structural ways, lower environments provide weak evidence. Align module versions and pipeline logic, then isolate the differences that are genuinely required. The goal is to test the same deployment mechanism before it reaches the highest-risk environment.

Detect drift after the pipeline succeeds

Manual emergency changes, other automation, provider defaults, and resource self-modification can move live infrastructure away from the repository. Schedule drift checks outside deployment windows so the team can detect divergence even when no new code is being released. High-risk drift should create work that is tracked to closure, not only a dashboard warning. Schedule drift checks or configuration monitoring and decide whether discovered differences should be reverted or adopted into code. Successful deployment is only one point in the infrastructure lifecycle.

Connect drift findings to ownership and change records. A documented break-glass change is different from an unexplained firewall opening, but both need reconciliation. The automation and orchestration in IaC distinction between automation and orchestration is useful here: the deployment command is only one step in a broader operating process that includes review, monitoring, and correction.

Measure pipeline safety as well as speed

Track deployment failure rate, rollback frequency, drift age, approval delay, destructive-plan frequency, policy exceptions, and time from infrastructure change to validated completion. Add lead time for review and percentage of deployments that require manual repair. Those metrics expose whether the pipeline is genuinely automating safe change or simply moving manual work into a scripted wrapper. Delivery speed matters, but a pipeline that deploys quickly while creating manual repair work is not mature.

Review pipeline permissions, modules, provider versions, policy rules, and emergency paths periodically. Test a controlled rollback or redeployment path so the team knows how to recover when a change fails after partially creating resources. IaC recovery should be practiced before an incident, not invented while production is broken. Test how the pipeline handles partial deployment, provider timeouts, deleted state backends, and manually restored resources. Recovery steps should reconcile code, state, and live infrastructure instead of merely forcing another apply until the pipeline turns green. Preserve the incident trail. A strong IaC pipeline creates repeatable infrastructure while preserving human understanding of high-impact changes. Keep deployment logs and state history long enough to reconstruct what happened during an incident. If a pipeline applies several modules, record which module and scope failed so recovery can target the partial change rather than blindly rerunning the entire environment. It should make safe changes easy, unsafe changes visible, and recovery predictable.

Promote the reviewed plan artifact or an equivalently immutable change description through the approval path rather than recalculating intent after approval. State locking, provider version pinning, drift checks, and environment-specific policy gates reduce the chance that a production apply differs from what reviewers saw. When a pipeline must re-plan because inputs changed, treat that as a new change requiring fresh review instead of quietly applying a different result.