0Pricing
Cloud & IT Cert Prep · Lesson

Continuous Deployment to Azure

Extend the pipeline with a deployment stage that pushes the build artifact to an App Service slot, runs smoke tests, and swaps to production on approval.

Continuous Deployment to Azure is a free Cloud & IT Cert Prep lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Cloud & IT Cert Prep learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is Continuous Deployment?

Continuous Deployment (CD) automatically releases every change that passes CI tests to production without manual intervention. Continuous Delivery is the softer version — it automates deployment up to a staging environment and requires a human approval gate before production. Both practices are built on the same pipeline infrastructure. In Azure Pipelines, CD is implemented by adding deployment stages after the CI stage, targeting Azure environments with approval gates as needed.

Multi-Stage Pipeline: CI + CD

A complete CI/CD pipeline has at least three stages: Build (compile, test, publish artifact), Deploy to Staging (deploy artifact to a non-production slot), and Deploy to Production (swap slot or deploy after approval). Stages pass the artifact forward via pipeline artifact storage. The staging stage runs integration or smoke tests automatically; the production stage waits for manual approval before proceeding.

# azure-pipelines.yml: multi-stage CI/CD
trigger:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

stages:
- stage: Build
  jobs:
  - job: BuildApp
    steps:
    - script: npm ci && npm run build
    - task: PublishPipelineArtifact@1
      inputs: {targetPath: dist, artifactName: webapp}

- stage: DeployStaging
  dependsOn: Build
  jobs:
  - deployment: StagingDeploy
    environment: Staging
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureWebApp@1
            inputs: {appName: myapp-staging, package: '$(Pipeline.Workspace)/webapp'}

- stage: DeployProduction
  dependsOn: DeployStaging
  jobs:
  - deployment: ProductionDeploy
    environment: Production   # Has manual approval gate
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureWebApp@1
            inputs: {appName: myapp, package: '$(Pipeline.Workspace)/webapp'}

Deployment Jobs and Environments

Use deployment jobs (not regular job) for deployment stages. Deployment jobs support deployment strategies (runOnce, rolling, canary), track deployment history per environment, and are required to reference Azure DevOps Environments. An environment records which pipeline runs deployed to it, what version is currently live, and provides approval gates, checks, and resource health status in a single dashboard.

# Deployment job with rolling strategy
- job: RollingDeploy
  strategy:
    rolling:
      maxParallel: 2     # Deploy to 2 targets at a time
      preDeploy:
        steps:
        - script: echo 'Pre-deploy checks'
      deploy:
        steps:
        - task: AzureWebApp@1
          inputs:
            appName: myapp
            package: '$(Pipeline.Workspace)/webapp'
      postRouteDeploy:
        steps:
        - script: curl -f https://myapp.azurewebsites.net/health

Deploying to Azure App Service

The AzureWebApp@1 task deploys a web application to Azure App Service. It supports deploying to a specific slot (e.g., staging), deploying ZIP packages, Docker images, or JAR/WAR files. After deploying to a staging slot, use the AzureAppServiceManage@0 task to swap the staging slot into production — the preferred zero-downtime deployment pattern for App Service.

# Deploy to staging slot, then swap to production
steps:
- task: AzureWebApp@1
  displayName: 'Deploy to staging slot'
  inputs:
    azureSubscription: 'AzureProductionSC'
    appType: webAppLinux
    appName: myUniqueWebApp
    deployToSlotOrASE: true
    resourceGroupName: MyRG
    slotName: staging
    package: '$(Pipeline.Workspace)/webapp/app.zip'
    runtimeStack: 'NODE|18-lts'

- task: AzureAppServiceManage@0
  displayName: 'Swap staging into production'
  inputs:
    azureSubscription: 'AzureProductionSC'
    action: Swap Slots
    webAppName: myUniqueWebApp
    resourceGroupName: MyRG
    sourceSlot: staging

Smoke Tests in the CD Pipeline

After deploying to staging, run smoke tests — a minimal set of tests that verify the deployment succeeded and the application is responding correctly. Smoke tests typically call key API endpoints and verify expected status codes and response content. If smoke tests fail, the pipeline stops before swapping to production or requesting approval, preventing a broken release from reaching users.

# Smoke test step after staging deployment
- script: |
    MAX_RETRY=10
    COUNT=0
    until curl -sf https://myUniqueWebApp-staging.azurewebsites.net/health; do
      COUNT=$((COUNT+1))
      if [ $COUNT -ge $MAX_RETRY ]; then
        echo 'Health check failed after $MAX_RETRY attempts'
        exit 1
      fi
      echo 'Waiting for app to start... attempt '$COUNT
      sleep 10
    done
    echo 'App is healthy'
  displayName: 'Smoke test: health endpoint'

Environment Approval Gates

Add approval gates to Azure DevOps Environments to require manual sign-off before deployments proceed. Navigate to the environment settings and add Approvals — specify users or groups who must approve. When the pipeline reaches a deployment job targeting that environment, it pauses and sends an email notification. Approvers can view the deployment details and approve or reject in the Azure DevOps portal or the notification email link.

# Pipeline YAML: deployment to production environment
# (Approval configured in Azure DevOps portal on 'Production' environment)
- stage: DeployProduction
  displayName: 'Deploy to Production'
  dependsOn: DeployStaging
  condition: succeeded('DeployStaging')
  jobs:
  - deployment: ProdDeploy
    environment: Production   # <-- Triggers approval gate configured in portal
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureWebApp@1
            inputs:
              appName: myapp-prod
              package: '$(Pipeline.Workspace)/webapp/app.zip'

