{"id":420,"date":"2026-04-14T00:03:33","date_gmt":"2026-04-14T00:03:33","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/azure-devops-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-developer-tools\/"},"modified":"2026-04-14T00:03:33","modified_gmt":"2026-04-14T00:03:33","slug":"azure-devops-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-developer-tools","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/azure-devops-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-developer-tools\/","title":{"rendered":"Azure DevOps 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 DevOps is Microsoft\u2019s suite of Developer Tools for planning work, hosting source code, building CI\/CD pipelines, managing test quality, and publishing internal packages\u2014all in one platform.<\/p>\n\n\n\n<p>In simple terms: Azure DevOps helps your team go from idea \u2192 code \u2192 build \u2192 test \u2192 release in a repeatable, auditable way.<\/p>\n\n\n\n<p>Technically, Azure DevOps is a set of cloud services (Azure DevOps Services) and a self-hosted product (Azure DevOps Server) that provide:\n&#8211; Agile planning (Azure Boards)\n&#8211; Git repositories (Azure Repos)\n&#8211; CI\/CD automation (Azure Pipelines)\n&#8211; Test management (Azure Test Plans)\n&#8211; Package feeds (Azure Artifacts)<\/p>\n\n\n\n<p>It solves common delivery problems: inconsistent build processes, manual deployments, poor traceability between requirements and code, lack of approvals\/audit trails, hard-to-manage secrets, and fragmented toolchains across engineering teams.<\/p>\n\n\n\n<blockquote>\n<p>Naming note (history): Azure DevOps Services was previously called <strong>Visual Studio Team Services (VSTS)<\/strong>, and Azure DevOps Server evolved from <strong>Team Foundation Server (TFS)<\/strong>. Azure DevOps is the current, active product name.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">2. What is Azure DevOps?<\/h2>\n\n\n\n<p><strong>Official purpose:<\/strong> Azure DevOps provides end-to-end tooling to help teams plan, collaborate, build, test, and deliver software.<\/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>Work planning and tracking:<\/strong> backlogs, boards, sprints, queries, dashboards<\/li>\n<li><strong>Source control:<\/strong> Git repositories, pull requests, branch policies<\/li>\n<li><strong>CI\/CD pipelines:<\/strong> YAML and classic pipelines, multi-stage releases, environments, approvals, gates<\/li>\n<li><strong>Test management:<\/strong> manual tests, exploratory testing, test plans\/suites<\/li>\n<li><strong>Package management:<\/strong> internal feeds for NuGet, npm, Maven, Python (PyPI), and Universal Packages<\/li>\n<li><strong>Extensibility:<\/strong> Marketplace extensions and REST APIs<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Major components<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Component<\/th>\n<th>What it does<\/th>\n<th>Common users<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Azure Boards<\/td>\n<td>Work items, Kanban, Scrum, reporting<\/td>\n<td>Product, engineering, program management<\/td>\n<\/tr>\n<tr>\n<td>Azure Repos<\/td>\n<td>Git repositories + PR workflows<\/td>\n<td>Developers<\/td>\n<\/tr>\n<tr>\n<td>Azure Pipelines<\/td>\n<td>CI\/CD automation<\/td>\n<td>DevOps engineers, developers, SREs<\/td>\n<\/tr>\n<tr>\n<td>Azure Test Plans<\/td>\n<td>Manual\/exploratory testing management<\/td>\n<td>QA teams, release managers<\/td>\n<\/tr>\n<tr>\n<td>Azure Artifacts<\/td>\n<td>Package feeds for internal dependencies<\/td>\n<td>Developers, platform teams<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Service type<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure DevOps Services (cloud\/SaaS):<\/strong> hosted by Microsoft, accessed via browser and APIs (commonly at <code>https:\/\/dev.azure.com\/&lt;org&gt;<\/code>).<\/li>\n<li><strong>Azure DevOps Server (self-hosted):<\/strong> installed and operated by you (often for regulated environments or data residency constraints).<\/li>\n<\/ul>\n\n\n\n<p>This tutorial focuses primarily on <strong>Azure DevOps Services<\/strong> because it\u2019s the most common starting point.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scope: organization and project model<\/h3>\n\n\n\n<p>Azure DevOps is typically structured as:\n&#8211; <strong>Organization<\/strong>: top-level container (billing, policies, users)\n&#8211; <strong>Project<\/strong>: contains repos, pipelines, boards, artifacts, and settings\n&#8211; <strong>Teams<\/strong> (within a project): sprint\/board configurations and permissions<\/p>\n\n\n\n<p>Azure DevOps Services is <strong>not<\/strong> scoped to an Azure subscription the way many Azure resources are. Instead, it integrates with Azure subscriptions through <strong>service connections<\/strong> (for example, deploying to Azure App Service, AKS, Azure SQL, etc.).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Regional\/global aspects<\/h3>\n\n\n\n<p>Azure DevOps Services is a global SaaS. When creating an organization, you typically choose a <strong>data location\/region (geo)<\/strong> for data residency. Exact region offerings and constraints can change\u2014<strong>verify in official docs<\/strong> for your tenant and compliance needs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How it fits into the Azure ecosystem<\/h3>\n\n\n\n<p>Azure DevOps integrates tightly with:\n&#8211; <strong>Microsoft Entra ID (Azure AD)<\/strong> for identity, SSO, MFA, Conditional Access\n&#8211; <strong>Azure Resource Manager<\/strong> via service connections for deployments\n&#8211; <strong>Azure Key Vault<\/strong> for secret retrieval in pipelines\n&#8211; <strong>Azure Monitor \/ Log Analytics<\/strong> indirectly through deployed app telemetry and pipeline auditing\n&#8211; <strong>GitHub<\/strong> (also Microsoft) for repo hosting and CI\/CD interoperability (choose based on org standards)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Why use Azure DevOps?<\/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 delivery with governance:<\/strong> approvals, environments, and audit history support controlled releases.<\/li>\n<li><strong>Traceability:<\/strong> link work items \u2194 commits \u2194 pull requests \u2194 builds \u2194 releases.<\/li>\n<li><strong>Standardization:<\/strong> reusable pipeline templates, shared agent pools, shared package feeds.<\/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>CI\/CD depth:<\/strong> multi-stage pipelines, deployment strategies, approvals, and environment modeling.<\/li>\n<li><strong>Strong Git workflow support:<\/strong> branch policies, required reviewers, build validation, code owners (via policies), PR checks.<\/li>\n<li><strong>Enterprise extensibility:<\/strong> REST APIs, service hooks, marketplace extensions.<\/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>Repeatability:<\/strong> builds and deployments become \u201crunbooks as code.\u201d<\/li>\n<li><strong>Observability for delivery:<\/strong> pipeline logs, test reports, artifacts, release history.<\/li>\n<li><strong>Integration-friendly:<\/strong> works with Kubernetes, VMs, PaaS, and on-prem deployments via self-hosted agents.<\/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>Entra ID integration:<\/strong> SSO, MFA, Conditional Access (tenant-controlled).<\/li>\n<li><strong>Fine-grained permissions:<\/strong> org\/project\/repo\/pipeline-level permissions.<\/li>\n<li><strong>Auditing:<\/strong> organization auditing features (availability can depend on configuration and licensing\u2014verify).<\/li>\n<li><strong>Protected branches &amp; environments:<\/strong> reduce risk of unreviewed changes reaching production.<\/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>Scales across many projects and teams.<\/li>\n<li>Supports distributed build capacity through <strong>self-hosted agents<\/strong> and <strong>agent pools<\/strong>.<\/li>\n<li>Supports large repos and complex release orchestration (within documented limits).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should choose Azure DevOps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You want an integrated suite: work tracking + repos + pipelines + artifacts in one place.<\/li>\n<li>You need enterprise controls around PRs, environments, and approvals.<\/li>\n<li>You operate in a Microsoft-centric environment (Entra ID, Azure, Windows, .NET), though it works well for Linux and containers too.<\/li>\n<li>You need both cloud and on-prem delivery options (Services + Server).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should not choose Azure DevOps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You want a <strong>single<\/strong> \u201csource-of-truth\u201d platform centered on GitHub features (Issues, Actions, Advanced Security) and your org standard is GitHub\u2014then consider GitHub as the primary platform.<\/li>\n<li>Your team heavily prefers GitLab\u2019s integrated DevSecOps model and already invested in GitLab runners and workflows.<\/li>\n<li>You require full offline\/air-gapped operations but cannot run Azure DevOps Server (or the required dependencies).<\/li>\n<li>You want minimal platform complexity and only need basic CI for a small repo\u2014lighter tools may be sufficient.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">4. Where is Azure DevOps used?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Industries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Financial services (controlled releases, auditing, gated deployments)<\/li>\n<li>Healthcare and life sciences (process and traceability)<\/li>\n<li>Government\/defense (often with Azure DevOps Server for restricted networks)<\/li>\n<li>Retail\/e-commerce (rapid releases with feature flags and staged rollouts)<\/li>\n<li>Manufacturing\/IoT (mixed edge + cloud deployments, sometimes hybrid connectivity)<\/li>\n<li>SaaS and ISVs (multi-tenant delivery, strong CI\/CD requirements)<\/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>Product engineering teams (full SDLC)<\/li>\n<li>Platform engineering teams (shared pipelines, templates, golden paths)<\/li>\n<li>SRE\/operations teams (release orchestration, compliance, incident-related changes)<\/li>\n<li>QA teams (manual test plans, test suites)<\/li>\n<li>Data\/ML teams (pipeline automation for training and deployment, though Azure ML has specialized pipelines)<\/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>Web apps and APIs<\/li>\n<li>Microservices (Kubernetes\/AKS)<\/li>\n<li>Mobile apps (Android\/iOS builds\u2014often with macOS agents for iOS)<\/li>\n<li>Infrastructure-as-Code (Bicep, Terraform)<\/li>\n<li>Data platforms (SQL projects, ETL, Synapse integration\u2014verify best-fit tooling)<\/li>\n<li>Legacy apps (Windows services, .NET Framework, on-prem deployments)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Architectures and deployment contexts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Single-service app with a single pipeline<\/li>\n<li>Microservices with pipeline templates + environment strategy<\/li>\n<li>Multi-tenant SaaS with separate release trains<\/li>\n<li>Hybrid: on-prem + Azure (self-hosted agents bridge private networks)<\/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> CI pipelines, feature branches, PR validation, test automation.<\/li>\n<li><strong>Production:<\/strong> gated deployments, approvals, change management workflows, audit and traceability.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. Top Use Cases and Scenarios<\/h2>\n\n\n\n<p>Below are realistic Azure DevOps use cases, each with the problem, why Azure DevOps fits, and a short scenario.<\/p>\n\n\n\n<p>1) <strong>Enterprise Git + PR governance<\/strong>\n&#8211; <strong>Problem:<\/strong> Teams need consistent PR reviews, build validation, and branch protections.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Branch policies, required reviewers, status checks, and build validations integrate tightly with pipelines.\n&#8211; <strong>Scenario:<\/strong> A bank enforces \u201c2 approvals + passing CI + linked work item\u201d before merge to <code>main<\/code>.<\/p>\n\n\n\n<p>2) <strong>CI for polyglot applications<\/strong>\n&#8211; <strong>Problem:<\/strong> A monorepo contains .NET, Node.js, and Python components with different build steps.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> YAML pipelines support matrices, templates, and multi-job workflows across platforms.\n&#8211; <strong>Scenario:<\/strong> One pipeline runs unit tests for each component and publishes versioned artifacts.<\/p>\n\n\n\n<p>3) <strong>CD with approvals and environments<\/strong>\n&#8211; <strong>Problem:<\/strong> Production deployments need human approval, change windows, and traceability.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Environments with approvals\/checks and multi-stage YAML pipelines.\n&#8211; <strong>Scenario:<\/strong> A release to production requires CAB approval, then deploys to AKS with rollout steps.<\/p>\n\n\n\n<p>4) <strong>Hybrid deployments via self-hosted agents<\/strong>\n&#8211; <strong>Problem:<\/strong> You must deploy to on-prem servers not reachable from the internet.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Self-hosted agents inside the network pull jobs securely; no inbound firewall openings required for the agent.\n&#8211; <strong>Scenario:<\/strong> A manufacturing plant deploys a service to on-prem Windows servers using a self-hosted agent.<\/p>\n\n\n\n<p>5) <strong>Infrastructure-as-Code (IaC) pipelines<\/strong>\n&#8211; <strong>Problem:<\/strong> Manual infrastructure changes cause drift and outages.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Pipelines can validate, plan, and apply IaC with approvals and environments.\n&#8211; <strong>Scenario:<\/strong> A platform team runs Terraform plan on PR, then applies after approval to dev\/stage\/prod.<\/p>\n\n\n\n<p>6) <strong>Internal package management<\/strong>\n&#8211; <strong>Problem:<\/strong> Teams need private dependencies and controlled package promotion.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Azure Artifacts provides private feeds with upstream sources and permissions.\n&#8211; <strong>Scenario:<\/strong> A company hosts internal NuGet packages and controls which teams can publish.<\/p>\n\n\n\n<p>7) <strong>Agile planning and traceability<\/strong>\n&#8211; <strong>Problem:<\/strong> Requirements, bugs, and tasks are tracked in one tool, but code lives elsewhere with weak linkage.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Boards + Repos + Pipelines are natively linked; work items can reference commits\/PRs.\n&#8211; <strong>Scenario:<\/strong> A team uses sprint boards and links PRs to user stories for audit.<\/p>\n\n\n\n<p>8) <strong>Regulated testing workflows<\/strong>\n&#8211; <strong>Problem:<\/strong> Manual test execution needs documented results and sign-off.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Azure Test Plans provides test cases, suites, parameters, and runs with traceability.\n&#8211; <strong>Scenario:<\/strong> A healthcare app team executes manual regression tests and exports evidence for audits.<\/p>\n\n\n\n<p>9) <strong>Multi-team shared pipeline templates (platform engineering)<\/strong>\n&#8211; <strong>Problem:<\/strong> Each team builds pipelines differently; maintenance and security vary.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> YAML templates and centralized repos enable standardized pipelines.\n&#8211; <strong>Scenario:<\/strong> A platform team provides a \u201cgolden pipeline\u201d template with SAST, tests, and artifact signing steps.<\/p>\n\n\n\n<p>10) <strong>Release notes and deployment audit<\/strong>\n&#8211; <strong>Problem:<\/strong> Teams need to know what changed, who approved it, and what version is running.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Release pipeline history, artifacts, build metadata, environment deployments.\n&#8211; <strong>Scenario:<\/strong> Ops checks deployment history to correlate incidents with releases.<\/p>\n\n\n\n<p>11) <strong>Migration from TFVC\/TFS to Git<\/strong>\n&#8211; <strong>Problem:<\/strong> Legacy version control limits modern PR-based workflows.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Azure Repos supports Git and provides migration paths from TFVC (often as part of broader modernization).\n&#8211; <strong>Scenario:<\/strong> A legacy team migrates from TFVC to Git and implements PR validation.<\/p>\n\n\n\n<p>12) <strong>Centralized delivery across multiple Azure subscriptions<\/strong>\n&#8211; <strong>Problem:<\/strong> Many subscriptions (dev\/prod\/regions) need consistent deployment orchestration.\n&#8211; <strong>Why Azure DevOps fits:<\/strong> Service connections and environments can model target subscriptions and approval gates.\n&#8211; <strong>Scenario:<\/strong> A global org deploys the same app to multiple regions and subscriptions with stage-by-stage approvals.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Core Features<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Azure Boards<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Work item tracking (Epics\/Features\/User Stories\/Tasks\/Bugs), Kanban boards, sprint planning, dashboards, queries.<\/li>\n<li><strong>Why it matters:<\/strong> Provides a system of record for delivery work, tying planning to execution.<\/li>\n<li><strong>Practical benefit:<\/strong> Traceability and reporting (velocity, burndown).<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Reporting capabilities depend on configuration and available analytics features; advanced reporting may require configuration or additional tools (verify your org\u2019s Analytics availability).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Azure Repos (Git)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Hosts private Git repos with pull requests, policies, code reviews, and permissions.<\/li>\n<li><strong>Why it matters:<\/strong> Enables enterprise-grade governance around changes.<\/li>\n<li><strong>Practical benefit:<\/strong> Required reviewers, build validation, and PR workflows reduce defects.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Some advanced code scanning\/security features are not identical to GitHub Advanced Security; evaluate based on your DevSecOps requirements.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Azure Pipelines<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> CI\/CD using YAML or classic pipelines; supports builds, tests, artifact publishing, and multi-stage deployments.<\/li>\n<li><strong>Why it matters:<\/strong> Automates delivery with consistent, repeatable workflows.<\/li>\n<li><strong>Practical benefit:<\/strong> Faster feedback loops, reliable deployments, standardized pipelines via templates.<\/li>\n<li><strong>Limitations\/caveats:<\/strong><\/li>\n<li>Microsoft-hosted agents have concurrency\/minute constraints based on your plan.<\/li>\n<li>Network access from hosted agents uses shared IP ranges; locking down firewalls requires planning (service tags\/IP ranges; verify current guidance).<\/li>\n<li>Some features differ between YAML and classic pipelines\u2014prefer YAML for versioned pipelines and reuse.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Azure Test Plans<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Manual test cases, suites, plans, test runs, exploratory testing integration.<\/li>\n<li><strong>Why it matters:<\/strong> Supports teams where manual validation is required (compliance, usability, regression).<\/li>\n<li><strong>Practical benefit:<\/strong> Repeatable manual testing with evidence and history.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Typically licensed separately (Test Plans access level). Confirm licensing requirements on the official pricing page.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Azure Artifacts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Hosts internal package feeds (NuGet, npm, Maven, Python, Universal Packages) with permissions and upstream sources.<\/li>\n<li><strong>Why it matters:<\/strong> Reduces supply chain risk and improves dependency management.<\/li>\n<li><strong>Practical benefit:<\/strong> Centralized dependency hosting, caching of upstream packages, controlled publishing.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Storage is a cost driver; retention and cleanup policies matter to avoid surprise bills.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Service Connections<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Securely connects Azure DevOps to external systems (Azure subscriptions, container registries, Kubernetes clusters, etc.).<\/li>\n<li><strong>Why it matters:<\/strong> Enables deployments without embedding credentials in code.<\/li>\n<li><strong>Practical benefit:<\/strong> Central place to manage deployment identities and permissions.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Use least privilege; prefer workload identity federation where available to avoid long-lived secrets (verify current recommended method in docs).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Environments, approvals, and checks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Models deployment targets (dev\/stage\/prod) and supports approvals and checks (manual approvals, business hours, branch control, etc. depending on configuration).<\/li>\n<li><strong>Why it matters:<\/strong> Adds safe gates for production.<\/li>\n<li><strong>Practical benefit:<\/strong> Reduces accidental releases; improves auditability.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Ensure environment permissions are locked down; otherwise, approvals are meaningless.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Branch policies and PR validations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Enforces required reviews, comment resolution, linked work items, successful builds, and more.<\/li>\n<li><strong>Why it matters:<\/strong> Raises code quality and compliance.<\/li>\n<li><strong>Practical benefit:<\/strong> Prevents direct pushes to protected branches and untested merges.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Overly strict policies can slow delivery; tune based on risk and team maturity.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Marketplace extensions and integrations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Adds capabilities (scanners, reporting, integrations) via the Azure DevOps Marketplace.<\/li>\n<li><strong>Why it matters:<\/strong> Extends Azure DevOps without custom building everything.<\/li>\n<li><strong>Practical benefit:<\/strong> Faster adoption of additional tooling.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Evaluate extension publisher trust, permissions requested, and data handling.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">REST APIs and service hooks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Programmatic access to most entities (work items, repos, builds, releases) and event hooks to external systems.<\/li>\n<li><strong>Why it matters:<\/strong> Enables automation and integration with ITSM, chatops, and internal platforms.<\/li>\n<li><strong>Practical benefit:<\/strong> Build internal portals, provisioning, standardized project creation.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> API rate limits and permission scopes apply; use service principals\/OAuth carefully and avoid overly broad PATs.<\/li>\n<\/ul>\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 DevOps Services is a SaaS platform accessed via:\n&#8211; Web UI\n&#8211; Git over HTTPS\/SSH\n&#8211; REST APIs\n&#8211; Agents (Microsoft-hosted or self-hosted) that execute pipeline jobs<\/p>\n\n\n\n<p>The typical flow:\n1. Developer pushes code to Azure Repos (or connects external repos).\n2. A pipeline trigger starts a build on an agent.\n3. The agent fetches source code, runs build\/test steps, and publishes artifacts.\n4. For CD, a deployment job uses a service connection to deploy to a target environment (Azure, Kubernetes, VMs, on-prem).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Request\/data\/control flow considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control plane:<\/strong> Azure DevOps orchestrates pipeline scheduling, approvals, and permissions.<\/li>\n<li><strong>Data plane:<\/strong> Repos store code; pipeline logs and artifacts are stored per pipeline run; artifacts and packages may have separate retention and storage behavior.<\/li>\n<li><strong>Agent execution:<\/strong> Agents pull jobs from Azure DevOps (important for firewall design). Self-hosted agents typically require outbound connectivity to Azure DevOps endpoints.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Integrations with related services<\/h3>\n\n\n\n<p>Common integrations in Azure ecosystems:\n&#8211; <strong>Microsoft Entra ID:<\/strong> SSO and access management\n&#8211; <strong>Azure Key Vault:<\/strong> secrets retrieval during pipeline runs\n&#8211; <strong>Azure Container Registry (ACR):<\/strong> build\/push container images\n&#8211; <strong>Azure Kubernetes Service (AKS):<\/strong> deploy via kubectl\/Helm tasks\n&#8211; <strong>Azure App Service:<\/strong> deploy web apps\n&#8211; <strong>Azure Monitor \/ Application Insights:<\/strong> app telemetry after deployment\n&#8211; <strong>Azure Policy \/ Defender for Cloud:<\/strong> governance and security posture for deployed resources (not Azure DevOps itself)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dependency services<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Source control and identity are foundational dependencies.<\/li>\n<li>For deployments: target platform dependencies (ARM, Kubernetes API, etc.).<\/li>\n<li>For secure secrets: Key Vault (recommended) or secure pipeline variables.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/authentication model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Human users:<\/strong> typically authenticate via Entra ID (recommended).<\/li>\n<li><strong>Automation:<\/strong> can use service principals via service connections; PATs for certain API operations (prefer short-lived or scoped where possible).<\/li>\n<li><strong>Repo access:<\/strong> HTTPS with tokens or SSH keys.<\/li>\n<li><strong>Permissions model:<\/strong> layered permissions at org, project, repo, pipeline, environment, and agent pool levels.<\/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>Azure DevOps Services is internet-accessible SaaS.<\/li>\n<li>To reach private resources (private VNets\/on-prem), use:<\/li>\n<li><strong>Self-hosted agents<\/strong> within the network<\/li>\n<li>Private connectivity patterns for target resources (private endpoints, VPN\/ExpressRoute)<\/li>\n<li>IP allowlisting for Microsoft-hosted agents can be challenging due to shared outbound IP ranges; prefer self-hosted agents for strict egress controls.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Monitoring\/logging\/governance<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pipeline run logs provide operational data for builds\/deployments.<\/li>\n<li>Audit logs (where available) support security investigations.<\/li>\n<li>Governance is implemented using:<\/li>\n<li>branch policies<\/li>\n<li>environment approvals\/checks<\/li>\n<li>role-based permissions<\/li>\n<li>naming conventions and project structures<\/li>\n<li>retention policies for runs\/artifacts<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Simple architecture diagram (conceptual)<\/h4>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart LR\n  Dev[Developer] --&gt;|git push \/ PR| Repos[Azure Repos]\n  Repos --&gt;|CI trigger| Pipelines[Azure Pipelines]\n  Pipelines --&gt; Agent[Build Agent\\n(Microsoft-hosted or self-hosted)]\n  Agent --&gt;|build\/test| Logs[Pipeline Logs]\n  Agent --&gt;|publish| Art[Pipeline Artifacts]\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Production-style architecture diagram (more complete)<\/h4>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart TB\n  subgraph Identity[Identity &amp; Access]\n    AAD[Microsoft Entra ID]\n  end\n\n  subgraph ADO[Azure DevOps Organization]\n    Boards[Azure Boards]\n    Repos[Azure Repos]\n    Pipes[Azure Pipelines]\n    Env[Environments\\nApprovals &amp; Checks]\n    Artifacts[Azure Artifacts]\n    Audit[Auditing\/Logs]\n  end\n\n  Devs[Engineers] --&gt;|SSO| AAD\n  AAD --&gt; ADO\n\n  Devs --&gt;|PRs link work items| Boards\n  Devs --&gt;|git push \/ PR| Repos\n  Repos --&gt;|CI| Pipes\n\n  subgraph BuildNet[Build Network Boundary]\n    Hosted[Microsoft-hosted agents]\n    SelfHosted[Self-hosted agents\\n(in VNet\/on-prem)]\n  end\n\n  Pipes --&gt; Hosted\n  Pipes --&gt; SelfHosted\n\n  SelfHosted --&gt; KV[Azure Key Vault]\n  SelfHosted --&gt; ACR[Azure Container Registry]\n  SelfHosted --&gt;|deploy| AKS[Azure Kubernetes Service]\n  SelfHosted --&gt;|deploy| AppSvc[Azure App Service]\n\n  Env --&gt;|gates| Pipes\n  Pipes --&gt; Artifacts\n  Pipes --&gt; Audit\n  AKS --&gt; Monitor[Azure Monitor \/ App Insights]\n  AppSvc --&gt; Monitor\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">8. Prerequisites<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Account\/tenant requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An Azure DevOps <strong>organization<\/strong> in Azure DevOps Services, or permission to create one.<\/li>\n<li>A <strong>project<\/strong> within the organization (or permission to create projects).<\/li>\n<\/ul>\n\n\n\n<p>Start here (official): https:\/\/learn.microsoft.com\/azure\/devops\/organizations\/accounts\/create-organization<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Permissions \/ IAM roles<\/h3>\n\n\n\n<p>You will need one of the following:\n&#8211; <strong>Organization Owner \/ Project Collection Administrator<\/strong> (broadest), or\n&#8211; <strong>Project Administrator<\/strong> to create repos and pipelines, plus\n&#8211; Permissions to create service connections (not required for the lab in this tutorial unless you deploy to Azure)<\/p>\n\n\n\n<p>For repos and pipelines:\n&#8211; Ability to create a repository or push to an existing repo\n&#8211; Ability to create\/edit pipelines<\/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 setting up billing for additional users, parallel jobs, artifacts storage, or test plans depending on usage.<\/li>\n<li>For this tutorial\u2019s basic pipeline lab, you can often stay within free entitlements, but <strong>verify current free limits<\/strong> on the official pricing pages.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tools needed (local workstation)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Git<\/strong> (required)<\/li>\n<li>One of:<\/li>\n<li>A code editor (VS Code recommended)<\/li>\n<li>Optional: <strong>Azure CLI<\/strong> + Azure DevOps extension (for CLI-based setup)<\/li>\n<\/ul>\n\n\n\n<p>Azure CLI install: https:\/\/learn.microsoft.com\/cli\/azure\/install-azure-cli<br\/>\nAzure 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 a global SaaS; organization data location choices exist. Choose a region\/geo aligned with compliance requirements (verify current options).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quotas\/limits (common ones to be aware of)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pipeline parallelism and hosted minutes (plan-dependent)<\/li>\n<li>Artifact\/package storage (plan-dependent)<\/li>\n<li>Repo size\/performance considerations at large scale<\/li>\n<\/ul>\n\n\n\n<p>Limits change over time\u2014verify in official docs:\nhttps:\/\/learn.microsoft.com\/azure\/devops\/organizations\/settings\/limits?view=azure-devops (verify exact URL\/section in current docs)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisite services (optional)<\/h3>\n\n\n\n<p>Not required for the lab, but commonly used:\n&#8211; Azure Key Vault\n&#8211; Azure Container Registry\n&#8211; Azure App Service \/ AKS\n&#8211; Log Analytics \/ Application Insights<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">9. Pricing \/ Cost<\/h2>\n\n\n\n<p>Azure DevOps pricing is best understood as a set of <strong>dimensions<\/strong> rather than a single \u201cper-resource\u201d cost.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Official pricing pages (verify current details)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure DevOps pricing overview: https:\/\/azure.microsoft.com\/pricing\/details\/devops\/<\/li>\n<li>Azure Pipelines pricing: https:\/\/azure.microsoft.com\/pricing\/details\/devops\/azure-pipelines\/<\/li>\n<li>Azure Test Plans pricing (typically included on the main DevOps pricing page): https:\/\/azure.microsoft.com\/pricing\/details\/devops\/<\/li>\n<li>Azure pricing calculator: https:\/\/azure.microsoft.com\/pricing\/calculator\/<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing dimensions<\/h3>\n\n\n\n<p>Common cost dimensions include:<\/p>\n\n\n\n<p>1) <strong>Users (access levels)<\/strong>\n&#8211; <strong>Basic<\/strong> access for most engineering users.\n&#8211; <strong>Stakeholder<\/strong> access for limited needs (work tracking and feedback; exact capabilities vary\u2014verify).\n&#8211; <strong>Basic + Test Plans<\/strong> for users needing Azure Test Plans features.<\/p>\n\n\n\n<p>A common model is:\n&#8211; A small number of Basic users may be free (often \u201cfirst 5 users\u201d in many plans historically), then per-user charges apply.\n&#8211; Stakeholder users may be free but limited.<\/p>\n\n\n\n<p>2) <strong>Azure Pipelines parallel jobs and hosted compute<\/strong>\n&#8211; Microsoft-hosted pipelines are commonly limited by:\n  &#8211; <strong>Parallel jobs<\/strong> (concurrency)\n  &#8211; <strong>Hosted minutes<\/strong> (time quotas)\n&#8211; Additional parallel jobs typically cost extra.\n&#8211; <strong>Self-hosted agents<\/strong> generally avoid Microsoft-hosted minutes charges, but you pay for the compute you run them on (VMs, scale sets, Kubernetes, etc.).<\/p>\n\n\n\n<p>Because quotas and free tiers change, <strong>do not assume exact free minutes<\/strong>\u2014confirm on the official Pipelines pricing page.<\/p>\n\n\n\n<p>3) <strong>Azure Artifacts storage and data<\/strong>\n&#8211; Azure Artifacts charges are commonly based on <strong>storage used<\/strong> beyond an included amount.\n&#8211; Retention and cleanup policies significantly impact cost.<\/p>\n\n\n\n<p>4) <strong>Azure DevOps Server (self-hosted)<\/strong>\n&#8211; Uses a different cost structure:\n  &#8211; server licensing + CALs (Client Access Licenses) and\/or Visual Studio subscriptions (details vary by agreement).\n&#8211; Infrastructure costs are yours (VMs, SQL Server, backups, HA\/DR).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Free tier (what to expect)<\/h3>\n\n\n\n<p>Many organizations can start cheaply because:\n&#8211; Small teams may qualify for free Basic seats.\n&#8211; Open-source\/public projects may have generous CI allowances.\n&#8211; Self-hosted agents can reduce or eliminate hosted pipeline compute charges (but shift cost to your infrastructure).<\/p>\n\n\n\n<p><strong>Verify<\/strong> the current free entitlements for:\n&#8211; number of free users\n&#8211; hosted CI minutes\n&#8211; artifact storage included<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cost drivers (direct)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Number of Basic and Test Plans users<\/li>\n<li>Number of parallel jobs (especially Microsoft-hosted)<\/li>\n<li>Artifact storage growth (packages + pipeline artifacts)<\/li>\n<li>Test Plans licensing<\/li>\n<li>Marketplace extensions that add paid features<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hidden or indirect costs<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Self-hosted agent compute:<\/strong> VMs, disks, patching, scaling, and security hardening<\/li>\n<li><strong>Build cache and artifact retention:<\/strong> long retention policies increase storage use<\/li>\n<li><strong>Network egress:<\/strong> moving large artifacts across regions or to on-prem can incur bandwidth costs (depending on where the storage and consumers are)<\/li>\n<li><strong>Operational overhead:<\/strong> governance, permission reviews, auditing processes<\/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>If your pipeline downloads dependencies from external registries or pushes large images to registries, network costs may appear on:<\/li>\n<li>your artifact stores (ACR, external registries)<\/li>\n<li>your build agents (if in Azure, egress might apply depending on destination)<\/li>\n<li>For strict data residency, consider self-hosted agents and controlling where artifacts\/packages are stored.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How to optimize cost<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prefer <strong>self-hosted agents<\/strong> for heavy CI workloads (when security and operations allow).<\/li>\n<li>Reduce artifact retention:<\/li>\n<li>Keep only the last N successful builds for non-release branches.<\/li>\n<li>Store release artifacts longer than dev artifacts.<\/li>\n<li>Use pipeline caching where appropriate (language\/package caches) to reduce build time and hosted minutes.<\/li>\n<li>Consolidate parallelism: avoid unnecessary fan-out builds.<\/li>\n<li>Use upstream sources and dependency management to reduce duplicate packages.<\/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 typical low-cost starter setup:\n&#8211; Small team using Azure DevOps Services\n&#8211; A few Basic users (may fit within a free tier depending on current entitlements)\n&#8211; One CI pipeline running on Microsoft-hosted agents with limited monthly minutes\n&#8211; Minimal Azure Artifacts storage<\/p>\n\n\n\n<p>Your actual cost depends on:\n&#8211; whether your users exceed the free seat count\n&#8211; whether you exceed included hosted minutes and parallelism\n&#8211; how long you retain artifacts\/logs<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example production cost considerations<\/h3>\n\n\n\n<p>In production, cost planning should include:\n&#8211; Dozens\/hundreds of Basic users (+ Test Plans for QA roles)\n&#8211; Multiple parallel jobs for CI and CD\n&#8211; Large artifact storage for many services and frequent releases\n&#8211; Self-hosted agent fleet (VMSS, Kubernetes-based agents) with autoscaling\n&#8211; Governance time (platform engineering and security reviews)<\/p>\n\n\n\n<p>For accurate estimates, use:\n&#8211; Azure DevOps pricing page(s)\n&#8211; Azure pricing calculator\n&#8211; Your expected pipeline minutes, concurrency, and artifact growth rates<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Step-by-Step Hands-On Tutorial<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Objective<\/h3>\n\n\n\n<p>Create an Azure DevOps project with an Azure Repos Git repository and a YAML-based Azure Pipelines CI workflow that:\n&#8211; runs unit tests for a small Python project\n&#8211; publishes a pipeline artifact\n&#8211; demonstrates traceability by linking a commit to a work item<\/p>\n\n\n\n<p>This lab avoids deploying to Azure resources to keep cost and risk low.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab Overview<\/h3>\n\n\n\n<p>You will:\n1. Create a project and repo in Azure DevOps.\n2. Create a simple Python app + unit test locally.\n3. Push code to Azure Repos.\n4. Create a YAML pipeline (<code>azure-pipelines.yml<\/code>) and run CI on Microsoft-hosted agents.\n5. Validate pipeline results and artifact publication.\n6. (Optional) Link work items and commits for traceability.\n7. Clean up the project to avoid ongoing usage.<\/p>\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>Go to Azure DevOps: https:\/\/dev.azure.com\/<\/li>\n<li>Sign in with your Microsoft Entra ID (work\/school) or Microsoft account (depending on your setup).<\/li>\n<li>Create an <strong>organization<\/strong> if you don\u2019t already have one.<\/li>\n<li>Create a new <strong>project<\/strong>:\n   &#8211; Project name: <code>ado-lab-python-ci<\/code>\n   &#8211; Visibility: Private (recommended for most labs)\n   &#8211; Version control: Git\n   &#8211; Work item process: Agile (any is fine)<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> You can open the project, see the left navigation (Boards, Repos, Pipelines, etc.), and the project summary.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Create a new Git repository (Azure Repos)<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In the project, go to <strong>Repos<\/strong>.<\/li>\n<li>If prompted, create a repository named: <code>python-ci-demo<\/code><\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> You see an empty repo with clone instructions (HTTPS\/SSH).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create a simple Python project locally<\/h3>\n\n\n\n<p>On your machine, create a new folder and files:<\/p>\n\n\n\n<pre><code class=\"language-bash\">mkdir python-ci-demo\ncd python-ci-demo\n<\/code><\/pre>\n\n\n\n<p>Create a minimal app file:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat &gt; app.py &lt;&lt;'EOF'\ndef add(a: int, b: int) -&gt; int:\n    return a + b\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\nEOF\n<\/code><\/pre>\n\n\n\n<p>Create a test file:<\/p>\n\n\n\n<pre><code class=\"language-bash\">mkdir -p tests\ncat &gt; tests\/test_app.py &lt;&lt;'EOF'\nfrom app import add\n\ndef test_add():\n    assert add(2, 3) == 5\nEOF\n<\/code><\/pre>\n\n\n\n<p>Add requirements for testing:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat &gt; requirements.txt &lt;&lt;'EOF'\npytest==8.*\nEOF\n<\/code><\/pre>\n\n\n\n<p>Optionally, create a <code>.gitignore<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat &gt; .gitignore &lt;&lt;'EOF'\n__pycache__\/\n.pytest_cache\/\n.venv\/\nEOF\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> You have a runnable mini project with a unit test.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Initialize Git and push to Azure Repos<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In Azure DevOps repo page, copy the <strong>clone URL<\/strong> (HTTPS is simplest).<\/li>\n<li>Initialize and push:<\/li>\n<\/ol>\n\n\n\n<pre><code class=\"language-bash\">git init\ngit add .\ngit commit -m \"Initial Python app with tests\"\ngit branch -M main\ngit remote add origin &lt;PASTE_YOUR_AZURE_REPOS_CLONE_URL_HERE&gt;\ngit push -u origin main\n<\/code><\/pre>\n\n\n\n<p>If prompted for credentials, use:\n&#8211; Entra ID sign-in flow in your Git Credential Manager, or\n&#8211; A Personal Access Token (PAT) if required by your environment<\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> Azure Repos shows your files on the <code>main<\/code> branch.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Add a YAML pipeline definition<\/h3>\n\n\n\n<p>Create a file named <code>azure-pipelines.yml<\/code> in your repo root:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat &gt; azure-pipelines.yml &lt;&lt;'EOF'\ntrigger:\n  branches:\n    include:\n      - main\n\npool:\n  vmImage: 'ubuntu-latest'\n\nsteps:\n  - task: UsePythonVersion@0\n    inputs:\n      versionSpec: '3.x'\n    displayName: 'Use Python 3'\n\n  - script: |\n      python -m pip install --upgrade pip\n      pip install -r requirements.txt\n    displayName: 'Install dependencies'\n\n  - script: |\n      pytest -q\n    displayName: 'Run unit tests'\n\n  - script: |\n      mkdir -p out\n      cp app.py out\/\n      cp -r tests out\/\n      cp requirements.txt out\/\n    displayName: 'Stage files for artifact'\n\n  - task: PublishPipelineArtifact@1\n    inputs:\n      targetPath: 'out'\n      artifact: 'drop'\n    displayName: 'Publish pipeline artifact'\nEOF\n<\/code><\/pre>\n\n\n\n<p>Commit and push:<\/p>\n\n\n\n<pre><code class=\"language-bash\">git add azure-pipelines.yml\ngit commit -m \"Add Azure Pipelines CI workflow\"\ngit push\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> The repo now contains <code>azure-pipelines.yml<\/code> on <code>main<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Create and run the pipeline in Azure DevOps<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <strong>Pipelines<\/strong> \u2192 <strong>Create Pipeline<\/strong>.<\/li>\n<li>Select <strong>Azure Repos Git<\/strong>.<\/li>\n<li>Select your repo: <code>python-ci-demo<\/code>.<\/li>\n<li>Choose <strong>Existing Azure Pipelines YAML file<\/strong>.<\/li>\n<li>Select branch: <code>main<\/code>, path: <code>\/azure-pipelines.yml<\/code>.<\/li>\n<li>Click <strong>Run<\/strong>.<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> A pipeline run starts. You should see jobs execute on <code>ubuntu-latest<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7: Review logs, test results, and published artifact<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the pipeline run.<\/li>\n<li>\n<p>Check each step:\n   &#8211; \u201cInstall dependencies\u201d\n   &#8211; \u201cRun unit tests\u201d\n   &#8211; \u201cPublish pipeline artifact\u201d<\/p>\n<\/li>\n<li>\n<p>Confirm the artifact:\n   &#8211; In the run summary, open <strong>Artifacts<\/strong>\n   &#8211; Download the <code>drop<\/code> artifact and confirm it contains <code>app.py<\/code>, <code>tests\/<\/code>, <code>requirements.txt<\/code><\/p>\n<\/li>\n<\/ol>\n\n\n\n<p><strong>Expected outcome:<\/strong> Pipeline run is green (success), and <code>drop<\/code> artifact is available.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 8 (Optional): Add a work item and link it to a commit for traceability<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <strong>Boards<\/strong> \u2192 <strong>Work Items<\/strong> \u2192 <strong>New Work Item<\/strong> (e.g., User Story or Task).<\/li>\n<li>Title: <code>Add CI pipeline for Python demo<\/code><\/li>\n<li>Save it and note the ID (for example, <code>#12<\/code>).<\/li>\n<\/ol>\n\n\n\n<p>Now make a small change and reference the work item ID in the commit message using the Azure Boards linking pattern:<\/p>\n\n\n\n<pre><code class=\"language-bash\">echo \"# small change\" &gt;&gt; README.md\ngit add README.md\ngit commit -m \"Docs: add README note AB#12\"\ngit push\n<\/code><\/pre>\n\n\n\n<p>Then:\n&#8211; Open the work item in Boards\n&#8211; Check <strong>Development<\/strong> section (or links) to see the commit association (UI varies)<\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> The work item shows a linked commit, improving traceability.<\/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 checklist:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Repo validation<\/strong><\/li>\n<li>You can browse repo files in Azure Repos.<\/li>\n<li>\n<p><code>azure-pipelines.yml<\/code> is present on <code>main<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>Pipeline validation<\/strong><\/p>\n<\/li>\n<li>Pipeline run completes successfully.<\/li>\n<li>Logs show <code>pytest<\/code> executed and passed.<\/li>\n<li>\n<p>Artifact named <code>drop<\/code> exists and is downloadable.<\/p>\n<\/li>\n<li>\n<p><strong>Traceability validation (optional)<\/strong><\/p>\n<\/li>\n<li>Work item shows a link to the commit referencing <code>AB#&lt;id&gt;<\/code>.<\/li>\n<\/ul>\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><strong>Issue: Pipeline can\u2019t find <code>pytest<\/code><\/strong>\n&#8211; Confirm <code>requirements.txt<\/code> is in the repo root.\n&#8211; Check the \u201cInstall dependencies\u201d step output.\n&#8211; Ensure the pipeline runs <code>pip install -r requirements.txt<\/code> before running tests.<\/p>\n\n\n\n<p><strong>Issue: <code>UsePythonVersion@0<\/code> task fails<\/strong>\n&#8211; Confirm you used <code>ubuntu-latest<\/code> pool.\n&#8211; If your org restricts tasks\/marketplace, verify built-in task availability.<\/p>\n\n\n\n<p><strong>Issue: Authentication failures when pushing to Azure Repos<\/strong>\n&#8211; Use Git Credential Manager and sign in with the correct account.\n&#8211; If PAT is required, create one with minimal scopes (Repo read\/write) and store it securely.\n&#8211; Verify org policies (some orgs require MFA\/Conditional Access).<\/p>\n\n\n\n<p><strong>Issue: Pipeline doesn\u2019t trigger on push<\/strong>\n&#8211; Confirm <code>trigger<\/code> includes the correct branch name (<code>main<\/code>).\n&#8211; Confirm you pushed to <code>main<\/code>, not <code>master<\/code>.\n&#8211; Confirm pipeline is created and pointing to the correct YAML path.<\/p>\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:\n1. Delete the pipeline:\n   &#8211; <strong>Pipelines<\/strong> \u2192 select pipeline \u2192 <strong>\u2026<\/strong> \u2192 <strong>Delete<\/strong>\n2. Delete the project (removes repos, boards, artifacts):\n   &#8211; <strong>Project settings<\/strong> \u2192 <strong>Overview<\/strong> \u2192 <strong>Delete<\/strong>\n3. If you created PATs, revoke them:\n   &#8211; User settings \u2192 <strong>Personal access tokens<\/strong> \u2192 Revoke\/delete<\/p>\n\n\n\n<p><strong>Expected outcome:<\/strong> Resources associated with the lab are removed, minimizing future costs and risk.<\/p>\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>Adopt YAML pipelines<\/strong> for versioning, code review, and reuse.<\/li>\n<li>Use <strong>pipeline templates<\/strong> stored in a central repo for consistent patterns.<\/li>\n<li>Create a clear <strong>environment strategy<\/strong> (dev\/test\/stage\/prod) with approvals and checks.<\/li>\n<li>Separate CI and CD concerns:<\/li>\n<li>CI validates every PR and merge.<\/li>\n<li>CD promotes signed\/versioned artifacts through environments.<\/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>Integrate with <strong>Microsoft Entra ID<\/strong> (SSO + MFA + Conditional Access).<\/li>\n<li>Use <strong>least privilege<\/strong>:<\/li>\n<li>Lock down who can create service connections.<\/li>\n<li>Restrict who can approve deployments to production.<\/li>\n<li>Limit who can administer agent pools.<\/li>\n<li>Prefer <strong>workload identity federation<\/strong> for Azure deployments where supported, to avoid long-lived secrets (verify current guidance in docs).<\/li>\n<li>Reduce PAT usage; if needed:<\/li>\n<li>use minimal scopes<\/li>\n<li>set expiration<\/li>\n<li>rotate regularly<\/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>Use <strong>self-hosted agents<\/strong> for heavy workloads if it reduces hosted compute usage cost-effectively.<\/li>\n<li>Implement <strong>retention policies<\/strong> for pipelines and artifacts.<\/li>\n<li>Minimize artifact size; store only what you need for releases.<\/li>\n<li>Use caching (language\/package caches) to reduce build time.<\/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>Parallelize tests judiciously (only where it reduces wall-clock time without exploding concurrency costs).<\/li>\n<li>Use incremental builds and caching where supported.<\/li>\n<li>Keep pipelines deterministic: pin tool versions where appropriate.<\/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>Use deployment rings (dev \u2192 stage \u2192 prod).<\/li>\n<li>Add rollback strategies:<\/li>\n<li>redeploy previous artifact<\/li>\n<li>blue\/green or canary where applicable (often implemented in your platform such as AKS\/App Service)<\/li>\n<li>Make pipelines idempotent (safe to re-run).<\/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>Standardize logging and artifact naming conventions.<\/li>\n<li>Use environments and approvals to reduce human error.<\/li>\n<li>Document \u201cbreak glass\u201d procedures (who can bypass approvals, when, and how it\u2019s audited).<\/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>Define organization standards:<\/li>\n<li>Project naming<\/li>\n<li>Repo naming<\/li>\n<li>Pipeline naming<\/li>\n<li>Branch naming (<code>main<\/code>, <code>release\/*<\/code>, <code>hotfix\/*<\/code>)<\/li>\n<li>Define policy baselines:<\/li>\n<li>required PR reviews<\/li>\n<li>build validations<\/li>\n<li>required linked work items (where needed)<\/li>\n<li>Review permissions quarterly.<\/li>\n<\/ul>\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 commonly uses <strong>Microsoft Entra ID<\/strong> identities and groups.<\/li>\n<li>Permissions exist at multiple levels:<\/li>\n<li>organization<\/li>\n<li>project<\/li>\n<li>repo<\/li>\n<li>pipeline<\/li>\n<li>environment<\/li>\n<li>agent pool<\/li>\n<li>Use groups (not individuals) for manageability.<\/li>\n<\/ul>\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 as part of Microsoft\u2019s cloud service baseline. For compliance-specific requirements (keys, CMK, etc.), <strong>verify in official docs<\/strong> for what is supported and under what plans.<\/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>Azure DevOps Services is reachable over the internet.<\/li>\n<li>For sensitive deployments:<\/li>\n<li>avoid opening inbound firewall ports to your private network<\/li>\n<li>use self-hosted agents that initiate outbound connections<\/li>\n<li>For firewall allowlisting, use Microsoft\u2019s published endpoints\/service tags\/IP ranges guidance (verify current documentation; IPs can change).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secrets handling<\/h3>\n\n\n\n<p>Preferred patterns:\n&#8211; Use <strong>Azure Key Vault<\/strong> and retrieve secrets at runtime.\n&#8211; Use pipeline secret variables only when necessary.\n&#8211; Avoid storing secrets in:\n  &#8211; repo files\n  &#8211; pipeline YAML\n  &#8211; build logs (ensure scripts do not echo secrets)<\/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 audit capabilities where available.<\/li>\n<li>Monitor:<\/li>\n<li>changes to service connections<\/li>\n<li>pipeline permission changes<\/li>\n<li>agent pool administration<\/li>\n<li>environment approvals and bypass events<\/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>Data residency: choose organization data location aligned with requirements.<\/li>\n<li>Retention: define how long logs\/artifacts\/test evidence must be retained.<\/li>\n<li>Separation of duties: ensure developers can\u2019t self-approve production deployments unless policy allows.<\/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>Overusing PATs with broad scopes and no expiration.<\/li>\n<li>Letting too many users administer agent pools or service connections.<\/li>\n<li>Allowing pipelines to run untrusted code with high privileges (especially on self-hosted agents).<\/li>\n<li>Using Microsoft-hosted agents to deploy into private networks by punching firewall holes rather than using self-hosted agents.<\/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>Protect <code>main<\/code> with branch policies (PR required + build validation).<\/li>\n<li>Protect production environments with approvals\/checks.<\/li>\n<li>Use separate Azure subscriptions\/resource groups per environment and grant least privilege through service connections.<\/li>\n<li>Use isolated agent pools for high-risk pipelines.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">13. Limitations and Gotchas<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Hosted agent IP variability:<\/strong> Microsoft-hosted agents use shared infrastructure; outbound IPs can change. If you need strict network control, use self-hosted agents.<\/li>\n<li><strong>Parallelism constraints:<\/strong> Pipeline concurrency is limited by your plan. A sudden increase in CI usage can cause queue delays.<\/li>\n<li><strong>Artifact retention surprises:<\/strong> Keeping artifacts forever can quietly increase storage costs.<\/li>\n<li><strong>Self-hosted agent security:<\/strong> Self-hosted agents execute code\u2014treat them like privileged servers:<\/li>\n<li>isolate networks<\/li>\n<li>rotate credentials<\/li>\n<li>avoid running untrusted PR code on privileged agents<\/li>\n<li><strong>Permissions complexity:<\/strong> Fine-grained permissions are powerful but easy to misconfigure; document and review regularly.<\/li>\n<li><strong>YAML vs Classic differences:<\/strong> Some UI features differ; standardize on YAML unless you have a specific reason not to.<\/li>\n<li><strong>Marketplace extension risk:<\/strong> Extensions may request broad permissions. Vet publishers, and prefer reputable vendors.<\/li>\n<li><strong>Org\/project sprawl:<\/strong> Too many projects without governance creates duplicated pipelines, inconsistent practices, and access sprawl.<\/li>\n<li><strong>Migration challenges (TFS\/TFVC):<\/strong> Moving to Git and modern CI\/CD requires process changes, not just tooling.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">14. Comparison with Alternatives<\/h2>\n\n\n\n<p>Azure DevOps sits in a competitive ecosystem of DevOps and Developer Tools. The \u201cbest\u201d option depends on governance needs, ecosystem alignment, and team 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 DevOps (Services)<\/strong><\/td>\n<td>End-to-end planning + repos + CI\/CD in one suite<\/td>\n<td>Strong enterprise controls, Boards integration, mature pipelines, Azure-friendly<\/td>\n<td>SaaS networking constraints; some orgs prefer GitHub-centric workflows<\/td>\n<td>You want integrated suite and enterprise governance, especially in Azure environments<\/td>\n<\/tr>\n<tr>\n<td><strong>GitHub (Issues\/Actions)<\/strong><\/td>\n<td>Repo-centric workflows, open-source, broad ecosystem<\/td>\n<td>Huge ecosystem, strong developer experience, strong security offerings (by plan)<\/td>\n<td>Work planning depth differs from Boards; enterprise release controls vary by workflow<\/td>\n<td>You want GitHub as the primary developer platform and Actions for CI\/CD<\/td>\n<\/tr>\n<tr>\n<td><strong>GitLab (SaaS\/self-managed)<\/strong><\/td>\n<td>Integrated DevSecOps + CI runners<\/td>\n<td>Single platform with CI runners, strong DevSecOps story<\/td>\n<td>Migration complexity; governance model differs<\/td>\n<td>You want GitLab\u2019s integrated model and runner ecosystem<\/td>\n<\/tr>\n<tr>\n<td><strong>Jenkins (self-managed)<\/strong><\/td>\n<td>Highly customizable CI<\/td>\n<td>Massive plugin ecosystem, full control<\/td>\n<td>High ops burden, plugin supply chain risk, governance needs custom work<\/td>\n<td>You need deep customization and accept operational overhead<\/td>\n<\/tr>\n<tr>\n<td><strong>Atlassian Jira + Bitbucket + Bamboo<\/strong><\/td>\n<td>Jira-centric orgs<\/td>\n<td>Strong planning in Jira, integrated ecosystem<\/td>\n<td>CI\/CD tooling can be fragmented; Bamboo less common now<\/td>\n<td>You are standardized on Atlassian and need close integration<\/td>\n<\/tr>\n<tr>\n<td><strong>AWS Code* (CodeCommit\/CodeBuild\/CodePipeline)<\/strong><\/td>\n<td>AWS-centric delivery<\/td>\n<td>Native AWS integration<\/td>\n<td>Different planning model; tooling varies and changes over time<\/td>\n<td>Your workloads are primarily on AWS and you want native CI\/CD there<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure DevOps Server (self-hosted)<\/strong><\/td>\n<td>Restricted networks, on-prem requirements<\/td>\n<td>Full control, can run in isolated environments<\/td>\n<td>Requires patching\/backup\/HA, licensing complexity<\/td>\n<td>You need self-hosting for compliance, connectivity, or residency<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\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<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> A financial institution must deliver microservices to Azure with strict approvals, traceability, and separation of duties. Production deployments must be gated and auditable.<\/li>\n<li><strong>Proposed architecture:<\/strong><\/li>\n<li>Azure DevOps Boards for requirements and change tracking<\/li>\n<li>Azure Repos with strict branch policies (2 reviewers, build validation)<\/li>\n<li>Multi-stage YAML pipelines:<ul>\n<li>CI: build\/test, container build, publish signed artifacts<\/li>\n<li>CD: deploy to dev \u2192 stage \u2192 prod using Environments<\/li>\n<\/ul>\n<\/li>\n<li>Self-hosted agents in a secured VNet to access private endpoints (Key Vault, ACR, AKS API)<\/li>\n<li>Azure Key Vault for secrets; service connections with least privilege<\/li>\n<li>Monitoring via Azure Monitor and Application Insights after deployment<\/li>\n<li><strong>Why Azure DevOps was chosen:<\/strong> Integrated traceability (Boards \u2194 code \u2194 pipelines), mature approvals\/environments, and strong Entra ID integration.<\/li>\n<li><strong>Expected outcomes:<\/strong><\/li>\n<li>Auditable delivery with consistent approvals<\/li>\n<li>Reduced production risk via gated releases<\/li>\n<li>Faster incident resolution through deployment history and traceability<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Startup\/small-team example<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> A startup needs consistent CI for a small API and wants a lightweight workflow that still supports PR checks and artifact publishing.<\/li>\n<li><strong>Proposed architecture:<\/strong><\/li>\n<li>Azure Repos for code<\/li>\n<li>One YAML pipeline for CI (tests + lint + artifact)<\/li>\n<li>Optional second stage for deployment later when needed<\/li>\n<li><strong>Why Azure DevOps was chosen:<\/strong> Quick setup, integrated repos + pipelines, and a path to add environments\/approvals as the team grows.<\/li>\n<li><strong>Expected outcomes:<\/strong><\/li>\n<li>Automated quality checks for every PR<\/li>\n<li>Repeatable builds and versioned artifacts<\/li>\n<li>Minimal operational overhead initially<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">16. FAQ<\/h2>\n\n\n\n<p>1) <strong>Is Azure DevOps the same as Azure DevOps Server?<\/strong><br\/>\nNo. <strong>Azure DevOps Services<\/strong> is Microsoft-hosted SaaS. <strong>Azure DevOps Server<\/strong> is self-hosted software you run and maintain.<\/p>\n\n\n\n<p>2) <strong>Do I need an Azure subscription to use Azure DevOps?<\/strong><br\/>\nNot always. Azure DevOps is organized around an Azure DevOps <strong>organization<\/strong>, not an Azure subscription. You only need an Azure subscription if you deploy to Azure resources or use Azure services that require billing.<\/p>\n\n\n\n<p>3) <strong>Can Azure DevOps host Git repositories?<\/strong><br\/>\nYes, via <strong>Azure Repos<\/strong> (Git). It also supports pull requests, branch policies, and integrations.<\/p>\n\n\n\n<p>4) <strong>Can I use GitHub repos with Azure Pipelines?<\/strong><br\/>\nYes. Azure Pipelines can run builds from GitHub repositories using supported integration options (verify current integration steps in docs).<\/p>\n\n\n\n<p>5) <strong>Should I use YAML pipelines or classic pipelines?<\/strong><br\/>\nFor most teams, <strong>YAML pipelines<\/strong> are recommended because they are versioned, reviewable, and template-friendly. Classic pipelines may still be used for legacy setups or certain UI-driven scenarios.<\/p>\n\n\n\n<p>6) <strong>What are Microsoft-hosted vs self-hosted agents?<\/strong><br\/>\n&#8211; <strong>Microsoft-hosted agents<\/strong>: provided by Microsoft, ephemeral, quick to start, but limited by hosted minutes\/parallelism and network constraints.<br\/>\n&#8211; <strong>Self-hosted agents<\/strong>: you run them; more control and network access, but you manage patching, scaling, and security.<\/p>\n\n\n\n<p>7) <strong>How do I securely deploy to Azure without storing secrets?<\/strong><br\/>\nUse <strong>service connections<\/strong> configured with least privilege and prefer <strong>workload identity federation<\/strong> when supported. Use <strong>Azure Key Vault<\/strong> for runtime secret retrieval. Verify current recommended patterns in Azure DevOps docs.<\/p>\n\n\n\n<p>8) <strong>Can Azure DevOps manage approvals for production deployments?<\/strong><br\/>\nYes, using <strong>Environments<\/strong> plus <strong>approvals and checks<\/strong>, and by locking down environment permissions.<\/p>\n\n\n\n<p>9) <strong>Does Azure DevOps provide audit logs?<\/strong><br\/>\nAzure DevOps has auditing features for many org activities. Availability and depth can vary\u2014verify in official docs for your plan and configuration.<\/p>\n\n\n\n<p>10) <strong>How do I link work items to commits and PRs?<\/strong><br\/>\nYou can link from the PR\/work item UI, and you can also reference work items in commit messages (for example <code>AB#&lt;id&gt;<\/code>). Exact behavior can vary by configuration.<\/p>\n\n\n\n<p>11) <strong>Can I use Azure Artifacts for npm\/NuGet\/Python packages?<\/strong><br\/>\nYes. Azure Artifacts supports multiple package types and can be used as a private feed with upstream sources.<\/p>\n\n\n\n<p>12) <strong>What\u2019s the easiest way to start with Azure DevOps?<\/strong><br\/>\nCreate an organization \u2192 project \u2192 repo \u2192 add an <code>azure-pipelines.yml<\/code> file \u2192 run a basic CI pipeline, like the lab in this tutorial.<\/p>\n\n\n\n<p>13) <strong>How do I prevent developers from pushing directly to main?<\/strong><br\/>\nUse <strong>branch policies<\/strong> that require PRs, require a successful build, and limit who can bypass policies.<\/p>\n\n\n\n<p>14) <strong>Is Azure DevOps suitable for Kubernetes deployments?<\/strong><br\/>\nYes. Azure Pipelines supports Kubernetes deployments using tasks or scripts (kubectl\/Helm). For private clusters, self-hosted agents inside the network are often used.<\/p>\n\n\n\n<p>15) <strong>How do I control costs for Azure DevOps?<\/strong><br\/>\nWatch:\n&#8211; user licensing (Basic\/Test Plans)\n&#8211; pipeline parallel jobs\/hosted minutes\n&#8211; artifacts storage and retention<br\/>\nUse self-hosted agents and retention policies where appropriate, and estimate using official pricing pages and the pricing calculator.<\/p>\n\n\n\n<p>16) <strong>Can Azure DevOps replace Jira?<\/strong><br\/>\nSometimes. Azure Boards can cover Agile planning needs for many teams. If you rely on specific Jira workflows\/apps, evaluate carefully.<\/p>\n\n\n\n<p>17) <strong>What\u2019s the best way to manage multiple teams?<\/strong><br\/>\nUse projects and teams intentionally:\n&#8211; one project per product or platform area (common)\n&#8211; teams for sprint\/board configuration per squad\nStandardize pipelines with templates.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">17. Top Online Resources to Learn Azure DevOps<\/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 DevOps documentation (Learn) \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/?view=azure-devops<\/td>\n<td>Canonical reference for all Azure DevOps features and how-to guides<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure DevOps pricing \u2014 https:\/\/azure.microsoft.com\/pricing\/details\/devops\/<\/td>\n<td>Current licensing model and cost dimensions<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Pipelines pricing \u2014 https:\/\/azure.microsoft.com\/pricing\/details\/devops\/azure-pipelines\/<\/td>\n<td>Details on hosted pipelines, parallel jobs, and CI\/CD compute model<\/td>\n<\/tr>\n<tr>\n<td>Official getting started<\/td>\n<td>Create an organization \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/organizations\/accounts\/create-organization<\/td>\n<td>Step-by-step org creation and baseline setup<\/td>\n<\/tr>\n<tr>\n<td>Official CI\/CD docs<\/td>\n<td>Azure Pipelines documentation \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/?view=azure-devops<\/td>\n<td>YAML pipelines, tasks, variables, environments, deployments<\/td>\n<\/tr>\n<tr>\n<td>Official repos docs<\/td>\n<td>Azure Repos documentation \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/repos\/?view=azure-devops<\/td>\n<td>Git repos, PRs, branch policies, repo permissions<\/td>\n<\/tr>\n<tr>\n<td>Official Boards docs<\/td>\n<td>Azure Boards documentation \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/boards\/?view=azure-devops<\/td>\n<td>Work items, boards, sprints, queries, dashboards<\/td>\n<\/tr>\n<tr>\n<td>Architecture guidance<\/td>\n<td>Azure Architecture Center (DevOps) \u2014 https:\/\/learn.microsoft.com\/azure\/architecture\/devops\/<\/td>\n<td>Practical architecture patterns for CI\/CD and DevOps on Azure<\/td>\n<\/tr>\n<tr>\n<td>CLI tooling<\/td>\n<td>Azure DevOps CLI \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/cli\/?view=azure-devops<\/td>\n<td>Automate project\/repo\/pipeline tasks with <code>az devops<\/code><\/td>\n<\/tr>\n<tr>\n<td>Video learning<\/td>\n<td>Microsoft DevOps YouTube channel \u2014 https:\/\/www.youtube.com\/@MicrosoftDevOps<\/td>\n<td>Practical demos, feature overviews, and real workflows (verify most recent playlists)<\/td>\n<\/tr>\n<tr>\n<td>Community learning<\/td>\n<td>Microsoft Q&amp;A (Azure DevOps) \u2014 https:\/\/learn.microsoft.com\/answers\/tags\/248\/azure-devops<\/td>\n<td>Troubleshooting and community Q&amp;A with Microsoft presence<\/td>\n<\/tr>\n<tr>\n<td>Samples<\/td>\n<td>Azure Pipelines YAML examples (Microsoft Learn) \u2014 https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/ecosystems\/?view=azure-devops<\/td>\n<td>Language\/framework-specific pipeline examples<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\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 teams<\/td>\n<td>DevOps fundamentals, CI\/CD with Azure DevOps, pipelines, automation<\/td>\n<td>check website<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>ScmGalaxy.com<\/td>\n<td>Developers, build\/release engineers<\/td>\n<td>Source control, build\/release management, DevOps tooling<\/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, ops teams<\/td>\n<td>Cloud operations and DevOps practices (Azure-oriented topics may be included)<\/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, platform teams<\/td>\n<td>Reliability engineering, CI\/CD operationalization, incident\/automation practices<\/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 automation<\/td>\n<td>AIOps concepts, automation, monitoring-to-remediation workflows<\/td>\n<td>check website<\/td>\n<td>https:\/\/www.aiopsschool.com\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\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 training and guidance (verify offerings)<\/td>\n<td>Individuals and teams seeking DevOps coaching<\/td>\n<td>https:\/\/rajeshkumar.xyz\/<\/td>\n<\/tr>\n<tr>\n<td>devopstrainer.in<\/td>\n<td>DevOps tools training (verify specific Azure DevOps coverage)<\/td>\n<td>Beginners to intermediate learners<\/td>\n<td>https:\/\/www.devopstrainer.in\/<\/td>\n<\/tr>\n<tr>\n<td>devopsfreelancer.com<\/td>\n<td>Freelance DevOps help\/training (verify services)<\/td>\n<td>Teams needing flexible assistance<\/td>\n<td>https:\/\/www.devopsfreelancer.com\/<\/td>\n<\/tr>\n<tr>\n<td>devopssupport.in<\/td>\n<td>DevOps support and enablement (verify scope)<\/td>\n<td>Teams needing troubleshooting and guidance<\/td>\n<td>https:\/\/www.devopssupport.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\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 and cloud consulting (verify service catalog)<\/td>\n<td>CI\/CD design, cloud migration enablement, automation<\/td>\n<td>Standardizing Azure DevOps pipelines; setting up agent pools; implementing branch policies<\/td>\n<td>https:\/\/cotocus.com\/<\/td>\n<\/tr>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps consulting and training (verify offerings)<\/td>\n<td>Platform enablement, pipeline modernization, coaching<\/td>\n<td>Azure DevOps adoption roadmap; template-based pipelines; governance model setup<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>DEVOPSCONSULTING.IN<\/td>\n<td>DevOps consulting (verify service catalog)<\/td>\n<td>CI\/CD implementation, process improvement<\/td>\n<td>Moving from manual deployments to Azure Pipelines; setting up artifacts feeds; release approval workflows<\/td>\n<td>https:\/\/devopsconsulting.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\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 DevOps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Git fundamentals: branches, merges, PRs<\/li>\n<li>Basic CI\/CD concepts: build, test, artifact, deploy<\/li>\n<li>Basics of Azure identity (Entra ID) and RBAC concepts<\/li>\n<li>Scripting basics: Bash\/PowerShell<\/li>\n<li>A language ecosystem (one is enough to start): .NET, Node.js, Python, Java<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn after Azure DevOps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Multi-stage deployments and environment strategies<\/li>\n<li>Infrastructure-as-Code:<\/li>\n<li>Bicep\/ARM or Terraform<\/li>\n<li>Containerization and orchestration:<\/li>\n<li>Docker, Kubernetes (AKS)<\/li>\n<li>Secret management patterns:<\/li>\n<li>Azure Key Vault, managed identities\/workload identity<\/li>\n<li>DevSecOps:<\/li>\n<li>SAST\/DAST concepts, SBOM, artifact signing (tool choice varies)<\/li>\n<li>Observability:<\/li>\n<li>Azure Monitor, Application Insights, dashboards and alerting<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Job roles that use Azure DevOps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DevOps Engineer<\/li>\n<li>Build\/Release Engineer<\/li>\n<li>Platform Engineer<\/li>\n<li>SRE (Site Reliability Engineer)<\/li>\n<li>Cloud Engineer \/ Cloud Architect<\/li>\n<li>Software Engineer (CI\/CD ownership in modern teams)<\/li>\n<li>QA Automation Engineer \/ Test Manager (with Test Plans)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Certification path (Azure-related)<\/h3>\n\n\n\n<p>Azure DevOps is commonly associated with Microsoft\u2019s DevOps certification track. Certification offerings can change, so <strong>verify current certifications<\/strong> on Microsoft Learn:\nhttps:\/\/learn.microsoft.com\/credentials\/<\/p>\n\n\n\n<p>A common path many candidates follow:\n&#8211; Azure Fundamentals (AZ-900)\n&#8211; Azure Administrator (AZ-104) or Azure Developer (AZ-204)\n&#8211; DevOps Engineer Expert (verify current exam code and prerequisites)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Project ideas for practice<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Build a multi-stage pipeline: CI \u2192 deploy to dev \u2192 manual approval \u2192 deploy to prod (using a free\/low-cost target if available)<\/li>\n<li>Create a reusable YAML template repo (\u201cgolden pipeline\u201d)<\/li>\n<li>Implement branch policies + PR validation build<\/li>\n<li>Set up Azure Artifacts feed and publish an internal library<\/li>\n<li>Run IaC validation on PRs (Terraform plan or Bicep what-if)<\/li>\n<li>Implement a self-hosted agent in a private VNet and deploy to a private resource<\/li>\n<\/ul>\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 machine\/runtime that executes Azure Pipelines jobs (Microsoft-hosted or self-hosted).<\/li>\n<li><strong>Agent pool<\/strong>: A logical group of agents used by pipelines.<\/li>\n<li><strong>Artifact<\/strong>: A build output stored and versioned (pipeline artifact, package artifact, container image).<\/li>\n<li><strong>Azure Artifacts<\/strong>: Azure DevOps component for hosting package feeds.<\/li>\n<li><strong>Azure Boards<\/strong>: Work tracking system (backlogs, boards, sprints).<\/li>\n<li><strong>Azure Pipelines<\/strong>: CI\/CD automation engine in Azure DevOps.<\/li>\n<li><strong>Azure Repos<\/strong>: Git repository hosting in Azure DevOps.<\/li>\n<li><strong>Branch policy<\/strong>: Rules enforcing PR reviews, build validation, and merge requirements.<\/li>\n<li><strong>Environments<\/strong>: Azure DevOps feature modeling deployment targets and enabling approvals\/checks.<\/li>\n<li><strong>Hosted agent<\/strong>: Microsoft-provided ephemeral build agent.<\/li>\n<li><strong>Self-hosted agent<\/strong>: Agent you run on your own infrastructure for control\/network access.<\/li>\n<li><strong>PAT (Personal Access Token)<\/strong>: Token used for API and Git authentication; should be scoped and time-limited.<\/li>\n<li><strong>PR (Pull Request)<\/strong>: Workflow for reviewing and merging changes into a target branch.<\/li>\n<li><strong>Service connection<\/strong>: Secure configuration that allows pipelines to authenticate to external services (Azure, Kubernetes, etc.).<\/li>\n<li><strong>YAML pipeline<\/strong>: Pipeline defined as code in a <code>.yml<\/code> file in the repository.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">23. Summary<\/h2>\n\n\n\n<p>Azure DevOps is Azure\u2019s flagship Developer Tools suite for planning work, hosting code, running CI\/CD, managing testing, and publishing internal packages. It matters because it brings <strong>traceability, governance, and automation<\/strong> together\u2014critical for teams shipping reliably at scale.<\/p>\n\n\n\n<p>Architecturally, Azure DevOps Services acts as the orchestration control plane, while build\/deploy execution happens on agents (Microsoft-hosted or self-hosted). Cost is primarily driven by <strong>user licensing<\/strong>, <strong>pipeline parallelism\/hosted compute<\/strong>, and <strong>artifact storage<\/strong>\u2014so retention policies and agent strategy are key. Security hinges on Entra ID integration, least-privilege service connections, protected branches, protected environments, and careful handling of secrets (prefer Key Vault).<\/p>\n\n\n\n<p>Use Azure DevOps when you need an integrated, enterprise-ready toolchain\u2014especially in Azure-centric environments. As a next step, extend the lab by adding multi-stage deployments with environments and approvals, and adopt a secure service connection pattern for deploying to Azure.<\/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-420","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\/420","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=420"}],"version-history":[{"count":0,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/420\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}