Azure DevOps is a cloud-based platform from Microsoft that provides a complete set of tools to practice DevOps. It covers every stage of the software delivery lifecycle — planning, coding, building, testing, releasing, and monitoring — all in one place. Think of it as a single platform that replaces the need to stitch together separate tools. Instead of Jira for planning + GitHub for code + Jenkins for CI/CD + Nexus for packages — Azure DevOps gives you all of that under one roof, all connected. > 💡 **Tip:** Azure DevOps was previously called **Visual Studio Team Services (VSTS)** before being rebranded in 2018. If you see VSTS mentioned anywhere, it is the same platform. ### Azure DevOps vs Other DevOps Tools | Feature | Azure DevOps | GitHub Actions | Jenkins | |---|---|---|---| | Project management | Azure Boards (built-in) | GitHub Projects | External (Jira etc.) | | Version control | Azure Repos | GitHub | External (GitHub etc.) | | CI/CD | Azure Pipelines | GitHub Actions | Jenkins itself | | Package management | Azure Artifacts | GitHub Packages | External (Nexus etc.) | | Best for | Enterprise, Microsoft ecosystem | Open source, GitHub-first teams | Custom, self-hosted setups | | Setup effort | Low (all-in-one) | Low | High (configure everything) | ### Who Uses Azure DevOps Azure DevOps is used by developers, DevOps engineers, QA engineers, and project managers. It works for a team of 2 and for enterprise teams of thousands. It is platform-agnostic — your code can be in any language, deployed to any cloud (Azure, AWS, GCP), and running on any OS. ---
Azure DevOps is made up of five services. You can use all of them together or pick only what you need — they work independently but are more powerful when connected.  Real flow — how they connect: Plan work in Boards → Write code in Repos → Build and test in Pipelines → Store packages in Artifacts → Track test results in Test Plans ### Azure Boards Azure Boards is the project management layer. Before any code is written, work is planned, sized, and assigned here. It supports Scrum, Kanban, and CMMI agile methodologies. Key features: * **Work items** — track tasks, bugs, user stories, and epics * **Kanban boards** — visualize work flowing through stages * **Sprint planning** — time-box your work into iterations (usually 2 weeks) * **Backlogs** — maintain and prioritize everything your team needs to do * **Dashboards** — see project health at a glance with charts and metrics ### Azure Repos Azure Repos provides cloud-hosted version control using Git. It stores your source code, tracks every change ever made, and enables team collaboration through branching and pull requests. Key features: * Unlimited private and public Git repositories * Pull requests with inline code review and comments * Branch policies to protect your main branch from bad merges * Full Git history — see who changed what and when ### Azure Pipelines Azure Pipelines is the CI/CD engine — the most important service for a DevOps engineer. It automatically builds your code, runs tests, and deploys your application whenever changes are pushed. Key features: * Works with any language — Python, Node.js, Java, .NET, Go, Ruby, and more * Works with any cloud — Azure, AWS, GCP, or on-premises * Supports containers, Kubernetes, and serverless * YAML-based pipeline definition — your pipeline is code, version-controlled like your app * Free tier includes 1,800 minutes per month (public projects get unlimited free minutes) ### Azure Test Plans Azure Test Plans provides tools for managing and running tests — both automated and manual. QA engineers define test cases, execute them, and track results all in one place. Key features: * **Manual test cases** — define step-by-step test scripts for QA engineers to follow * **Exploratory testing** — unscripted, session-based testing with a browser extension * **Test execution tracking** — record pass/fail for every test run * **Pipeline integration** — automated test results from pipelines appear alongside manual results * **Defect tracking** — failed tests automatically link to Azure Boards bugs This is where the whole team gets a single view of quality — not split across spreadsheets, emails, and separate dashboards. ### Azure Artifacts Azure Artifacts is a private package registry. Teams use it to host and share internal packages — npm libraries, NuGet packages, Python packages, and Maven artifacts. Key features: * Supports npm, NuGet, PyPI, Maven, and Cargo package formats * Private and public package feeds (you control who can install what) * Integrated with Azure Pipelines — publish packages automatically after a build * **Upstream sources** — proxy and cache public registries (npm, PyPI) so builds never depend on the internet being up ---
### Creating Your Account Go to [dev.azure.com](https://dev.azure.com) and sign in with a Microsoft account. The free tier includes: * 5 users with full access at no cost * Unlimited private Git repositories * 1,800 pipeline minutes per month for private projects * Public projects get unlimited pipeline minutes free ### Creating an Organization An **organization** is the top-level container. Everything — your projects, teams, billing, and settings — lives inside it. * Choose a unique name — this becomes your URL: `dev.azure.com/your-org-name` * Select the region closest to your team for lowest latency * One organization can hold up to 1,000 projects ### Creating Your First Project Inside your organization, click **New Project** and fill in: | Field | What to Choose | |---|---| | Project name | Short, descriptive name (e.g., `my-web-app`) | | Visibility | Private for most teams; Public for open source | | Version control | **Git** — always choose this unless told otherwise | | Work item process | **Agile** or **Scrum** for most teams; Basic if just starting out | > 💡 **Tip:** TFVC (Team Foundation Version Control) is the legacy Microsoft option — almost nobody uses it today. Always pick Git. ---
### Setting Up Your Repository After creating a project, go to **Repos** in the left sidebar. A Git repository is already created for you. **Clone to your local machine:** ```bash git clone https://dev.azure.com/your-org/your-project/_git/your-repo cd your-repo ``` **Push existing local code:** ```bash git init git add . git commit -m "Initial commit" git remote add origin https://dev.azure.com/your-org/your-project/_git/your-repo git push -u origin main ``` ### Branching Strategy A good branching strategy keeps `main` always stable and deployable while the team works on features in parallel. main ──────────────────────────────────────────► (always deployable) | | | feature/login-page | hotfix/fix-payment-bug |──────────────────► |─────────► | (develop here) | (emergency fix — goes straight to main) **Branch naming conventions:** | Branch Type | Purpose | Naming Pattern | |---|---|---| | `main` | Production-ready code, always stable | `main` | | Feature | New feature development | `feature/user-authentication` | | Bugfix | Fix a non-critical bug | `bugfix/login-error` | | Hotfix | Emergency production fix | `hotfix/payment-crash` | | Release | Prepare and stabilize a release | `release/v2.1.0` | > 🔴 **Common Mistake:** Committing directly to `main`. Always create a branch, do your work there, and merge through a pull request. Direct commits to `main` bypass all reviews and automated checks. **Working with branches:** ```bash ## Create and switch to a new feature branch git checkout -b feature/user-dashboard ## Work, then commit git add . git commit -m "Add user dashboard component" ## Push the branch to Azure Repos git push origin feature/user-dashboard ## After PR is merged, clean up locally git checkout main git branch -d feature/user-dashboard ``` ### Pull Requests A **pull request (PR)** is how code gets reviewed and merged into `main`. It is not just a merge button — it is the quality gate between your work and production. **Creating a pull request:** * Go to **Repos → Pull Requests → New Pull Request** * Select source branch (e.g., `feature/user-dashboard`) and target (`main`) * Add a clear title and description — explain what changed and why * Assign at least one reviewer from your team * Link the related work item (type `#42` to link work item 42) **Branch policies — protect your main branch:** Branch policies prevent anyone from pushing directly to `main`. Set them up under **Project Settings → Repos → Branches → Branch Policies on main**. | Policy | What It Enforces | |---|---| | Minimum reviewers | At least 1 (or 2) approvals required before merging | | Build validation | Pipeline must pass before merge is allowed | | Comment resolution | Every review comment must be resolved | | Work item linking | PR must be linked to a work item | > ⚠️ **Security:** Branch policies are one of the most important protections you can set up. Without them, anyone on the team can push broken code directly to main and break production. ### Commit Message Best Practice Clear commit messages let your team understand what changed and why — without reading the code. ```bash ## Format: type(scope): short description git commit -m "feat(auth): add JWT token validation" git commit -m "fix(dashboard): resolve chart rendering on mobile" git commit -m "docs(readme): update installation instructions" git commit -m "refactor(api): simplify error handling logic" git commit -m "test(auth): add unit tests for login flow" git commit -m "chore(deps): upgrade express to v4.18" ## Common types: ## feat — new feature ## fix — bug fix ## docs — documentation only ## refactor — code improvement without adding features ## test — adding or updating tests ## chore — tooling or build process changes ``` ---
### What is a Pipeline A pipeline is a sequence of automated steps that run automatically every time code changes. It catches problems early — before they reach users — and automates the work of shipping software. Code pushed to repo | v BUILD — install dependencies, compile | v TEST — run unit tests, integration tests, linting | v PACKAGE — create a deployable artifact | v DEPLOY — ship to Dev → Staging → Production Without a pipeline, every step above is done manually. With a pipeline, every step is automatic, consistent, and auditable. ### Pipeline Building Blocks Understanding the hierarchy is critical before writing any YAML: Pipeline (the whole workflow) | Stage (a phase — Build, Test, Deploy-Dev, Deploy-Prod) | Job (runs on one agent/machine) | Step (a single action — run a script, or run a task) | Concept | What It Is | Example | |---|---|---| | **Trigger** | What starts the pipeline | Push to `main` | | **Stage** | A major phase | Build, Deploy-Dev, Deploy-Prod | | **Job** | Work that runs on one machine | build-job, test-job | | **Step** | One action inside a job | `npm install`, `docker build` | | **Agent** | The machine running the job | `ubuntu-latest` | | **Artifact** | Output passed between stages | Compiled app, Docker image | | **Variable** | Reusable value | `$(Build.BuildId)` | | **Environment** | Named deployment target | Dev, Staging, Production | ### YAML Pipelines Pipelines in Azure DevOps are defined in a YAML file — typically `azure-pipelines.yml` at the root of your repository. This means your pipeline is code: version-controlled, reviewable, and auditable just like your application. **Basic pipeline anatomy:** ```yaml ## azure-pipelines.yml ## Trigger — what starts this pipeline trigger: branches: include: - main - develop ## Pool — what type of machine runs the jobs pool: vmImage: ubuntu-latest ## Variables — reusable values variables: appName: my-web-app nodeVersion: '20.x' ## Steps — the actual work steps: - task: NodeTool@0 inputs: versionSpec: $(nodeVersion) displayName: Install Node.js - script: | npm ci npm run build displayName: Install and build - script: npm test displayName: Run tests ``` ### Microsoft-Hosted vs Self-Hosted Agents An **agent** is the machine that runs your pipeline jobs. You have two options: | | Microsoft-Hosted | Self-Hosted | |---|---|---| | Setup | None — ready to use | You install and configure it | | Cost | Free tier + paid minutes | Free (you pay for the machine) | | Speed | Slower (fresh VM every run) | Faster (no cold start) | | Custom tools | Install each run | Pre-installed permanently | | Private network access | No | Yes | | Use when | Standard builds, most cases | Special software, private network, speed-critical | **Setting up a self-hosted agent on Linux:** ```bash ## Download the agent package mkdir myagent && cd myagent wget https://vstsagentpackage.azureedge.net/agent/latest/vsts-agent-linux-x64-latest.tar.gz tar zxvf vsts-agent-linux-x64-latest.tar.gz ## Configure — it will ask for your Azure DevOps URL and a PAT token ./config.sh ## Install and start as a background service sudo ./svc.sh install sudo ./svc.sh start ``` Reference it in your pipeline: ```yaml pool: name: 'MyAgentPool' ## the pool your self-hosted agent is registered in ``` > 💡 **Tip:** Use self-hosted agents when your pipeline needs to reach internal databases or services that are not on the public internet, or when you need specific build tools pre-installed to avoid slow install steps on every run. ### Pipeline for a Node.js App ```yaml trigger: - main pool: vmImage: ubuntu-latest variables: nodeVersion: '20.x' stages: - stage: Build displayName: Build and Test jobs: - job: BuildJob steps: - task: NodeTool@0 inputs: versionSpec: $(nodeVersion) displayName: Install Node.js - script: npm ci displayName: Install dependencies - script: npm run build displayName: Build application - script: npm test -- --coverage displayName: Run tests with coverage - task: PublishTestResults@2 inputs: testResultsFormat: JUnit testResultsFiles: '**/test-results.xml' condition: always() displayName: Publish test results - task: PublishBuildArtifacts@1 inputs: pathToPublish: dist artifactName: build-output displayName: Publish artifact - stage: Deploy displayName: Deploy to Staging dependsOn: Build condition: succeeded() jobs: - job: DeployJob steps: - task: DownloadBuildArtifacts@1 inputs: artifactName: build-output displayName: Download artifact - script: echo "Deploying to staging..." displayName: Deploy ``` ### Pipeline for a Python App ```yaml trigger: branches: include: - main pool: vmImage: ubuntu-latest steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.11' displayName: Set Python version - script: | python -m pip install --upgrade pip pip install -r requirements.txt displayName: Install dependencies - script: | pip install pytest pytest-cov pytest tests/ --cov=src --cov-report=xml displayName: Run tests - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: Cobertura summaryFileLocation: coverage.xml displayName: Publish coverage report ``` ### Pipeline for Building a Docker Image ```yaml trigger: - main pool: vmImage: ubuntu-latest variables: imageName: myapp imageTag: $(Build.BuildId) steps: - task: Docker@2 displayName: Build Docker image inputs: command: build repository: $(imageName) dockerfile: Dockerfile tags: | $(imageTag) latest - task: Docker@2 displayName: Push to container registry inputs: command: push repository: $(imageName) tags: | $(imageTag) latest ``` ### Pipeline Triggers ```yaml ## Run on push to specific branches trigger: branches: include: - main - release/* exclude: - feature/experimental-* paths: exclude: - README.md ## don't trigger if only docs changed ## Run on pull requests targeting main pr: branches: include: - main ## Scheduled — run every night at 2 AM UTC schedules: - cron: "0 2 * * *" displayName: Nightly build branches: include: - main always: true ## Manual only — no automatic triggers trigger: none ``` ### Pipeline Variables and Secrets ```yaml ## Variables inline in YAML variables: appName: my-web-app environment: staging ## Variables from a variable group (UI-defined or Key Vault-linked) variables: - group: my-app-secrets ## contains DB_PASSWORD, API_KEY, etc. - name: appName value: my-web-app steps: - script: | echo "Deploying $(appName) to $(environment)" env: DB_PASSWORD: $(DB_PASSWORD) ## inject secret as env variable — masked in logs ``` > ⚠️ **Security:** Never put passwords, API keys, or connection strings directly in your YAML file. Even in a private repo, it is a security risk. Use variable groups linked to Azure Key Vault, or define secret variables through the pipeline UI where they are encrypted at rest. ### Caching Dependencies Caching saves downloaded packages between pipeline runs — significantly speeds up builds: ```yaml steps: - task: Cache@2 displayName: Cache node modules inputs: key: 'npm | "$(Agent.OS)" | package-lock.json' restoreKeys: | npm | "$(Agent.OS)" path: node_modules - script: npm ci displayName: Install (uses cache if available) ``` ### Pipeline Templates — Reuse Across Pipelines Templates let you define common steps once and reuse them across multiple pipelines. This avoids copy-pasting the same YAML everywhere. **Create a shared template file** (`templates/node-setup.yml`): ```yaml ## templates/node-setup.yml parameters: - name: nodeVersion default: '20.x' steps: - task: NodeTool@0 inputs: versionSpec: ${{ parameters.nodeVersion }} displayName: Install Node.js - script: npm ci displayName: Install dependencies ``` **Use it in any pipeline:** ```yaml steps: - template: templates/node-setup.yml parameters: nodeVersion: '20.x' - script: npm run build displayName: Build ``` > 💡 **Tip:** Templates are one of the most powerful features for teams managing many pipelines. Define your build setup, test publishing, and deployment steps as templates — then update them in one place when something changes. ### Pipeline Environments and Approvals **Environments** are named deployment targets (Dev, Staging, Production). They let you add approval gates — a human must approve before the pipeline continues. **Setting up an environment:** * Go to **Pipelines → Environments → New Environment** * Name it `staging` or `production` * Click the three dots → **Approvals and Checks → Add Approval** * Select which team members must approve before deployment proceeds ```yaml stages: - stage: DeployStaging jobs: - deployment: DeployToStaging environment: staging ## references the named environment strategy: runOnce: deploy: steps: - script: echo "Deploying to staging" - stage: DeployProduction dependsOn: DeployStaging jobs: - deployment: DeployToProd environment: production ## approval gate configured on this environment strategy: runOnce: deploy: steps: - script: echo "Deploying to production" ``` ### Key Built-in Pipeline Variables Azure Pipelines gives you built-in variables you can use anywhere: | Variable | What It Contains | |---|---| | `$(Build.BuildId)` | Unique number for this pipeline run | | `$(Build.SourceBranch)` | Branch that triggered the pipeline | | `$(Build.Repository.Name)` | Name of the repository | | `$(Build.ArtifactStagingDirectory)` | Where to put files before publishing | | `$(System.ArtifactsDirectory)` | Where downloaded artifacts land | | `$(Agent.OS)` | Operating system of the agent | ---
### Work Item Hierarchy Azure Boards organizes work in a clear hierarchy from big strategic goals down to individual tasks: Epic (Large goal spanning weeks or months — e.g. "Launch user authentication") | Feature (Group of related work — e.g. "Login with Google") | User Story (One piece of user value — e.g. "As a user I can log in with Google") | Task / Bug (Concrete work item — e.g. "Implement OAuth callback endpoint") | Work Item | What It Represents | Who Creates It | |---|---|---| | Epic | Large body of work — multiple sprints | Product Manager | | Feature | A deliverable capability within an epic | PM / Tech Lead | | User Story | One requirement from a user's perspective | Developer, PM | | Task | Concrete unit of technical work | Developer | | Bug | A defect that needs fixing | QA, Developer | ### Writing Good Work Items A well-written user story follows the "As a... I want... So that..." format and always has acceptance criteria: ``` Title: User can reset their password via email Description: As a registered user, I want to receive a password reset email, So that I can regain access if I forget my password. Acceptance Criteria: * User enters email on the forgot password page * System sends a reset link within 2 minutes * Reset link expires after 24 hours * User can set a new password using the link * Old password no longer works after the reset Priority: 2 (High) Story Points: 5 ``` > 🔴 **Common Mistake:** Writing user stories without acceptance criteria. Without them, "done" means different things to different people — and features ship incomplete or incorrect. ### Kanban Board The Kanban board gives a visual overview of all work flowing through your process. Each column is a stage: To Do → Active → In Review → Testing → Done * Drag and drop work items between columns to update state * Set **Work In Progress (WIP) limits** — maximum items allowed per column — to prevent people from juggling too many things at once * Add **swimlanes** to visually separate different types of work (e.g., bugs vs features) * Customize column names to match your team's actual process ### Sprints and Backlogs Sprints are fixed time periods (typically 2 weeks) where your team commits to completing a defined set of work. **Sprint planning workflow:** Product Backlog (everything that needs doing — prioritized) | | Sprint planning meeting v Sprint Backlog (the subset committed for this 2-week sprint) | | During the sprint v Sprint Board (Kanban view of sprint work only) | | End of sprint v Sprint Review (demo what shipped) + Retrospective (improve the process) | v Next sprint planning **Managing the backlog:** * Go to **Boards → Backlogs** * Top of the list = highest priority — drag to reorder * During planning, drag items from the backlog into a sprint * Use story points or hours to estimate effort ### Linking Work Items to Code When you commit code related to a work item, include the work item ID in your commit message. Azure DevOps automatically creates a two-way link. ```bash ## Link a commit to work item #42 git commit -m "feat(auth): add password reset flow - fixes #42" ## Link to multiple work items git commit -m "fix(ui): resolve header overlap #78 #79" ``` This gives you full traceability: from a business requirement → code commit → pipeline run → deployment. You can always answer "what changed and why?" ### Dashboards Dashboards show project health at a glance. Add widgets for: * Pipeline pass rate and recent build results * Burndown chart for the current sprint * Cumulative flow diagram (find bottlenecks) * Active bug count * Velocity across past sprints To create: **Overview → Dashboards → New Dashboard** ---
Azure DevOps is a cloud-based platform from Microsoft that provides a complete set of tools to practice DevOps. It cover...
Azure DevOps is made up of five services. You can use all of them together or pick only what you need — they work indepe...
Creating Your Account Go to [dev.azure.com](https://dev.azure.com) and sign in with a Microsoft account. The free tier i...
Setting Up Your Repository After creating a project, go to Repos in the left sidebar. A Git repository is already create...
What is a Pipeline A pipeline is a sequence of automated steps that run automatically every time code changes. It catche...
Work Item Hierarchy Azure Boards organizes work in a clear hierarchy from big strategic goals down to individual tasks: ...
Connecting to GitHub If your code is on GitHub but you want Azure Pipelines for CI/CD: Go to Pipelines → New Pipeline → ...
Pipeline Analytics Go to Pipelines → Analytics to see metrics across all pipelines: Metric What It Tells You Pipeline pa...
Version Control Pipeline Best Practices Security Best Practices Never store secrets in YAML files or source code — use K...
The Full CI/CD Flow in Azure DevOps Developer picks up User Story from Azure Boards v Creates a feature branch in Azure ...
Build a real pipeline from scratch. No Helm, no Helmfile, no chart registries. Just Azure DevOps, Docker, and raw Kubern...
A practical, production-grade walkthrough for teams starting from zero — from blank org to automated deployments using H...
Aligns directly with DevOps, Site Reliability (SRE), and Platform Engineering job descriptions.