Skip to main content
Back to blog

Environment Management for QA in Azure DevOps

How to manage test environments in Azure DevOps using Environments, deployment gates, and approval workflows. Covers staging, UAT, and production environment configuration for QA teams with YAML examples.

InnovateBits4 min read
Share

Azure DevOps Environments are named deployment targets with history, approval gates, and policies. They give QA teams visibility and control over what's deployed where — and the ability to block deployments that don't meet quality criteria.


Creating environments

Go to Pipelines → Environments → + New environment.

Development  → Auto-deploy (developers, no approval)
Staging      → Auto-deploy after CI passes (QA tests here)
UAT          → Requires QA Lead approval
Production   → Requires QA + Product Owner approval

Configuring approval gates

Staging: automatic deployment

- stage: DeployStaging
  jobs:
    - deployment: Staging
      environment: staging          # No approvals — auto-deploys
      strategy:
        runOnce:
          deploy:
            steps:
              - script: ./deploy.sh staging

UAT: QA lead approval required

  1. Go to Environments → UAT → Approvals and checks
  2. Click + → Approvals
  3. Add: QA Lead user
  4. Instructions: "Verify staging test results before approving UAT deployment"
  5. Timeout: 48 hours
- stage: DeployUAT
  jobs:
    - deployment: UAT
      environment: uat              # Pauses for approval before running
      strategy:
        runOnce:
          deploy:
            steps:
              - script: ./deploy.sh uat

Production: dual approval

  1. Go to Environments → Production → Approvals and checks
  2. Add approver: QA Lead
  3. Add approver: Product Owner
  4. Approval order: Both must approve (not either/or)
  5. Timeout: 72 hours

Branch control check

Prevent production deployments from non-release branches:

  1. Go to Environments → Production → Approvals and checks
  2. Click + → Branch control
  3. Allowed branches: refs/heads/release/*, refs/heads/main

Now only pipelines triggered from main or release branches can deploy to production.


Environment-specific variable groups

Library
├── vars-development    (non-secret config for dev)
├── vars-staging        (non-secret config for staging)
├── vars-uat            (non-secret config for UAT)
├── vars-production     (non-secret config for prod)
├── secrets-staging     (credentials for staging)
└── secrets-production  (credentials for prod)
variables:
  ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
    - group: vars-production
    - group: secrets-production
  ${{ else }}:
    - group: vars-staging
    - group: secrets-staging

Environment deployment history

Azure DevOps tracks every deployment to each environment:

Go to Pipelines → Environments → [staging]:

Staging environment deployment history:

Build #1052  2025-10-12 14:23  ✓ Succeeded  main@a3f2b1c
Build #1048  2025-10-11 09:15  ✓ Succeeded  main@7d8e9f0
Build #1044  2025-10-10 16:45  ✗ Failed     feature/wishlist@b2c3d4
Build #1041  2025-10-09 11:20  ✓ Succeeded  main@5e6f7a8

When investigating "when did this bug appear on staging?", check the deployment history and compare against when the bug was first reported.


QA sign-off workflow using approval gates

Integrating QA sign-off into the pipeline:

- stage: QAValidation
  jobs:
    - job: RunRegression
      steps:
        - script: npx playwright test
        - task: PublishTestResults@2
          condition: always()
 
    - job: QASignOff
      dependsOn: RunRegression
      pool: server
      steps:
        - task: ManualValidation@0
          timeoutInMinutes: 1440   # 24 hours
          inputs:
            notifyUsers: 'qa-lead@company.com'
            instructions: |
              Regression results: see pipeline test tab.
              Approve only if:
              - Pass rate >= 95%
              - No open P1/P2 bugs
              - Staging has been stable for 24+ hours

When this runs, QA Lead receives an email and can approve or reject from the Azure DevOps UI.


Common errors and fixes

Error: Approval notification emails not being received Fix: Check that notification subscriptions are configured in User Settings → Notifications. Also check that the approver's email matches their Azure DevOps account email.

Error: Pipeline deploys to production without waiting for approval Fix: The approval check must be on the environment, not the pipeline YAML. Approval gates in environments apply to any pipeline that deploys to that environment.

Error: Branch control check blocks hotfix deployments from hotfix branches Fix: Add refs/heads/hotfix/* to the allowed branches list in the Production environment's branch control check.

Error: Manual validation task times out during holidays Fix: Increase timeout to 72–96 hours for environments that aren't staffed continuously. Also add multiple approvers so one person's absence doesn't block releases.

Free newsletter

Stay ahead in AI-driven QA

Get practical tutorials on test automation, AI testing, and quality engineering — straight to your inbox. No spam, unsubscribe any time.

Discussion

Sign in with GitHub to comment · powered by Giscus