Design and implement build and release pipelines
Design and implement a package management strategy
A package management strategy controls how code and dependencies are stored, versioned, and shared across a DevOps workflow. Azure Artifacts is the primary service for hosting packages, and it supports multiple package types including NuGet, npm, Maven, and Python. Teams decide whether to use public feeds from the internet or create private feeds that are only accessible within their organization. Private feeds give the team control over which package versions are approved, and they prevent unexpected changes when a public package is updated or removed. The strategy also includes deciding how upstream sources work: a feed can be configured to automatically cache packages from public registries, so builds still work even if the public registry is temporarily unavailable. Each package should follow semantic versioning so that consumers know whether a change is a patch, a minor update, or a breaking major release.
Design and implement a testing strategy for pipelines
Testing in pipelines catches problems early and prevents broken code from reaching production. A testing strategy layers different types of tests at different stages of the pipeline. Unit tests run first and check individual functions or methods in isolation, so they are fast and give immediate feedback. Integration tests run next and verify that multiple components work together, such as a web app calling a database. Functional tests check that the application behaves correctly from the user's perspective, and they often run against a deployed environment. Load tests measure how the system performs under stress and help find performance bottlenecks before they affect real users. The pipeline should fail and stop deployment if any test in the critical path fails. Teams also decide how much test coverage is enough, balancing the cost of writing tests against the risk of missing bugs. Test results are published to Azure DevOps so the team can track trends over time and identify flaky tests that need attention.
Design and implement pipelines
Pipelines automate the steps that turn source code into a deployed application. Azure Pipelines is the service that defines these steps as a series of jobs and tasks. A pipeline starts when a trigger event happens, such as a code push to a branch or a pull request being merged. The pipeline runs on a build agent, which can be a Microsoft-hosted agent that is maintained by Azure or a self-hosted agent that the team manages on their own infrastructure. The pipeline definition is stored as a YAML file in the repository, which keeps the build process versioned alongside the code. Each pipeline can have multiple stages, such as build, test, and deploy, and stages can run sequentially or in parallel depending on the dependencies between them. Variables and variable groups allow the same pipeline to work across different environments by changing values like connection strings or API keys without modifying the pipeline code itself.
Design and implement deployments
Deployments release the built application to target environments such as development, staging, and production. Azure Pipelines uses release pipelines or multi-stage YAML pipelines to manage deployments. A deployment strategy defines how the new version replaces the old version with minimal downtime. Blue-green deployment runs two identical environments: the current version (blue) serves live traffic while the new version (green) is deployed and tested, and then traffic is switched to green. Canary deployment sends a small percentage of users to the new version first, monitors for errors, and then gradually rolls out to everyone. Rolling deployment replaces instances one at a time so the application stays available throughout the update. Each deployment should include approval gates that require a human to sign off before the release moves to production, and automated gates that check health metrics before allowing the deployment to continue. If a deployment fails, the pipeline should support automatic rollback to the previous known-good version.
Design and implement infrastructure as code
Infrastructure as code (IaC) treats the provisioning of servers, networks, and other resources the same way developers treat application code. Instead of manually clicking through the Azure portal, the team writes configuration files that define the desired state of the infrastructure. Azure Resource Manager (ARM) templates use JSON to describe Azure resources and their dependencies, and they can be deployed repeatedly to create identical environments. Bicep is a newer language that compiles to ARM templates but uses a simpler syntax that is easier to read and write. Terraform is another option that works across multiple cloud providers and uses its own configuration language called HCL. The IaC files are stored in source control alongside the application code, so every change to the infrastructure goes through the same review and testing process. The pipeline runs the IaC deployment as part of the release, ensuring that the infrastructure matches the application version being deployed. State management is important: ARM templates are stateless and always apply the full definition, while Terraform tracks state in a backend file and only applies the difference between the current state and the desired state.
Maintain pipelines
Maintaining pipelines keeps the build and release process reliable and efficient over time. Pipelines need regular updates when dependencies change, such as updating the version of a build tool or replacing a deprecated task. Pipeline caching speeds up builds by storing frequently downloaded dependencies, so the agent does not have to download them from the internet on every run. Retention policies control how long pipeline runs, artifacts, and logs are kept, which prevents storage costs from growing indefinitely. Teams should monitor pipeline health by tracking metrics such as success rate, duration, and queue time, and they should investigate any sudden changes. Pipeline security includes restricting who can modify pipeline definitions, using service connections with minimal permissions, and scanning for secrets that might be accidentally committed to the repository. When a pipeline breaks, the team should fix it quickly because a broken pipeline blocks all future deployments. Regular reviews of the pipeline configuration help remove unused steps, consolidate duplicate tasks, and adopt new features that Azure Pipelines releases over time.