{"id":422,"date":"2026-04-14T00:13:12","date_gmt":"2026-04-14T00:13:12","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/azure-pipelines-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-developer-tools\/"},"modified":"2026-04-14T00:13:12","modified_gmt":"2026-04-14T00:13:12","slug":"azure-pipelines-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-developer-tools","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/azure-pipelines-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-developer-tools\/","title":{"rendered":"Azure Pipelines Tutorial: Architecture, Pricing, Use Cases, and Hands-On Guide for Developer Tools"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Category<\/h2>\n\n\n\n<p>Developer Tools<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introduction<\/h2>\n\n\n\n<p>Azure Pipelines is Microsoft\u2019s continuous integration and continuous delivery (CI\/CD) service in Azure DevOps. It automates building, testing, and delivering software so teams can ship changes reliably and repeatedly\u2014without manual steps.<\/p>\n\n\n\n<p>In simple terms: you connect your code repository, define how to build and test it, and Azure Pipelines runs those steps on agents (Microsoft-hosted or self-hosted). You get consistent builds, test results, and deployable artifacts every time a developer commits code or opens a pull request.<\/p>\n\n\n\n<p>Technically, Azure Pipelines is a pipeline orchestration service that executes jobs (scripts and tasks) on build agents, supports multi-stage workflows (build \u2192 test \u2192 deploy), integrates with Azure Repos\/GitHub\/other Git providers, and can deploy to many targets (Azure services, Kubernetes, VMs, on-prem environments). It provides identity-aware access controls, approvals, auditability, and integrations with the broader Azure ecosystem.<\/p>\n\n\n\n<p><strong>What problem it solves:<\/strong> turning code changes into validated, deployable outputs (and optionally deployments) in a repeatable, secure, and observable way\u2014reducing risk, speeding delivery, and standardizing engineering practices.<\/p>\n\n\n\n<blockquote>\n<p>Naming\/status note: <strong>Azure Pipelines<\/strong> is the current name and is actively supported as part of <strong>Azure DevOps Services<\/strong> (cloud\/SaaS) and <strong>Azure DevOps Server<\/strong> (self-hosted\/on-prem). This tutorial focuses primarily on <strong>Azure DevOps Services<\/strong> unless noted otherwise.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">2. What is Azure Pipelines?<\/h2>\n\n\n\n<p><strong>Official purpose:<\/strong> Azure Pipelines provides CI\/CD automation to build, test, and deploy code from version control to any target environment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Core capabilities<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Continuous integration (CI):<\/strong> Automatically build and test on commits and pull requests.<\/li>\n<li><strong>Continuous delivery\/deployment (CD):<\/strong> Promote artifacts across environments (dev\/test\/stage\/prod) with controls like approvals and checks.<\/li>\n<li><strong>Multi-platform execution:<\/strong> Run builds on Windows, Linux, and macOS agents (availability depends on agent type and Microsoft-hosted images).<\/li>\n<li><strong>Language\/tool support:<\/strong> Works with .NET, Java, Node.js, Python, Go, containers, and more via built-in tasks and scripts.<\/li>\n<li><strong>Artifacts and traceability:<\/strong> Publish artifacts, link work items, and keep logs for audit and troubleshooting.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Major components<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure DevOps organization<\/strong> \u2192 top-level container for projects, users, policies.<\/li>\n<li><strong>Project<\/strong> \u2192 contains repos, pipelines, artifacts, boards, etc.<\/li>\n<li><strong>Pipeline<\/strong> \u2192 the automated workflow definition (YAML or classic UI).<\/li>\n<li><strong>Stages \/ Jobs \/ Steps<\/strong> \u2192 structure of work to execute (conceptual even if created via classic editor).<\/li>\n<li><strong>Agents &amp; agent pools<\/strong><\/li>\n<li><strong>Microsoft-hosted agents:<\/strong> ephemeral agents provided by Microsoft.<\/li>\n<li><strong>Self-hosted agents:<\/strong> your own machines\/VMs\/runners in your network.<\/li>\n<li><strong>Service connections<\/strong> \u2192 secure connections from pipelines to external systems (e.g., Azure subscription, container registry).<\/li>\n<li><strong>Environments<\/strong> \u2192 logical deployment targets with checks\/approvals (commonly used in multi-stage pipelines).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Service type and scope<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Service type:<\/strong> Managed CI\/CD orchestration (SaaS) under Azure DevOps Services; also available for Azure DevOps Server (self-hosted).<\/li>\n<li><strong>Scope model:<\/strong> Typically <strong>organization \u2192 project \u2192 pipeline<\/strong>. Permissions and policies are applied at these scopes.<\/li>\n<li><strong>Regional\/global considerations:<\/strong> Azure DevOps Services is a globally available SaaS with organization-level data residency\/geo considerations (verify specifics in official docs for your org region). Agent execution location differs by <strong>Microsoft-hosted agent pool region<\/strong> and your <strong>self-hosted<\/strong> placement.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Fit in the Azure ecosystem<\/h3>\n\n\n\n<p>Azure Pipelines is a core part of <strong>Azure Developer Tools<\/strong> and integrates tightly with:\n&#8211; <strong>Azure Repos<\/strong> (Git hosting), <strong>Azure Artifacts<\/strong> (package feeds), <strong>Azure Boards<\/strong> (work tracking)\n&#8211; <strong>Azure Resource Manager<\/strong>, <strong>Azure CLI<\/strong>, and common Azure deployment targets (App Service, AKS, Functions, VMs, etc.)\n&#8211; <strong>Microsoft Entra ID (Azure AD)<\/strong> for identity and governance<\/p>\n\n\n\n<p>Official overview docs:<br\/>\nhttps:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/?view=azure-devops<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Why use Azure Pipelines?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Business reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Faster release cycles with less risk:<\/strong> Automated validation reduces regressions and speeds feedback.<\/li>\n<li><strong>Consistency and standardization:<\/strong> Shared pipelines and templates reduce \u201cworks on my machine\u201d issues.<\/li>\n<li><strong>Traceability:<\/strong> Logs, artifacts, approvals, and linked work items help audits and incident reviews.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technical reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Flexible execution model:<\/strong> Choose Microsoft-hosted for convenience or self-hosted for network access\/special tooling.<\/li>\n<li><strong>Broad integration surface:<\/strong> Built-in tasks plus scripts enable most build\/deploy workflows.<\/li>\n<li><strong>Multi-stage pipelines:<\/strong> Model environments and promotions with approvals and checks.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operational reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Repeatable deployments:<\/strong> Reduce manual runbooks.<\/li>\n<li><strong>Visibility:<\/strong> Central run history, test reporting, artifact retention, and pipeline analytics (capabilities vary; verify in official docs for your org).<\/li>\n<li><strong>Scales with team size:<\/strong> Agent pools and parallelism allow throughput increases.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/compliance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Granular permissions:<\/strong> Control who can edit pipelines, approve deployments, and manage service connections.<\/li>\n<li><strong>Secret handling:<\/strong> Use secret variables, variable groups, secure files, and integrations like Azure Key Vault (commonly used pattern).<\/li>\n<li><strong>Auditability:<\/strong> Azure DevOps provides auditing capabilities (verify configuration and availability in official docs).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scalability\/performance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Parallelism:<\/strong> Multiple jobs can run simultaneously with additional parallel job capacity.<\/li>\n<li><strong>Agent choice:<\/strong> Scale self-hosted agents with VM scale sets\/containers (architecture-dependent).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should choose Azure Pipelines<\/h3>\n\n\n\n<p>Choose Azure Pipelines when:\n&#8211; You already use <strong>Azure DevOps<\/strong> (Repos\/Boards\/Artifacts) and want an integrated CI\/CD platform.\n&#8211; You need <strong>hybrid<\/strong> builds\/deployments that access <strong>private networks<\/strong> (self-hosted agents).\n&#8211; You want strong Azure-native deployment patterns and enterprise governance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should not choose Azure Pipelines<\/h3>\n\n\n\n<p>Consider alternatives when:\n&#8211; Your engineering workflow is standardized on <strong>GitHub Actions<\/strong> and you don\u2019t need Azure DevOps features.\n&#8211; You require a fully self-managed pipeline engine with deep customization and plugin ecosystems (e.g., Jenkins) and accept operational overhead.\n&#8211; You must run CI\/CD entirely inside a disconnected environment where Azure DevOps Services cannot be used (then consider Azure DevOps Server or self-managed tools).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Where is Azure Pipelines used?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Industries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Software\/SaaS, finance, healthcare, retail, manufacturing, telecom, public sector\u2014anywhere repeatable builds and controlled releases matter.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Team types<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DevOps and platform engineering teams standardizing delivery<\/li>\n<li>Product teams delivering microservices and front ends<\/li>\n<li>SRE\/operations teams automating infrastructure and release processes<\/li>\n<li>Regulated industry teams requiring approvals and audit trails<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Workloads<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>.NET applications (common), Java services, Node.js APIs, Python services<\/li>\n<li>Containerized microservices and Kubernetes workloads<\/li>\n<li>Infrastructure as Code (IaC) deployments (Bicep\/Terraform\u2014verify your org\u2019s standards)<\/li>\n<li>Mobile apps (agent\/tooling dependent; verify supported macOS builds if needed)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Architectures<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Monoliths and microservices<\/li>\n<li>Multi-repo or mono-repo approaches<\/li>\n<li>GitFlow, trunk-based development, release branches with environments<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world deployment contexts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Deploying to Azure App Service\/Functions\/AKS<\/li>\n<li>Deploying to on-prem IIS\/VMs via self-hosted agents<\/li>\n<li>Building containers and pushing to registries (ACR or others)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Production vs dev\/test usage<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Dev\/test:<\/strong> fast feedback, PR validation, ephemeral environments<\/li>\n<li><strong>Production:<\/strong> gated releases, approvals, environment checks, formal change management integrations<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Top Use Cases and Scenarios<\/h2>\n\n\n\n<p>Below are realistic, commonly implemented scenarios with Azure Pipelines.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Pull request validation (CI)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> PRs merge with failing tests or broken builds.<\/li>\n<li><strong>Why Azure Pipelines fits:<\/strong> PR triggers run builds\/tests automatically and report status back to the PR.<\/li>\n<li><strong>Example:<\/strong> Every PR to <code>main<\/code> runs unit tests and blocks merge on failure.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) Multi-stage promotion (dev \u2192 test \u2192 prod)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Manual promotions cause drift and inconsistent releases.<\/li>\n<li><strong>Why it fits:<\/strong> Multi-stage pipelines model environments, approvals, and artifact promotion.<\/li>\n<li><strong>Example:<\/strong> Build once, deploy the same artifact to dev, then promote to prod after approval.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Build and publish deployable artifacts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Teams can\u2019t reproduce builds or don\u2019t know what was deployed.<\/li>\n<li><strong>Why it fits:<\/strong> Pipeline artifacts\/build artifacts provide versioned outputs tied to a run.<\/li>\n<li><strong>Example:<\/strong> Publish a ZIP\/package and store it with retention policies.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Container CI (build image + scan + push)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Container images are built inconsistently and lack traceability.<\/li>\n<li><strong>Why it fits:<\/strong> Pipelines can build, run tests, run security scans (tool-dependent), and push to a registry.<\/li>\n<li><strong>Example:<\/strong> Build and tag images with commit SHA, push to Azure Container Registry.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Infrastructure as Code (IaC) validation and deployment<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Infrastructure changes break environments.<\/li>\n<li><strong>Why it fits:<\/strong> Run lint\/plan\/what-if checks, then deploy with approvals.<\/li>\n<li><strong>Example:<\/strong> Run an ARM\/Bicep \u201cwhat-if\u201d on PR and apply only after approval.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6) Deploy to private networks using self-hosted agents<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Microsoft-hosted agents can\u2019t reach private endpoints\/on-prem.<\/li>\n<li><strong>Why it fits:<\/strong> Self-hosted agents run inside your network with outbound-only connectivity to Azure DevOps.<\/li>\n<li><strong>Example:<\/strong> Deploy to an on-prem SQL Server or internal Kubernetes cluster.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) Scheduled builds (nightly regression)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Regressions are discovered late.<\/li>\n<li><strong>Why it fits:<\/strong> Scheduled triggers run nightly or weekly test suites.<\/li>\n<li><strong>Example:<\/strong> Nightly integration tests against a staging environment.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">8) Release orchestration with approvals and checks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> No governance over production deployments.<\/li>\n<li><strong>Why it fits:<\/strong> Approvals and checks can enforce change control.<\/li>\n<li><strong>Example:<\/strong> Require security review approval before production deployment stage.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9) Multi-repo dependency builds<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Services depend on shared libraries and need coordinated builds.<\/li>\n<li><strong>Why it fits:<\/strong> Pipelines can reference multiple repos and trigger dependencies (implementation varies; verify best approach in docs).<\/li>\n<li><strong>Example:<\/strong> Build shared library, publish package, downstream service consumes it.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">10) Cross-platform builds (Windows + Linux)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Builds only validated on one OS.<\/li>\n<li><strong>Why it fits:<\/strong> Run jobs on different agent OS images and compare results.<\/li>\n<li><strong>Example:<\/strong> Test a .NET library on Windows and Linux.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">11) Security and compliance reporting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Teams need auditable release evidence.<\/li>\n<li><strong>Why it fits:<\/strong> Pipeline run logs, artifact traceability, and approvals form evidence.<\/li>\n<li><strong>Example:<\/strong> Export run history for audit and link to work items.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">12) Monorepo selective builds<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Every commit triggers expensive builds for unrelated components.<\/li>\n<li><strong>Why it fits:<\/strong> Use path filters\/conditional jobs (capabilities depend on YAML\/classic features; verify in docs).<\/li>\n<li><strong>Example:<\/strong> Only build the <code>src\/api<\/code> folder when it changes.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Core Features<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1) YAML pipelines and classic pipelines<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Define pipelines as code (YAML) or configure via UI (classic editor).<\/li>\n<li><strong>Why it matters:<\/strong> YAML enables versioning and code review; classic can be simpler for beginners or legacy teams.<\/li>\n<li><strong>Practical benefit:<\/strong> Repeatable pipeline definitions, easier collaboration.<\/li>\n<li><strong>Caveat:<\/strong> Microsoft generally recommends YAML for modern workflows; classic remains supported but may not expose every newer feature equally. Verify current guidance in docs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) Microsoft-hosted and self-hosted agents<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Executes pipeline jobs on hosted VMs\/containers (Microsoft-hosted) or your infrastructure (self-hosted).<\/li>\n<li><strong>Why it matters:<\/strong> Choice impacts cost, performance, and network access.<\/li>\n<li><strong>Practical benefit:<\/strong> Hosted = minimal ops; self-hosted = access private resources, custom tools, predictable performance.<\/li>\n<li><strong>Caveat:<\/strong> Microsoft-hosted agents are ephemeral with some restrictions (no inbound connectivity, limited customization). Self-hosted agents require patching, scaling, and securing.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Parallel jobs and scalability controls<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Run multiple jobs concurrently across agent pools.<\/li>\n<li><strong>Why it matters:<\/strong> CI speed and throughput depend on parallelism.<\/li>\n<li><strong>Practical benefit:<\/strong> Faster feedback by splitting tests\/builds.<\/li>\n<li><strong>Caveat:<\/strong> Parallelism is a licensing\/capacity dimension (see pricing section); self-hosted scaling is your responsibility.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Built-in tasks and extensibility<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Provides a marketplace of tasks and built-in steps for building, testing, packaging, deploying, and scripting.<\/li>\n<li><strong>Why it matters:<\/strong> Reduces custom scripting.<\/li>\n<li><strong>Practical benefit:<\/strong> Faster pipeline authoring and standardization.<\/li>\n<li><strong>Caveat:<\/strong> Marketplace extensions introduce supply-chain risk; vet publishers and versions.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Triggers (CI, PR, scheduled, and more)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Automatically starts runs based on repo events or schedules.<\/li>\n<li><strong>Why it matters:<\/strong> Ensures validation happens consistently.<\/li>\n<li><strong>Practical benefit:<\/strong> PR validation and scheduled regression builds.<\/li>\n<li><strong>Caveat:<\/strong> Trigger behavior differs between YAML and classic; verify exact trigger support for your pipeline type.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6) Artifacts (Pipeline artifacts \/ build artifacts)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Stores outputs from a run (packages, zips, binaries) for download and deployment.<\/li>\n<li><strong>Why it matters:<\/strong> Enables \u201cbuild once, deploy many\u201d and traceability.<\/li>\n<li><strong>Practical benefit:<\/strong> Promotions use identical artifacts across environments.<\/li>\n<li><strong>Caveat:<\/strong> Artifact retention and storage quotas\/limits apply; verify org settings.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) Environments, approvals, and checks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Model deployment targets and enforce controls before deployments.<\/li>\n<li><strong>Why it matters:<\/strong> Governance and safe releases.<\/li>\n<li><strong>Practical benefit:<\/strong> Manual approvals, business hours checks, or other controls (depending on your setup).<\/li>\n<li><strong>Caveat:<\/strong> Some checks require specific configuration and permissions; verify per environment.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">8) Variable groups, secret variables, and secure files<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Centralize configuration, store secrets (as secret variables), and manage secure files (certs, provisioning profiles).<\/li>\n<li><strong>Why it matters:<\/strong> Keeps sensitive data out of source control.<\/li>\n<li><strong>Practical benefit:<\/strong> Reuse config across pipelines safely.<\/li>\n<li><strong>Caveat:<\/strong> Secrets still require careful access control; avoid exposing them in logs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9) Service connections (Azure, containers, Kubernetes, etc.)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Defines authenticated connections to external services.<\/li>\n<li><strong>Why it matters:<\/strong> Enables deployments without embedding credentials in code.<\/li>\n<li><strong>Practical benefit:<\/strong> Central governance of credentials and scope.<\/li>\n<li><strong>Caveat:<\/strong> Mis-scoped service connections are a common security issue; use least privilege.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">10) Test reporting and code coverage publishing<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Publishes test results and optionally code coverage to the pipeline run summary.<\/li>\n<li><strong>Why it matters:<\/strong> Fast feedback, quality gates, and trends.<\/li>\n<li><strong>Practical benefit:<\/strong> Easy visibility into failures.<\/li>\n<li><strong>Caveat:<\/strong> Exact formats supported depend on test framework and tasks used.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">11) Templates and reuse (primarily YAML)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Share pipeline building blocks across repos.<\/li>\n<li><strong>Why it matters:<\/strong> Standardization and maintainability.<\/li>\n<li><strong>Practical benefit:<\/strong> Centralized best practices at scale.<\/li>\n<li><strong>Caveat:<\/strong> Template governance requires versioning strategy and change control.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">12) Integration with Azure DevOps suite<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Links pipelines with Boards, Repos, Artifacts, dashboards, and permissions.<\/li>\n<li><strong>Why it matters:<\/strong> End-to-end DevOps workflow in one platform.<\/li>\n<li><strong>Practical benefit:<\/strong> Traceability from work item \u2192 commit \u2192 build \u2192 deployment.<\/li>\n<li><strong>Caveat:<\/strong> Cross-project and cross-org traceability needs explicit configuration.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Architecture and How It Works<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">High-level service architecture<\/h3>\n\n\n\n<p>Azure Pipelines consists of:\n&#8211; <strong>Control plane (Azure DevOps Services):<\/strong> Stores pipeline definitions, queues jobs, manages permissions, logs, and artifacts.\n&#8211; <strong>Execution plane (agents):<\/strong> Runs your pipeline jobs. Agents poll Azure DevOps for queued jobs and execute steps.\n&#8211; <strong>Integrations:<\/strong> Repos, artifact storage, test reporting, and deployment targets.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Request\/data\/control flow (typical CI run)<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Developer pushes code to a repo (Azure Repos Git or external Git).<\/li>\n<li>A trigger starts a pipeline run.<\/li>\n<li>Azure DevOps queues a job to an agent pool.<\/li>\n<li>An agent picks up the job, checks out code, runs tasks\/scripts.<\/li>\n<li>Agent streams logs back to Azure DevOps.<\/li>\n<li>Outputs (artifacts\/test results) are published to Azure DevOps storage.<\/li>\n<li>Optional: downstream stages deploy artifacts to environments.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Integrations with related services<\/h3>\n\n\n\n<p>Common integrations include:\n&#8211; <strong>Azure Repos \/ GitHub:<\/strong> source triggers, PR validation.\n&#8211; <strong>Azure Artifacts:<\/strong> publish and consume packages (NuGet, npm, Maven, etc.).\n&#8211; <strong>Azure Key Vault:<\/strong> retrieve secrets at run time (commonly via variable groups\/tasks\u2014verify current recommended approach).\n&#8211; <strong>Azure Resource Manager \/ Azure CLI:<\/strong> deploy infrastructure and apps.\n&#8211; <strong>Container registries (ACR\/Docker Hub):<\/strong> build and push images.\n&#8211; <strong>Kubernetes (AKS\/on-prem):<\/strong> deploy manifests\/Helm.\n&#8211; <strong>Microsoft Entra ID:<\/strong> identity and access governance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dependency services<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A Git repository (Azure Repos or external)<\/li>\n<li>Agents (Microsoft-hosted or self-hosted)<\/li>\n<li>Optional: Azure subscription and service connections for deployments<\/li>\n<li>Optional: artifact\/package feeds<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/authentication model (conceptual)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Users<\/strong> authenticate via Entra ID\/Microsoft accounts into Azure DevOps.<\/li>\n<li><strong>Pipelines<\/strong> access resources through:<\/li>\n<li><strong>Service connections<\/strong> (service principal, federated credentials, or other auth methods\u2014verify the current recommended authentication method in official docs)<\/li>\n<li><strong>Pipeline identities<\/strong> and permissions within Azure DevOps<\/li>\n<li><strong>Secrets<\/strong> stored as secret variables\/variable groups and accessed at runtime<\/li>\n<li><strong>Agents<\/strong> connect to Azure DevOps over HTTPS and use agent registration tokens\/credentials (implementation differs by agent type and setup).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Networking model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Microsoft-hosted agent:<\/strong> runs in Microsoft-managed network; reaches public endpoints; cannot directly access your private VNet unless you expose endpoints publicly (not recommended) or use alternative patterns.<\/li>\n<li><strong>Self-hosted agent:<\/strong> placed inside your network\/VNet; makes <strong>outbound<\/strong> connections to Azure DevOps; can reach private resources directly.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Monitoring\/logging\/governance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Run logs:<\/strong> full step-by-step logs per job, downloadable.<\/li>\n<li><strong>Test results:<\/strong> reported to the run summary when published.<\/li>\n<li><strong>Auditing:<\/strong> Azure DevOps provides audit logs for key events (verify availability and retention).<\/li>\n<li><strong>Governance:<\/strong> use branch policies, required reviews, restricted pipeline edits, and protected environments.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Simple architecture diagram (Mermaid)<\/h3>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart LR\n  Dev[Developer] --&gt;|Push\/PR| Repo[Git Repo&lt;br\/&gt;(Azure Repos or GitHub)]\n  Repo --&gt;|Trigger| ADO[Azure DevOps&lt;br\/&gt;Azure Pipelines]\n  ADO --&gt;|Queue job| Pool[Agent Pool]\n  Pool --&gt; Agent[Agent&lt;br\/&gt;(Microsoft-hosted or self-hosted)]\n  Agent --&gt;|Build\/Test| Agent\n  Agent --&gt;|Publish logs\/results| ADO\n  Agent --&gt;|Publish artifact| Artifacts[Pipeline\/Build Artifacts]\n  Artifacts --&gt; Consumer[Download or Deploy]\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Production-style architecture diagram (Mermaid)<\/h3>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart TB\n  subgraph Org[Azure DevOps Organization]\n    subgraph Proj[Project]\n      Repos[Azure Repos]\n      Pipelines[Azure Pipelines]\n      Envs[Environments&lt;br\/&gt;Dev\/Test\/Prod]\n      Artif[Artifacts Storage]\n      Sec[Service Connections&lt;br\/&gt;+ Variable Groups]\n    end\n  end\n\n  Devs[Developers] --&gt;|Commit\/PR| Repos\n  Repos --&gt;|CI Trigger| Pipelines\n\n  subgraph Agents[Execution]\n    Hosted[Microsoft-hosted Agents]\n    Self[Self-hosted Agents&lt;br\/&gt;in VNet\/on-prem]\n  end\n\n  Pipelines --&gt;|Jobs| Hosted\n  Pipelines --&gt;|Jobs| Self\n\n  Hosted --&gt;|Build\/Test| Hosted\n  Self --&gt;|Build\/Test\/Deploy| Self\n\n  Hosted --&gt;|Publish| Artif\n  Self --&gt;|Publish| Artif\n\n  Pipelines --&gt;|Deploy stages| Envs\n  Envs --&gt;|Controlled by approvals\/checks| Envs\n\n  Sec --&gt; Pipelines\n\n  subgraph Targets[Deployment Targets]\n    Azure[Azure Services&lt;br\/&gt;(App Service\/AKS\/Functions)]\n    OnPrem[On-prem\/Private Services]\n  end\n\n  Envs --&gt; Azure\n  Envs --&gt; OnPrem\n  Self --&gt;|Private access| OnPrem\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Prerequisites<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Account\/subscription\/project requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An <strong>Azure DevOps organization<\/strong> (Azure DevOps Services): https:\/\/dev.azure.com\/<\/li>\n<li>An <strong>Azure DevOps project<\/strong> where you can create repos and pipelines<\/li>\n<li>Optional: an <strong>Azure subscription<\/strong> if you will deploy to Azure resources<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Permissions \/ IAM<\/h3>\n\n\n\n<p>At minimum, you typically need:\n&#8211; Permission to <strong>create and edit pipelines<\/strong> in the project\n&#8211; Permission to <strong>queue builds<\/strong>\n&#8211; If using Azure Repos: permission to <strong>read\/commit<\/strong> to the repository\n&#8211; If deploying: permission to <strong>create\/manage service connections<\/strong> (or use an existing approved service connection)<\/p>\n\n\n\n<p>Exact permission names vary by Azure DevOps security model (project-level groups like Project Administrators, Build Administrators, etc.). Verify in official docs:\nhttps:\/\/learn.microsoft.com\/azure\/devops\/organizations\/security\/?view=azure-devops<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Billing requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure DevOps Services may require a billing setup depending on your organization, parallel jobs usage, and whether you purchase additional capacity.<\/li>\n<li>If deploying to Azure resources, you need an Azure subscription with a payment method.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">CLI\/SDK\/tools (for this lab)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Git: https:\/\/git-scm.com\/downloads<\/li>\n<li>.NET SDK (for the sample app): https:\/\/dotnet.microsoft.com\/download<\/li>\n<li>A code editor (VS Code recommended): https:\/\/code.visualstudio.com\/<\/li>\n<\/ul>\n\n\n\n<p>Optional tools (not required for the classic UI lab):\n&#8211; Azure CLI: https:\/\/learn.microsoft.com\/cli\/azure\/install-azure-cli\n&#8211; Azure DevOps CLI extension: https:\/\/learn.microsoft.com\/azure\/devops\/cli\/?view=azure-devops<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Region availability<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure DevOps Services is SaaS; availability is global, but your organization\u2019s region\/geo may matter for compliance and data residency. Verify in official docs for your org.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quotas\/limits (high-level)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Parallel job limits depend on purchased\/free capacity.<\/li>\n<li>Retention limits apply to logs and artifacts (org settings).<\/li>\n<li>Microsoft-hosted agent timeouts and resource constraints apply.\nBecause limits change, verify current limits in official docs:\nhttps:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/agents\/hosted?view=azure-devops<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisite services<\/h3>\n\n\n\n<p>For the core CI lab in this article:\n&#8211; Azure DevOps Services + Azure Repos (or any connected Git repo)\nNo Azure resources are required unless you choose to extend into deployments.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Pricing \/ Cost<\/h2>\n\n\n\n<p>Azure Pipelines pricing is tied to <strong>Azure DevOps Services<\/strong> licensing and is primarily based on <strong>parallel jobs<\/strong> and agent type.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing dimensions (what you pay for)<\/h3>\n\n\n\n<p>Common pricing dimensions include:\n&#8211; <strong>Microsoft-hosted parallel jobs:<\/strong> Capacity to run jobs concurrently on Microsoft-hosted agents (time\/minutes and concurrency rules can apply\u2014verify current model).\n&#8211; <strong>Self-hosted parallel jobs:<\/strong> Concurrency capacity for self-hosted agents (you provide the compute).\n&#8211; <strong>Additional Azure DevOps users\/features:<\/strong> Azure DevOps has separate user licensing considerations (Basic, Basic + Test Plans, etc.), depending on your org needs.<\/p>\n\n\n\n<p>Official pricing page (verify current details):<br\/>\nhttps:\/\/azure.microsoft.com\/pricing\/details\/devops\/azure-devops-services\/<\/p>\n\n\n\n<p>Official licensing\/concurrency guidance (verify current details):<br\/>\nhttps:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/licensing\/concurrent-jobs?view=azure-devops<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Free tier (what\u2019s commonly available)<\/h3>\n\n\n\n<p>Azure Pipelines typically includes some free capacity (often at least limited parallel job access), and <strong>public\/open-source projects<\/strong> have special considerations. Because free-tier details can change, confirm in:\n&#8211; Pricing page above\n&#8211; Concurrency jobs documentation above<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cost drivers<\/h3>\n\n\n\n<p>Direct and indirect drivers:\n&#8211; <strong>Number of parallel jobs<\/strong> (how many builds you want running at once)\n&#8211; <strong>Build frequency and duration<\/strong> (long tests, slow restores, large repos)\n&#8211; <strong>Agent type<\/strong>\n  &#8211; Microsoft-hosted: you pay for hosted capacity per pricing model\n  &#8211; Self-hosted: you pay for the underlying compute (VMs), storage, and maintenance\n&#8211; <strong>Artifact storage and retention<\/strong> (large artifacts + long retention)\n&#8211; <strong>Network egress<\/strong> (especially self-hosted agents downloading dependencies from the internet or pushing artifacts to external systems)\n&#8211; <strong>Third-party tools<\/strong> (security scanners, SaaS integrations, marketplace extensions)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hidden or indirect costs to watch<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Self-hosted agent operations:<\/strong> patching, scaling, backup, monitoring, incident response<\/li>\n<li><strong>Build cache misses:<\/strong> repeated dependency downloads (NuGet\/npm\/Maven) increase runtime and bandwidth<\/li>\n<li><strong>Over-retention:<\/strong> keeping artifacts\/logs forever can cause storage growth (subject to org limits)<\/li>\n<li><strong>Secret sprawl:<\/strong> unmanaged secrets can lead to security incidents with real cost<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network\/data transfer implications<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Microsoft-hosted agents pull source and dependencies over the public internet.<\/li>\n<li>Self-hosted agents in Azure may incur:<\/li>\n<li>Egress to the internet for dependency downloads<\/li>\n<li>Inter-region traffic if your resources are in different regions<\/li>\n<li>Deployments to Azure are typically internal to Azure but still can cross regions and boundaries depending on architecture.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How to optimize cost (practical)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Right-size parallelism:<\/strong> Start with minimal concurrency and increase as bottlenecks appear.<\/li>\n<li><strong>Shorten pipeline duration:<\/strong> split test suites, use incremental builds, avoid unnecessary steps.<\/li>\n<li><strong>Use caching where appropriate:<\/strong> pipeline caching for dependencies can reduce repeated downloads (feature availability depends on pipeline type and configuration; verify in docs).<\/li>\n<li><strong>Reduce artifact size:<\/strong> publish only what you need; compress; avoid publishing build intermediates.<\/li>\n<li><strong>Set retention policies:<\/strong> keep fewer runs\/artifacts for feature branches.<\/li>\n<li><strong>Prefer self-hosted for private network access<\/strong> when Microsoft-hosted would require insecure exposure\u2014cost can be lower at scale, but ops overhead increases.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Example low-cost starter estimate (no fabricated numbers)<\/h3>\n\n\n\n<p>A low-cost starter setup commonly looks like:\n&#8211; 1 pipeline for CI\n&#8211; Use included\/free parallel job capacity (if available for your org)\n&#8211; Keep artifact retention short (e.g., days\/weeks)\n&#8211; Minimal external integrations<\/p>\n\n\n\n<p>Because Microsoft\u2019s free minutes\/parallel job entitlements and paid tiers can change, use:\n&#8211; Azure DevOps pricing page: https:\/\/azure.microsoft.com\/pricing\/details\/devops\/azure-devops-services\/\n&#8211; Azure Pricing Calculator: https:\/\/azure.microsoft.com\/pricing\/calculator\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example production cost considerations<\/h3>\n\n\n\n<p>For production, plan for:\n&#8211; Multiple teams \u2192 multiple pipelines and increased concurrency needs\n&#8211; Separate pipelines for PR validation, main branch CI, and deployments\n&#8211; Self-hosted agents for private deployments (cost = VM + storage + ops)\n&#8211; Longer retention for audit\/compliance (more storage)\n&#8211; Security scanning steps (longer runtime, possible third-party licensing)<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">10. Step-by-Step Hands-On Tutorial<\/h2>\n\n\n\n<p>This lab creates a real CI pipeline using <strong>Azure Pipelines<\/strong> with the <strong>classic editor<\/strong> (UI-based). YAML pipelines are widely used in production, but this approach is fully executable while keeping the tutorial copy\/paste-friendly without embedding pipeline-definition files.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Objective<\/h3>\n\n\n\n<p>Build and test a small .NET application on every commit, publish test results, and publish a build artifact using <strong>Azure Pipelines<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab Overview<\/h3>\n\n\n\n<p>You will:\n1. Create an Azure DevOps project and Git repository.\n2. Create a simple .NET solution locally and push it to Azure Repos.\n3. Create a classic Azure Pipeline (build pipeline) using Microsoft-hosted agents.\n4. Configure tasks: install .NET SDK, restore, build, test, publish artifacts.\n5. Enable CI trigger.\n6. Run and validate results.\n7. Clean up resources.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Expected cost<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>For many orgs, this lab can run within included\/free Azure Pipelines capacity. If your org has no free hosted capacity remaining, you may need to enable billing or use a self-hosted agent. Always verify your org\u2019s parallel job availability.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Create an Azure DevOps organization and project<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open Azure DevOps: https:\/\/dev.azure.com\/<\/li>\n<li>Sign in with your Microsoft account or your organization account.<\/li>\n<li>Create an <strong>Organization<\/strong> (if you don\u2019t already have one).<\/li>\n<li>Create a <strong>New Project<\/strong>:\n   &#8211; Project name: <code>pipelines-lab<\/code>\n   &#8211; Visibility: Private (recommended for general lab work)<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> You land in the new project overview page and can access <strong>Repos<\/strong> and <strong>Pipelines<\/strong> from the left navigation.<\/p>\n\n\n\n<p><strong>Verification:<\/strong>\n&#8211; Go to <strong>Project settings<\/strong> \u2192 confirm you can see settings (if not, you may lack admin permissions).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Create a repo and push a sample .NET app<\/h3>\n\n\n\n<p>You\u2019ll create a minimal app and unit test locally, then push to Azure Repos.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.1 Create the repo in Azure Repos<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In the project, go to <strong>Repos<\/strong> \u2192 <strong>Files<\/strong>.<\/li>\n<li>If prompted, initialize the repo with a README (optional but convenient).<\/li>\n<\/ol>\n\n\n\n<p>Copy the clone URL:\n&#8211; Repos \u2192 Clone \u2192 copy the HTTPS URL.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.2 Create the app locally<\/h4>\n\n\n\n<p>On your machine:<\/p>\n\n\n\n<pre><code class=\"language-bash\">mkdir azure-pipelines-lab\ncd azure-pipelines-lab\n\ndotnet new sln -n PipelinesLab\n\ndotnet new classlib -n PipelinesLab.Core\ndotnet new xunit -n PipelinesLab.Tests\n\ndotnet sln PipelinesLab.sln add PipelinesLab.Core\/PipelinesLab.Core.csproj\ndotnet sln PipelinesLab.sln add PipelinesLab.Tests\/PipelinesLab.Tests.csproj\n\ndotnet add PipelinesLab.Tests\/PipelinesLab.Tests.csproj reference PipelinesLab.Core\/PipelinesLab.Core.csproj\n<\/code><\/pre>\n\n\n\n<p>Add a small piece of code to test.<\/p>\n\n\n\n<p>Create a file <code>PipelinesLab.Core\/Calculator.cs<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-csharp\">namespace PipelinesLab.Core;\n\npublic static class Calculator\n{\n    public static int Add(int a, int b) =&gt; a + b;\n}\n<\/code><\/pre>\n\n\n\n<p>Edit the generated test file (for example, <code>PipelinesLab.Tests\/UnitTest1.cs<\/code>) to:<\/p>\n\n\n\n<pre><code class=\"language-csharp\">using PipelinesLab.Core;\nusing Xunit;\n\nnamespace PipelinesLab.Tests;\n\npublic class UnitTest1\n{\n    [Fact]\n    public void Add_Works()\n    {\n        Assert.Equal(5, Calculator.Add(2, 3));\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>Run tests locally:<\/p>\n\n\n\n<pre><code class=\"language-bash\">dotnet test\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> Tests pass locally.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.3 Push to Azure Repos<\/h4>\n\n\n\n<p>Initialize git and push:<\/p>\n\n\n\n<pre><code class=\"language-bash\">git init\ngit add .\ngit commit -m \"Initial commit: .NET solution with tests\"\n<\/code><\/pre>\n\n\n\n<p>Add your Azure Repos remote (use the HTTPS clone URL you copied):<\/p>\n\n\n\n<pre><code class=\"language-bash\">git remote add origin &lt;YOUR_AZURE_REPOS_HTTPS_URL&gt;\ngit branch -M main\ngit push -u origin main\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> Code appears in <strong>Repos<\/strong> in the Azure DevOps project.<\/p>\n\n\n\n<p><strong>Verification:<\/strong>\n&#8211; In Azure DevOps \u2192 <strong>Repos<\/strong> \u2192 browse files and confirm <code>PipelinesLab.sln<\/code> exists.<\/p>\n\n\n\n<p><strong>Common error and fix:<\/strong>\n&#8211; If authentication fails, use Git Credential Manager and sign in, or create a PAT (Personal Access Token) per official guidance:\n  https:\/\/learn.microsoft.com\/azure\/devops\/organizations\/accounts\/use-personal-access-tokens-to-authenticate<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create a classic Azure Pipeline (build pipeline)<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In Azure DevOps, go to <strong>Pipelines<\/strong>.<\/li>\n<li>Choose <strong>New pipeline<\/strong>.<\/li>\n<li>Select <strong>Azure Repos Git<\/strong> and choose your repo.<\/li>\n<li>\n<p>Look for the option <strong>Use the classic editor<\/strong> (UI-based).<br\/>\n   &#8211; If you don\u2019t see it, the UI may differ by update\/permissions. Verify in official docs for classic pipelines availability.<\/p>\n<\/li>\n<li>\n<p>In the classic editor:\n   &#8211; Select a template: start with an empty job or a .NET template if available.\n   &#8211; Agent pool: select <strong>Azure Pipelines<\/strong> (Microsoft-hosted).\n   &#8211; Agent specification: pick a Windows or Ubuntu image that supports the .NET SDK you need (the UI shows available options).<\/p>\n<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> You see a pipeline with at least one job and can add tasks.<\/p>\n\n\n\n<p><strong>Verification:<\/strong>\n&#8211; Confirm the pipeline is associated with the correct repository and default branch (<code>main<\/code>).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Add tasks (restore, build, test, publish)<\/h3>\n\n\n\n<p>In the classic pipeline editor, add tasks in this approximate order.<\/p>\n\n\n\n<blockquote>\n<p>Task names in the UI may vary slightly over time. Use the task search box and verify task publisher is Microsoft when possible.<\/p>\n<\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\">4.1 Install .NET SDK (if needed)<\/h4>\n\n\n\n<p>Add a task to install\/use a specific .NET SDK version:\n&#8211; Task commonly called <strong>Use .NET Core<\/strong> or <strong>Use .NET SDK<\/strong> (naming varies).<\/p>\n\n\n\n<p>Configure:\n&#8211; Version: choose a supported LTS (verify your target version)\n&#8211; Installation path: default<\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> Agent has the required .NET SDK available.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">4.2 Restore<\/h4>\n\n\n\n<p>Add a <strong>.NET Core<\/strong> or <strong>DotNet<\/strong> command task:\n&#8211; Command: <code>restore<\/code>\n&#8211; Projects: <code>PipelinesLab.sln<\/code><\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> Dependencies restore successfully.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">4.3 Build<\/h4>\n\n\n\n<p>Add a .NET build task:\n&#8211; Command: <code>build<\/code>\n&#8211; Projects: <code>PipelinesLab.sln<\/code>\n&#8211; Arguments: <code>--configuration Release<\/code><\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> Solution builds.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">4.4 Test with results<\/h4>\n\n\n\n<p>Add a .NET test task:\n&#8211; Command: <code>test<\/code>\n&#8211; Projects: <code>PipelinesLab.sln<\/code>\n&#8211; Arguments: <code>--configuration Release<\/code><\/p>\n\n\n\n<p>To publish test results, you may:\n&#8211; Enable \u201cPublish test results\u201d inside the test task (if available), <strong>or<\/strong>\n&#8211; Add a separate <strong>Publish Test Results<\/strong> task configured for the output format your runner produces.<\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> Tests run and results are visible in the pipeline run summary.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">4.5 Publish an artifact<\/h4>\n\n\n\n<p>Add a task to copy outputs to the staging directory (often optional depending on task behavior), then publish.<\/p>\n\n\n\n<p>Common approach:\n1. Add a file copy task:\n   &#8211; Source folder: repository root or specific output path\n   &#8211; Target folder: <code>$(Build.ArtifactStagingDirectory)<\/code>\n2. Add <strong>Publish Build Artifacts<\/strong> task:\n   &#8211; Path to publish: <code>$(Build.ArtifactStagingDirectory)<\/code>\n   &#8211; Artifact name: <code>drop<\/code><\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> The run produces an artifact named <code>drop<\/code>.<\/p>\n\n\n\n<p><strong>Verification:<\/strong>\n&#8211; Ensure you are copying the right build output. For .NET class libraries, outputs are under <code>bin\/Release\/...<\/code>. You can also publish the entire repo for demonstration, but it\u2019s not recommended for real projects.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Enable Continuous Integration (CI) trigger<\/h3>\n\n\n\n<p>In the classic pipeline editor:\n1. Open the <strong>Triggers<\/strong> tab.\n2. Enable <strong>Continuous integration<\/strong>.\n3. Set branch filters:\n   &#8211; Include: <code>main<\/code><\/p>\n\n\n\n<p>Save the pipeline.<\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> A commit to <code>main<\/code> automatically triggers a new build.<\/p>\n\n\n\n<p><strong>Verification:<\/strong>\n&#8211; Make a small commit (e.g., update README) and push to <code>main<\/code>.\n&#8211; Confirm a new pipeline run starts automatically.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Run the pipeline and review outputs<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Queue a run manually the first time:\n   &#8211; Pipelines \u2192 select your pipeline \u2192 <strong>Run pipeline<\/strong> \/ <strong>Queue<\/strong><\/li>\n<li>Watch the run:\n   &#8211; Confirm each task succeeds\n   &#8211; Open logs if a step fails<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcomes:<\/strong>\n&#8211; Build succeeds\n&#8211; Test results are published\n&#8211; Artifact <code>drop<\/code> is available for download<\/p>\n\n\n\n<p><strong>Verification checklist:<\/strong>\n&#8211; Pipeline run summary shows:\n  &#8211; Source commit\n  &#8211; Duration and agent details\n  &#8211; Tests tab or test summary (if configured)\n  &#8211; Artifacts section with <code>drop<\/code><\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Validation<\/h3>\n\n\n\n<p>Use this quick validation to confirm your CI is functioning end-to-end:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Break a test intentionally by changing expected value (e.g., expect <code>6<\/code> instead of <code>5<\/code>).<\/li>\n<li>Commit and push:<\/li>\n<\/ol>\n\n\n\n<pre><code class=\"language-bash\">git add .\ngit commit -m \"Introduce failing test\"\ngit push\n<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Confirm Azure Pipelines triggers automatically and the run fails at the test step.<\/li>\n<li>Fix the test and push again; confirm the next run succeeds.<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> You\u2019ve proven CI triggers, test reporting, and build repeatability.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Troubleshooting<\/h3>\n\n\n\n<p>Common issues and realistic fixes:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\n<p><strong>No hosted agent available \/ pipeline stuck queued<\/strong>\n   &#8211; Cause: No available parallel job capacity or billing not enabled.\n   &#8211; Fix: Check parallel jobs and billing status in org settings; or use a self-hosted agent.\n   &#8211; Reference: https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/licensing\/concurrent-jobs?view=azure-devops<\/p>\n<\/li>\n<li>\n<p><strong>Repository checkout fails<\/strong>\n   &#8211; Cause: pipeline identity lacks repo permissions, or branch name mismatch.\n   &#8211; Fix: Verify repo permissions and the pipeline is targeting <code>main<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>.NET SDK not found<\/strong>\n   &#8211; Cause: agent image doesn\u2019t include your target SDK.\n   &#8211; Fix: Add the \u201cUse .NET\u201d task to install the correct version or change agent image to one that supports it (verify hosted agent software lists).<\/p>\n<\/li>\n<li>\n<p><strong>Tests run but no test results appear<\/strong>\n   &#8211; Cause: results not being published or wrong result format path.\n   &#8211; Fix: Enable publish results in the test task or configure Publish Test Results task correctly.<\/p>\n<\/li>\n<li>\n<p><strong>Artifact is empty<\/strong>\n   &#8211; Cause: copying wrong folder into <code>$(Build.ArtifactStagingDirectory)<\/code>.\n   &#8211; Fix: Inspect build output paths in logs, then adjust copy pattern.<\/p>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Cleanup<\/h3>\n\n\n\n<p>To avoid ongoing usage:\n&#8211; Disable CI trigger in the pipeline if you don\u2019t need it.\n&#8211; Delete the pipeline:\n  &#8211; Pipelines \u2192 select pipeline \u2192 More options \u2192 Delete\n&#8211; Delete the project (most thorough cleanup):\n  &#8211; Project settings \u2192 Overview \u2192 Delete (requires project admin rights)<\/p>\n\n\n\n<p>If you created any self-hosted agents for experimentation:\n&#8211; Remove agent registration from Agent pools\n&#8211; Decommission the VM\/host to stop compute charges<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Architecture best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Prefer \u201cbuild once, deploy many\u201d:<\/strong> Build artifacts once in CI and promote the same artifact across environments.<\/li>\n<li><strong>Separate concerns:<\/strong> CI builds\/tests; CD promotes and deploys.<\/li>\n<li><strong>Use self-hosted agents for private access:<\/strong> Don\u2019t expose private endpoints just to use Microsoft-hosted agents.<\/li>\n<li><strong>Use environments for deployments:<\/strong> Model dev\/test\/prod and apply approvals\/checks.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">IAM\/security best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Least privilege service connections:<\/strong> Scope Azure service principals to only necessary resource groups\/subscriptions.<\/li>\n<li><strong>Restrict who can edit pipelines:<\/strong> Treat pipeline edits as code changes requiring review.<\/li>\n<li><strong>Protect production environments:<\/strong> Require approvals; limit approvers; enforce separation of duties.<\/li>\n<li><strong>Prefer modern authentication:<\/strong> Use the most secure supported method for Azure service connections (for example, workload identity federation if supported in your scenario\u2014verify current docs).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Cost best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Reduce build time:<\/strong> faster pipelines cost less and deliver faster feedback.<\/li>\n<li><strong>Right-size parallelism:<\/strong> buy concurrency only when needed.<\/li>\n<li><strong>Use retention policies:<\/strong> keep fewer runs for non-release branches.<\/li>\n<li><strong>Avoid heavyweight hosted builds when self-hosted is cheaper at scale<\/strong> (but account for ops cost).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Cache dependencies<\/strong> where supported (NuGet\/npm\/etc.).<\/li>\n<li><strong>Parallelize tests<\/strong> thoughtfully (test isolation matters).<\/li>\n<li><strong>Use incremental builds<\/strong> and avoid rebuilding unchanged components where possible.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Reliability best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Pin critical tool versions<\/strong> (SDK\/runtime) to avoid unexpected changes.<\/li>\n<li><strong>Fail fast:<\/strong> run lint\/unit tests early.<\/li>\n<li><strong>Make deployments idempotent:<\/strong> reruns should not corrupt environments.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operations best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Standardize agent images for self-hosted pools<\/strong> and patch regularly.<\/li>\n<li><strong>Centralize logs and evidence<\/strong> for audits and incident analysis.<\/li>\n<li><strong>Use naming conventions<\/strong> for pipelines, agent pools, environments, and service connections.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Governance\/tagging\/naming best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use consistent names like:<\/li>\n<li>Pipelines: <code>ci-&lt;repo&gt;<\/code>, <code>cd-&lt;service&gt;<\/code><\/li>\n<li>Environments: <code>dev<\/code>, <code>test<\/code>, <code>prod<\/code><\/li>\n<li>Agent pools: <code>selfhosted-vnet-prod<\/code>, <code>selfhosted-build<\/code><\/li>\n<li>Document ownership and on-call rotation for pipeline failures.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">12. Security Considerations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Identity and access model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure DevOps uses organization\/project security groups and permissions.<\/li>\n<li>Pipelines access external systems via <strong>service connections<\/strong>.<\/li>\n<li>Developers\u2019 ability to change pipelines can equate to the ability to change what runs on agents\u2014treat pipeline modification as privileged.<\/li>\n<\/ul>\n\n\n\n<p><strong>Recommendation:<\/strong> Lock down:\n&#8211; Who can create\/edit pipelines\n&#8211; Who can manage service connections\n&#8211; Who can approve deployments to production environments<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Encryption<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure DevOps Services encrypts data at rest and in transit (TLS). For compliance specifics, verify Microsoft\u2019s official documentation and trust resources for Azure DevOps.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network exposure<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Microsoft-hosted agents run outside your network boundary.<\/li>\n<li>Use self-hosted agents for:<\/li>\n<li>private endpoints<\/li>\n<li>on-prem deployments<\/li>\n<li>strict egress controls<\/li>\n<li>Ensure self-hosted agents have restricted outbound access (allow-list required endpoints).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secrets handling<\/h3>\n\n\n\n<p>Preferred approaches:\n&#8211; Use <strong>secret variables<\/strong> and <strong>variable groups<\/strong> with locked permissions.\n&#8211; Integrate with <strong>Azure Key Vault<\/strong> for centralized secret lifecycle (common enterprise pattern\u2014verify your organization\u2019s approved approach).\n&#8211; Use <strong>secure files<\/strong> for certificates and protect access.<\/p>\n\n\n\n<p>Avoid:\n&#8211; Hardcoding secrets in scripts\n&#8211; Printing secrets in logs\n&#8211; Storing credentials in repo files<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Audit\/logging<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Azure DevOps auditing features (verify availability for your plan).<\/li>\n<li>Retain pipeline logs\/artifacts appropriately for compliance, but balance cost and privacy.<\/li>\n<li>Review service connection usage and changes regularly.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Compliance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Map pipeline controls to internal requirements:<\/li>\n<li>approvals for production deployments<\/li>\n<li>separation of duties<\/li>\n<li>immutable artifact promotion<\/li>\n<li>evidence retention<\/li>\n<li>Verify Azure DevOps compliance attestations and regional data handling in Microsoft documentation.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Common security mistakes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Over-privileged Azure service connections (subscription Owner when Contributor is enough)<\/li>\n<li>Allowing PRs from forks to run with secrets (risk depends on configuration\u2014verify your PR security settings)<\/li>\n<li>Running untrusted code on self-hosted agents with access to production networks<\/li>\n<li>Sharing agent pools across high-trust and low-trust projects without isolation<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secure deployment recommendations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Isolate agent pools by trust boundary (e.g., prod deployments use a dedicated pool).<\/li>\n<li>Use approvals and checks for production environments.<\/li>\n<li>Use least privilege for service connections.<\/li>\n<li>Keep build agents ephemeral where possible; reimage self-hosted agents regularly if feasible.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">13. Limitations and Gotchas<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Known limitations (common patterns)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Microsoft-hosted agents can\u2019t reach private networks<\/strong> without exposing endpoints or using additional networking patterns; self-hosted agents are the typical solution.<\/li>\n<li><strong>Hosted agent environments are ephemeral:<\/strong> don\u2019t rely on local state between runs.<\/li>\n<li><strong>Time limits and resource constraints<\/strong> exist for hosted jobs (timeouts, disk\/CPU\/memory constraints). Verify current limits in official docs.<\/li>\n<li><strong>Classic vs YAML differences:<\/strong> Some advanced reuse patterns (templates) and modern practices are primarily YAML-focused.<\/li>\n<li><strong>Marketplace extension risk:<\/strong> Extensions can be powerful but require governance and vetting.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quotas and capacity<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Parallel jobs and concurrency are limited by plan.<\/li>\n<li>Organization-level limits may exist for artifacts\/log retention. Verify in org settings and docs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Regional constraints<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your Azure DevOps organization region and agent availability can affect performance and compliance. Verify your organization\u2019s geo and agent pool options.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing surprises<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Adding parallel jobs for faster throughput can increase cost.<\/li>\n<li>Self-hosted compute costs and ops time can exceed expectations if not standardized.<\/li>\n<li>Excessive artifact retention increases storage usage.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Compatibility issues<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Build scripts that assume specific tool versions may break when hosted agent images update.<\/li>\n<li>Deployments can fail if service connections expire (cert rotation, secret expiry).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operational gotchas<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Self-hosted agents are effectively \u201cproduction infrastructure\u201d: they need monitoring, patching, and access control.<\/li>\n<li>Pipeline permissions and service connections can become complex in large orgs\u2014document ownership.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Migration challenges<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Moving from classic to YAML requires redesign (tasks map, but triggers\/templates differ).<\/li>\n<li>Migrating from other CI tools (Jenkins\/GitLab) often requires revisiting credential handling, artifact management, and environment promotion strategy.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">14. Comparison with Alternatives<\/h2>\n\n\n\n<p>Azure Pipelines is one of several mature CI\/CD options. The best choice depends on where your code lives, governance needs, and operational preferences.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Comparison table<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Option<\/th>\n<th>Best For<\/th>\n<th>Strengths<\/th>\n<th>Weaknesses<\/th>\n<th>When to Choose<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Azure Pipelines (Azure DevOps)<\/strong><\/td>\n<td>Teams using Azure DevOps or needing enterprise CI\/CD with Azure integration<\/td>\n<td>Strong Azure DevOps suite integration, flexible agents, multi-stage pipelines, approvals\/checks<\/td>\n<td>Requires Azure DevOps org governance; hosted capacity\/licensing considerations<\/td>\n<td>You want integrated Boards\/Repos\/Artifacts + pipelines, or need self-hosted agents for private deployments<\/td>\n<\/tr>\n<tr>\n<td><strong>GitHub Actions<\/strong><\/td>\n<td>GitHub-native CI\/CD<\/td>\n<td>Tight GitHub integration, huge marketplace, good developer experience<\/td>\n<td>Governance and enterprise controls differ; complex cross-repo enterprise patterns can vary<\/td>\n<td>Your code is in GitHub and you want workflow-as-code close to the repo<\/td>\n<\/tr>\n<tr>\n<td><strong>Jenkins (self-managed)<\/strong><\/td>\n<td>Maximum customization and self-hosting<\/td>\n<td>Very flexible, massive plugin ecosystem<\/td>\n<td>High ops overhead, plugin supply-chain risk, harder governance<\/td>\n<td>You need full control and accept running\/maintaining CI infrastructure<\/td>\n<\/tr>\n<tr>\n<td><strong>GitLab CI\/CD<\/strong><\/td>\n<td>GitLab-centric orgs<\/td>\n<td>Integrated SCM + CI + security features (plan dependent)<\/td>\n<td>Less aligned if you\u2019re standardized on Azure DevOps<\/td>\n<td>Your org uses GitLab and wants an integrated DevSecOps platform<\/td>\n<\/tr>\n<tr>\n<td><strong>AWS CodePipeline\/CodeBuild<\/strong><\/td>\n<td>AWS-centric deployments<\/td>\n<td>Native AWS integration, IAM alignment<\/td>\n<td>Less integrated for Azure-first environments<\/td>\n<td>Most workloads deploy to AWS and you want AWS-native pipelines<\/td>\n<\/tr>\n<tr>\n<td><strong>Google Cloud Build<\/strong><\/td>\n<td>GCP-centric deployments<\/td>\n<td>Native GCP integration, container-first workflows<\/td>\n<td>Less integrated for Azure-first environments<\/td>\n<td>Workloads primarily deploy to GCP<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<p>Nearest \u201csame cloud\u201d alternatives:\n&#8211; <strong>GitHub Actions<\/strong> (Microsoft-owned, but a separate product from Azure DevOps)\n&#8211; Azure DevOps also includes additional tooling (Repos\/Boards\/Artifacts\/Test Plans); Azure Pipelines is the CI\/CD component.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">15. Real-World Example<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Enterprise example (regulated industry)<\/h3>\n\n\n\n<p><strong>Problem:<\/strong> A financial services company needs auditable releases with separation of duties, controlled production deployments, and traceability from change request to deployment.<\/p>\n\n\n\n<p><strong>Proposed architecture:<\/strong>\n&#8211; Azure Repos for source control with branch policies (required reviewers, build validation)\n&#8211; Azure Pipelines multi-stage pipeline:\n  &#8211; CI: build + tests + security scanning tool integration (tool-specific)\n  &#8211; Publish immutable artifact\n  &#8211; CD: deploy to dev\/test\/prod environments\n&#8211; Dedicated self-hosted agent pools for deployments into private networks\n&#8211; Environments with approvals and checks for production\n&#8211; Azure Key Vault for secrets\n&#8211; Centralized logging of deployment evidence (pipeline logs + artifacts retention)<\/p>\n\n\n\n<p><strong>Why Azure Pipelines was chosen:<\/strong>\n&#8211; Integrates with Azure DevOps governance and work tracking\n&#8211; Supports self-hosted agents for private network deployments\n&#8211; Approvals\/checks provide operational controls and auditability<\/p>\n\n\n\n<p><strong>Expected outcomes:<\/strong>\n&#8211; Reduced production incidents due to consistent releases\n&#8211; Faster audits due to centralized evidence\n&#8211; Clear ownership and controlled access to production deployments<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Startup\/small-team example<\/h3>\n\n\n\n<p><strong>Problem:<\/strong> A startup needs fast CI feedback for a .NET API and wants to publish build artifacts for releases with minimal overhead.<\/p>\n\n\n\n<p><strong>Proposed architecture:<\/strong>\n&#8211; Azure Repos (or GitHub) with a single CI pipeline\n&#8211; Microsoft-hosted agent for simple builds\n&#8211; Automated unit tests on each commit and PR\n&#8211; Publish build artifact for release packaging\n&#8211; Optional manual deployment step for early-stage environments<\/p>\n\n\n\n<p><strong>Why Azure Pipelines was chosen:<\/strong>\n&#8211; Quick setup inside Azure DevOps\n&#8211; Minimal infrastructure to manage\n&#8211; Easy scaling later by adding parallel jobs or self-hosted agents<\/p>\n\n\n\n<p><strong>Expected outcomes:<\/strong>\n&#8211; Faster iteration with fewer broken builds\n&#8211; Reproducible build outputs for releases\n&#8211; A clear path to add deployment stages later<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">16. FAQ<\/h2>\n\n\n\n<p>1) <strong>Is Azure Pipelines only for Azure deployments?<\/strong><br\/>\nNo. Azure Pipelines can build and deploy to many targets (including on-prem and other clouds) depending on connectivity and credentials. Azure targets are common because of built-in integrations.<\/p>\n\n\n\n<p>2) <strong>Do I need Azure DevOps to use Azure Pipelines?<\/strong><br\/>\nAzure Pipelines is part of Azure DevOps. In practice, you use an Azure DevOps organization\/project to run pipelines.<\/p>\n\n\n\n<p>3) <strong>Should I use YAML pipelines or classic pipelines?<\/strong><br\/>\nFor most modern teams, YAML is recommended because it\u2019s versioned and reviewable. Classic pipelines can still be useful for quick starts or legacy workflows. Verify Microsoft\u2019s latest guidance in official docs.<\/p>\n\n\n\n<p>4) <strong>What\u2019s the difference between Microsoft-hosted and self-hosted agents?<\/strong><br\/>\nMicrosoft-hosted agents are managed by Microsoft and are ephemeral. Self-hosted agents run on your infrastructure, giving you private network access and custom tooling, but you manage patching and scaling.<\/p>\n\n\n\n<p>5) <strong>Can Azure Pipelines access resources in a private Azure VNet?<\/strong><br\/>\nYes, typically by using a self-hosted agent running in that VNet (or connected network). Microsoft-hosted agents generally can\u2019t directly access private endpoints.<\/p>\n\n\n\n<p>6) <strong>How do I store secrets safely for pipelines?<\/strong><br\/>\nUse secret variables\/variable groups and restrict access. For stronger lifecycle and central management, integrate with Azure Key Vault (verify the recommended approach and tasks in current docs).<\/p>\n\n\n\n<p>7) <strong>Can pull requests from forks run pipelines securely?<\/strong><br\/>\nThis is sensitive: running untrusted code with access to secrets can be dangerous. Use PR security settings and avoid exposing secrets to untrusted contributions. Verify your org\u2019s PR pipeline security configuration.<\/p>\n\n\n\n<p>8) <strong>How do approvals work for production deployments?<\/strong><br\/>\nApprovals are typically configured on environments\/stages so specific users\/groups must approve before deployment proceeds. Exact behavior depends on pipeline type and environment configuration.<\/p>\n\n\n\n<p>9) <strong>How do I speed up my pipelines?<\/strong><br\/>\nParallelize tests, cache dependencies, reduce artifact size, and avoid unnecessary steps. Also consider increasing parallel job capacity if queue time is the bottleneck.<\/p>\n\n\n\n<p>10) <strong>What causes \u201cNo hosted parallelism has been purchased or granted\u201d?<\/strong><br\/>\nYour organization may not have free hosted capacity available or billing may not be enabled. Check parallel job settings and licensing.<\/p>\n\n\n\n<p>11) <strong>Can I run pipelines on macOS?<\/strong><br\/>\nYes, typically via Microsoft-hosted macOS agents (availability and limits apply) or self-hosted macOS agents if supported by your setup. Verify current hosted images and availability.<\/p>\n\n\n\n<p>12) <strong>How do I deploy to Kubernetes (AKS)?<\/strong><br\/>\nCommonly via kubectl\/Helm tasks using a Kubernetes service connection or by running scripts on an agent that has network access and credentials. Verify best practices for credential handling.<\/p>\n\n\n\n<p>13) <strong>How do I manage multiple microservices with Azure Pipelines?<\/strong><br\/>\nUse separate pipelines per service or a monorepo strategy with path-based triggers\/conditions (often YAML-based). Standardize with templates where possible.<\/p>\n\n\n\n<p>14) <strong>What\u2019s the best way to handle environment-specific configuration?<\/strong><br\/>\nUse variable groups, environment-scoped variables, and secret stores (Key Vault) rather than hardcoding values.<\/p>\n\n\n\n<p>15) <strong>Can Azure Pipelines run infrastructure deployments (IaC)?<\/strong><br\/>\nYes. You can run Azure CLI\/PowerShell\/Terraform\/Bicep workflows. Treat IaC like application code: validate on PRs, deploy with approvals.<\/p>\n\n\n\n<p>16) <strong>Does Azure Pipelines support audit and compliance needs?<\/strong><br\/>\nAzure DevOps provides logs, run history, approvals, and auditing features. The exact compliance posture depends on your configuration and Microsoft\u2019s attestations\u2014verify for your requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">17. Top Online Resources to Learn Azure Pipelines<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Resource Type<\/th>\n<th>Name<\/th>\n<th>Why It Is Useful<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Official documentation<\/td>\n<td>Azure Pipelines docs (Learn) \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/?view=azure-devops<\/td>\n<td>The primary, most up-to-date reference for concepts, tasks, agents, and pipeline types<\/td>\n<\/tr>\n<tr>\n<td>Official getting started<\/td>\n<td>Create your first pipeline (Azure DevOps) \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/create-first-pipeline?view=azure-devops<\/td>\n<td>Step-by-step onboarding flow (often YAML-first)<\/td>\n<\/tr>\n<tr>\n<td>Official concepts<\/td>\n<td>Agents and agent pools \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/agents\/agents?view=azure-devops<\/td>\n<td>Core execution model; required reading for scaling and security<\/td>\n<\/tr>\n<tr>\n<td>Official hosted agents<\/td>\n<td>Microsoft-hosted agents \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/agents\/hosted?view=azure-devops<\/td>\n<td>Images, capabilities, and constraints for hosted builds<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure DevOps Services Pricing \u2014 https:\/\/azure.microsoft.com\/pricing\/details\/devops\/azure-devops-services\/<\/td>\n<td>Authoritative pricing model reference<\/td>\n<\/tr>\n<tr>\n<td>Official licensing<\/td>\n<td>Parallel jobs\/concurrency \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/licensing\/concurrent-jobs?view=azure-devops<\/td>\n<td>Explains how concurrency works and what you must buy\/enable<\/td>\n<\/tr>\n<tr>\n<td>Official security<\/td>\n<td>Azure DevOps security documentation \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/organizations\/security\/?view=azure-devops<\/td>\n<td>Permissions, policies, and governance fundamentals<\/td>\n<\/tr>\n<tr>\n<td>Official auth<\/td>\n<td>Personal Access Tokens (PATs) \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/organizations\/accounts\/use-personal-access-tokens-to-authenticate<\/td>\n<td>Practical authentication guidance for Git and API usage<\/td>\n<\/tr>\n<tr>\n<td>Architecture guidance<\/td>\n<td>Azure Architecture Center \u2014 https:\/\/learn.microsoft.com\/azure\/architecture\/<\/td>\n<td>Broader Azure architecture patterns relevant to CI\/CD and deployments<\/td>\n<\/tr>\n<tr>\n<td>Video learning<\/td>\n<td>Azure DevOps YouTube (official Microsoft channels; verify latest playlists) \u2014 https:\/\/www.youtube.com\/@MicrosoftDeveloper<\/td>\n<td>Useful demos and product updates; always cross-check with docs<\/td>\n<\/tr>\n<tr>\n<td>Samples<\/td>\n<td>Azure DevOps samples on GitHub (Microsoft org; verify relevance) \u2014 https:\/\/github.com\/microsoft\/azure-pipelines-tasks<\/td>\n<td>Shows how tasks work; helpful for deeper customization<\/td>\n<\/tr>\n<tr>\n<td>Community learning<\/td>\n<td>Microsoft Q&amp;A for Azure DevOps \u2014 https:\/\/learn.microsoft.com\/answers\/topics\/azure-devops.html<\/td>\n<td>Troubleshooting patterns and validated answers (still verify)<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">18. Training and Certification Providers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Institute<\/th>\n<th>Suitable Audience<\/th>\n<th>Likely Learning Focus<\/th>\n<th>Mode<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>Beginners to enterprise DevOps teams<\/td>\n<td>Azure DevOps, CI\/CD, pipelines, DevOps practices<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>ScmGalaxy.com<\/td>\n<td>Students and working professionals<\/td>\n<td>SCM + DevOps fundamentals, CI\/CD workflows<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.scmgalaxy.com\/<\/td>\n<\/tr>\n<tr>\n<td>CLoudOpsNow.in<\/td>\n<td>Cloud engineers, SREs, ops teams<\/td>\n<td>Cloud operations + DevOps automation<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.cloudopsnow.in\/<\/td>\n<\/tr>\n<tr>\n<td>SreSchool.com<\/td>\n<td>SREs and platform teams<\/td>\n<td>Reliability engineering, automation, incident readiness<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.sreschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>AiOpsSchool.com<\/td>\n<td>Ops teams exploring AIOps<\/td>\n<td>Observability, automation, AIOps concepts<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.aiopsschool.com\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">19. Top Trainers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Platform\/Site<\/th>\n<th>Likely Specialization<\/th>\n<th>Suitable Audience<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>RajeshKumar.xyz<\/td>\n<td>DevOps coaching\/training resources (verify offerings)<\/td>\n<td>Beginners to intermediate DevOps learners<\/td>\n<td>https:\/\/rajeshkumar.xyz\/<\/td>\n<\/tr>\n<tr>\n<td>devopstrainer.in<\/td>\n<td>DevOps training programs (verify syllabus)<\/td>\n<td>Individuals and corporate teams<\/td>\n<td>https:\/\/www.devopstrainer.in\/<\/td>\n<\/tr>\n<tr>\n<td>devopsfreelancer.com<\/td>\n<td>DevOps freelance\/training services (verify scope)<\/td>\n<td>Teams needing targeted help<\/td>\n<td>https:\/\/www.devopsfreelancer.com\/<\/td>\n<\/tr>\n<tr>\n<td>devopssupport.in<\/td>\n<td>DevOps support and guidance resources (verify services)<\/td>\n<td>Ops teams and engineers<\/td>\n<td>https:\/\/www.devopssupport.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">20. Top Consulting Companies<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Company<\/th>\n<th>Likely Service Area<\/th>\n<th>Where They May Help<\/th>\n<th>Consulting Use Case Examples<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>cotocus.com<\/td>\n<td>DevOps\/Cloud consulting (verify exact portfolio)<\/td>\n<td>CI\/CD design, cloud architecture, implementation support<\/td>\n<td>Pipeline standardization, migration planning, agent strategy<\/td>\n<td>https:\/\/cotocus.com\/<\/td>\n<\/tr>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps consulting and enablement (verify offerings)<\/td>\n<td>Platform enablement, training + implementation<\/td>\n<td>Azure DevOps rollout, governance model, pipeline best practices<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>DEVOPSCONSULTING.IN<\/td>\n<td>DevOps consulting (verify services)<\/td>\n<td>CI\/CD implementation and operations alignment<\/td>\n<td>Delivery process automation, pipeline troubleshooting, best-practice rollout<\/td>\n<td>https:\/\/www.devopsconsulting.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">21. Career and Learning Roadmap<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn before Azure Pipelines<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Git fundamentals (branches, PRs, merge strategies)<\/li>\n<li>Basic build tooling for your stack (.NET\/Node\/Java\/Python)<\/li>\n<li>Basic Azure fundamentals (resource groups, identity, subscriptions) if you will deploy to Azure<\/li>\n<li>Security basics: least privilege, secret handling, secure SDLC concepts<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn after Azure Pipelines<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Multi-stage pipelines and environment promotion strategies<\/li>\n<li>Artifact management and package feeds (Azure Artifacts)<\/li>\n<li>Infrastructure as Code and deployment patterns (ARM\/Bicep\/Terraform\u2014depending on your org)<\/li>\n<li>Observability and release health: monitoring, alerting, SLOs<\/li>\n<li>Supply chain security: signed artifacts, dependency scanning, provenance (tooling-dependent)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Job roles that use Azure Pipelines<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DevOps Engineer \/ Platform Engineer<\/li>\n<li>Cloud Engineer<\/li>\n<li>SRE (especially where deployments and reliability controls are automated)<\/li>\n<li>Build\/Release Engineer<\/li>\n<li>Software Engineer (owning service CI\/CD)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Certification path (practical guidance)<\/h3>\n\n\n\n<p>Azure Pipelines is commonly used in DevOps roles aligned with Microsoft certifications (for example, DevOps Engineer Expert). Certification names and requirements change; verify the latest Microsoft certification roadmap:\nhttps:\/\/learn.microsoft.com\/credentials\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Project ideas for practice<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create CI for a .NET\/Node app with unit tests and code coverage publishing.<\/li>\n<li>Add PR validation with branch policies and required reviewers.<\/li>\n<li>Add a deployment stage to a dev environment with approvals for prod.<\/li>\n<li>Implement a self-hosted agent in an Azure VNet and deploy to a private endpoint service.<\/li>\n<li>Standardize pipelines across 3 repos with shared templates (YAML-based; follow official docs).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">22. Glossary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Agent:<\/strong> A compute worker that runs pipeline jobs (Microsoft-hosted or self-hosted).<\/li>\n<li><strong>Agent pool:<\/strong> A logical group of agents that pipelines can target.<\/li>\n<li><strong>Artifact:<\/strong> A build output stored for later download or deployment.<\/li>\n<li><strong>Azure DevOps organization:<\/strong> Top-level container for projects, users, and governance.<\/li>\n<li><strong>Build (CI):<\/strong> Automated process to compile, test, and package code on changes.<\/li>\n<li><strong>CD (delivery\/deployment):<\/strong> Automated process to deploy artifacts to environments.<\/li>\n<li><strong>Classic pipeline:<\/strong> UI-configured pipeline (as opposed to YAML-as-code).<\/li>\n<li><strong>Environment:<\/strong> A logical target (dev\/test\/prod) used to manage deployments and approvals\/checks.<\/li>\n<li><strong>Job:<\/strong> A set of steps executed by an agent.<\/li>\n<li><strong>Parallel job:<\/strong> Licensed capacity to run pipeline jobs concurrently.<\/li>\n<li><strong>Pipeline run:<\/strong> One execution instance of a pipeline definition.<\/li>\n<li><strong>PR validation:<\/strong> Running CI checks automatically when a pull request is created\/updated.<\/li>\n<li><strong>Service connection:<\/strong> Stored authentication configuration that allows pipelines to access external services securely.<\/li>\n<li><strong>Stage:<\/strong> A major phase in a pipeline (build\/test\/deploy), often tied to environments.<\/li>\n<li><strong>Task:<\/strong> A packaged unit of work in a pipeline (e.g., run tests, publish artifacts).<\/li>\n<li><strong>Variable group:<\/strong> A shared set of variables (including secrets) used across pipelines.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">23. Summary<\/h2>\n\n\n\n<p>Azure Pipelines is Azure DevOps\u2019 CI\/CD service in the <strong>Azure Developer Tools<\/strong> ecosystem. It automates builds, tests, artifact publishing, and deployments using Microsoft-hosted or self-hosted agents, integrating tightly with Azure services and enterprise governance needs.<\/p>\n\n\n\n<p>It matters because it standardizes delivery: every change can be validated, packaged, and promoted with approvals and traceable evidence. Cost is primarily driven by <strong>parallel job capacity<\/strong>, pipeline runtime, and (for self-hosted agents) the compute and operations overhead you manage. Security hinges on least-privilege service connections, protected environments, safe secret management, and strong governance over who can change pipeline definitions.<\/p>\n\n\n\n<p>Use Azure Pipelines when you want a robust CI\/CD platform integrated with Azure DevOps and need flexible agent placement (including private networks). Next step: learn multi-stage pipelines, environments\/approvals, and service connections in the official documentation: https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/?view=azure-devops<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Developer Tools<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,18,43],"tags":[],"class_list":["post-422","post","type-post","status-publish","format-standard","hentry","category-azure","category-developer-tools","category-devops"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/422","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=422"}],"version-history":[{"count":0,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/422\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=422"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=422"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=422"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}