Hands-onLesson 15 of 16

Classic to YAML Migration

Migrate safely from Classic Build and Release definitions to YAML pipelines without losing approvals, traceability, or deployment confidence.

🧒 Simple Explanation (ELI5)

Migrating from Classic to YAML is like moving from a whiteboard process to a written playbook. You do not erase the whiteboard on day one. You first copy the process carefully, test the written version, and only switch when you know it behaves the same or better.

🔧 Technical Explanation

Migration Principle

Do not migrate by rewriting everything from memory. Migrate by inventorying the existing working behavior and reproducing it deliberately.

Classic ConceptYAML EquivalentNotes
Build tasksSteps / tasks in a jobOften map directly
Release environmentsStages and deployment jobsAdd Azure DevOps environments for approvals
Release variablesVariables / variable groups / templatesSeparate secret handling carefully
ApprovalsEnvironment approvals and checksKeep out of YAML where governance matters
Task groupsTemplatesBetter long-term reuse pattern

Recommended Migration Order

  1. Inventory all tasks, variables, artifacts, approvals, service connections, and environment-specific behaviors.
  2. Migrate the build portion first into YAML.
  3. Validate artifact parity with the Classic build.
  4. Migrate lower-environment deployment stages.
  5. Re-create production approvals and checks using environments.
  6. Run both paths in parallel for a short validation window if the workload is critical.
Migration Path
Inventory
YAML Build
YAML Deploy Non-Prod
YAML Prod

🛠️ Hands-on

Migration Checklist

text
[ ] List all Classic build tasks
[ ] List artifacts published and artifact names
[ ] Export variables and variable groups
[ ] Capture release approvals and gates
[ ] Identify service connections used
[ ] Document target environments and namespaces
[ ] Reproduce build in YAML
[ ] Reproduce deploy logic in YAML stages
[ ] Recreate approvals on environments
[ ] Run validation deployment

Example: Build Task Mapping

yaml
pool:
  vmImage: windows-latest

steps:
- task: NuGetCommand@2
  inputs:
    command: restore
- task: VSBuild@1
  inputs:
    solution: '**/*.sln'
- task: VSTest@2
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: 'drop'
    ArtifactName: 'drop'

Example: Release to Stage Mapping

yaml
stages:
- stage: Deploy_Prod
  jobs:
  - deployment: Prod
    environment: production
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: drop
          - script: echo "deploy package here"
💡
Migration Heuristic

If the build is stable, migrate it first. Build migration usually has fewer governance dependencies than production release migration and gives quick confidence with lower risk.

🐛 Debugging Scenarios

Scenario 1: YAML Build Output Does Not Match Classic Artifact

Scenario 2: Production Approval Behavior Changed After Migration

Scenario 3: Team Rejects YAML Because It Looks Harder

⚠️
Migration Anti-Pattern

Do not combine migration with a full platform redesign unless the business has accepted the extra risk. First get parity, then improve architecture deliberately.

📋 Interview Questions

Beginner

Why do teams migrate from Classic to YAML?

To version pipeline logic in Git, enable code review, improve reuse, and simplify long-term maintenance.

Should a team delete the Classic pipeline immediately after creating YAML?

Not for important workloads. Validate parity first and keep rollback options until confidence is established.

What usually migrates first: build or production release?

Usually the build, because it is easier to validate and often less governance-heavy.

What replaces Classic task groups in YAML?

Templates are the common YAML reuse mechanism.

Where should production approvals live after migration?

On Azure DevOps environments and checks, not only inside editable YAML logic.

Intermediate

What is the biggest migration risk from Classic to YAML?

Missing hidden behavior such as UI-configured variables, approvals, branch filters, artifact names, or service connection authorizations that are easy to overlook.

How do you prove migration parity?

By comparing outputs, variables, target behavior, approvals, and deployment results between the Classic and YAML paths in a controlled validation period.

Would you refactor heavily during migration?

Usually no. I first recreate the working behavior, then refactor once the team trusts the new path.

How do templates help migration after parity is reached?

They let you consolidate repeated build or deploy logic across migrated pipelines without reintroducing manual UI duplication.

How do you keep migration auditable?

Track the inventory, create reviewed pull requests, map old-to-new pipeline definitions, and document who approved the production cutover.

Scenario-Based

A YAML pipeline deploys successfully, but a Classic release used to run an extra hidden step. How do you find it?

I inspect the Classic definition thoroughly, including task groups, environment settings, variables, approvals, and release logs to identify any implicit behavior missing from the YAML version.

How would you migrate a mission-critical production release with low tolerance for failure?

I would inventory thoroughly, migrate in phases, run parallel validation, preserve rollback, and cut over only after lower environments and approval paths demonstrate parity.

The team says YAML is too hard to read. What would you change?

I would simplify the structure, remove premature abstraction, use clearer naming, and provide a short operational readme or walkthrough so the migration improves clarity instead of reducing it.

What is your argument against leaving everything in Classic forever?

Classic works, but it limits version control, reuse, peer review, and scalable standardization. Over time that hidden UI logic becomes an operational tax.

How do you explain a safe migration to leadership?

We are not changing the business outcome in one jump. We are converting the delivery logic into versioned code in phases, validating parity at each phase, and keeping rollback options until the new path is proven.

🌍 Real-World Usage

Most real Azure DevOps estates live in a hybrid state for a while. Successful migration programs do not treat that as failure. They use it as a controlled transition from UI-defined legacy flows to reviewable, reusable pipeline-as-code.

🧾 Summary

Classic-to-YAML migration is an engineering change-management problem, not just a syntax conversion. Inventory first, migrate in stages, preserve governance, prove parity, then improve.