AZ-400 Practice Question: Design and implement build and release pipelines
Your organization uses a monorepo in Azure Repos containing multiple microservices. You need to design a build pipeline that only builds and tests the services that have changed in a given commit, to optimize build times. The pipeline must trigger on any push to any branch, but only the affected services should be built. You also need to ensure that dependent services are rebuilt if their dependencies change. The services are located in subdirectories: /services/serviceA, /services/serviceB, etc. Each service has a Dockerfile and a unit test project. You plan to use a script to determine which services changed. Which approach should you use to implement this pipeline?
Answer choices
Why each option matters
Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.
Correct answer & explanation
✓
Use a script step to determine which services changed, then output variables to dynamically create a job matrix or use the 'each' keyword to iterate over changed services.
Use a script to determine which services changed, then output variables to dynamically create a job matrix. This satisfies the requirement to only build affected services and handle dependency rebuilding if the script includes dependency detection. Option B is wrong because it requires a stage for every service upfront and is less dynamic. Option C is wrong because it does not optimize build times. Option D is wrong because it creates all jobs and uses complex conditions to skip unchanged services.
Answer analysis
Option-by-option breakdown
For each option: why learners choose it and why it is or isn't the right answer here.
- ✓
Use a script step to determine which services changed, then output variables to dynamically create a job matrix or use the 'each' keyword to iterate over changed services.
Why this is correct
A script step can run `git diff` against the previous commit or merge target to identify which services changed, then set output variables such as `ChangedServices=true,false`. The pipeline can later use these variables with YAML's `matrix` strategy or the `each` directive in template expressions to dynamically generate one job per changed service, ensuring only affected services are built and tested while keeping the pipeline fully data-driven and scalable.
- ✗
Create a multi-stage pipeline where each stage represents a service, and use a 'dependsOn' condition to run stages only if the corresponding service changed.
Why it's wrong here
Azure DevOps stages are statically defined at pipeline compile time, so you would have to create a separate stage for every service manually and then add `dependsOn` conditions that inspect file paths. This approach becomes unmaintainable as the number of services grows, and `dependsOn` alone cannot dynamically alter the set of stages based on which files changed—conditions must be written for each possible service, making it equivalent to hardcoding but with extra overhead.
- ✗
Create a single job that runs all unit tests for all services on every commit. Use caching to speed up the build.
Why it's wrong here
Running all unit tests for every service on each commit defeats the purpose of targeted builds in a monorepo. Even with caching, the pipeline still pays the cost of checking out the entire repository, compiling or loading all services, and executing their entire test suites; caching only speeds up repeated dependencies, not the computation itself, so overall CI times remain high and scale linearly with repository size.
- ✗
Create a job for each service that runs in parallel on every commit. Use conditions to skip jobs if the service has not changed, but the conditions would need to check every service, which is complex.
Why it's wrong here
This approach statically defines a job for every service, and though `conditions` can skip jobs when a service hasn't changed, the jobs are still instantiated, queued, and evaluated on each run. The condition expressions must enumerate every service's file paths and then be maintained as new services are added or paths change, causing pipeline bloat and unnecessary agent allocation overhead even for skipped jobs.
Go deeper
Related to this question
Learn chapter
Introduction to DevOps and Azure DevOps
Key term
Build pipeline
A build pipeline is an automated sequence of steps that compiles source code into a deployable artifact, running tests and checks along the way.
Key term
Branch
A branch is a pointer to a specific commit in a version control system that allows you to work on features or fixes in isolation from the main codebase.
About these practice questions
This AZ-400 question is part of Courseiva's 823-question bank — original exam-style content with full explanations and wrong-answer analysis, never real exam questions or exam dumps. Learn why practice questions differ from exam dumps →
JA
Written by Johnson Ajibi, MSc IT Security
Senior Network & Security Engineer · founder of Courseiva
This AZ-400 practice question is part of Courseiva's free Microsoft certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the AZ-400 exam.