Deploying to Azure Kubernetes Service

Deploy containerised applications to AKS using the KubernetesManifest@0 task. This task applies Kubernetes YAML manifests to the cluster, with built-in support for imagePullSecrets and canary deployments. Connect to the AKS cluster using a Kubernetes service connection configured in Azure DevOps. The task uses kubectl apply under the hood and waits for the rollout to complete before marking the step successful.

# AKS deployment step in Azure Pipelines
- task: KubernetesManifest@0
  displayName: 'Deploy to AKS'
  inputs:
    action: deploy
    kubernetesServiceConnection: 'AKS-Production-SC'
    namespace: production
    manifests: |
      k8s/deployment.yaml
      k8s/service.yaml
    containers: 'mycontainerregistry.azurecr.io/myapp:$(Build.BuildId)'
    imagePullSecrets: acr-secret

Image Tagging Strategy

Tag container images with the build ID ($(Build.BuildId)) or Git commit SHA ($(Build.SourceVersion)) so you can always trace a running container back to the exact code revision that built it. Avoid using the latest tag in production — Kubernetes caches it and may not pull the new version. Store the specific image tag as a pipeline variable and inject it into Kubernetes manifests at deploy time using envsubst or sed.

# Tag and push image with build ID in CI stage
- script: |
    IMAGE='mycontainerregistry.azurecr.io/myapp'
    TAG='$(Build.BuildId)'
    docker build -t $IMAGE:$TAG -t $IMAGE:latest .
    az acr login --name mycontainerregistry
    docker push $IMAGE:$TAG
    docker push $IMAGE:latest
    echo "##vso[task.setvariable variable=imageTag;isOutput=true]$TAG"
  name: BuildImage
  displayName: 'Build and push container image'

Rollback Strategies

Define a rollback strategy for production deployments so you can recover quickly from a bad release. For App Service, rollback means swapping the production slot back to the previous staging version. For AKS, use kubectl rollout undo. Build a dedicated rollback pipeline or add a manual rollback job that can be triggered from the Azure DevOps portal. Document the rollback procedure and practice it regularly — an untested rollback is not a rollback.

# Rollback job triggered manually
- job: Rollback
  condition: and(failed(), eq(variables['Build.Reason'], 'Manual'))
  steps:
  # App Service rollback: swap production back to previous
  - task: AzureAppServiceManage@0
    inputs:
      azureSubscription: 'AzureProductionSC'
      action: Swap Slots
      webAppName: myUniqueWebApp
      resourceGroupName: MyRG
      sourceSlot: production  # Swap production back to staging version
      targetSlot: staging

Deployment Notifications and Monitoring

After each production deployment, automatically run a monitoring check to confirm the new version is healthy. Use the AzureMonitor@1 pipeline check to query Azure Monitor metrics — if error rates are elevated post-deployment, block further pipeline progression and trigger a rollback. Send deployment notifications to Microsoft Teams or Slack via webhook tasks so the team knows when a deployment completes and what version is live.

# Send Teams notification on deployment completion
- task: InvokeRestAPI@1
  displayName: 'Notify Teams channel'
  inputs:
    connectionType: connectedServiceName
    serviceConnection: 'TeamsWebhookSC'
    method: POST
    body: '{
      "text": "Deployed **$(Build.BuildId)** to Production. Committed by $(Build.RequestedFor). <br>View: https://myapp.contoso.com"
    }'
    waitForCompletion: false

CD Best Practices

Follow these continuous deployment best practices: deploy frequently (small batches reduce risk), use feature flags to decouple deployment from release, automate all quality gates before production, practise production-like staging so differences don't mask bugs, monitor deployment windows with automated health checks, and always have a tested rollback plan. A mature CD pipeline makes deployment a non-event rather than a high-stress operation.

Quick Check

Test your understanding of Microsoft Azure Fundamentals (AZ-900) concepts from this lesson.

Lesson Recap

In this lesson you learned: multi-stage YAML pipelines chain Build, Staging, and Production stages with artifact passing, deployment jobs with Environments enable approval gates and deployment tracking, and smoke tests after staging deployment prevent broken releases from reaching production. Next up we explore GitHub Actions on Azure.

Frequently asked questions

Is the “Continuous Deployment to Azure” lesson free?

Yes — the full text of “Continuous Deployment to Azure” is free to read here on the web, and the Cloud & IT Cert Prep course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Cloud & IT Cert Prep course, upgrade to CoddyKit PRO.

What will I learn in “Continuous Deployment to Azure”?

Extend the pipeline with a deployment stage that pushes the build artifact to an App Service slot, runs smoke tests, and swaps to production on approval. You practise Cloud & IT Cert Prep with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Cloud & IT Cert Prep?

No prior experience is required. Cloud & IT Cert Prep on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Continuous Deployment to Azure” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Cloud & IT Cert Prep lesson?

Yes. Every Cloud & IT Cert Prep lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Azure DevOps Services Overview
  2. Building a CI Pipeline with Azure Pipelines
  3. Continuous Deployment to Azure
  4. GitHub Actions on Azure
← Back to Cloud & IT Cert Prep