Umbraco Deployment on Azure

  • Page Owner: Not Set
  • Last Reviewed: 2025-08-26

Create the AppSettings.Production.json and AppSettings.QA.json file

The appsettings.*.json file is necessary to add some app settings that allow Umbraco to run successfully in an Azure environment. Additionally add items needed for each environment.

{
  "$schema": "./umbraco/config/appsettings-schema.json",
  "Uumbraco": {
    "CMS": {
      "Content": {
        "MacroErrors": "Inline"
      },
    },
    "Storage": {
      "AzureBlob": {
        "Media": {
          "ConnectionString": "[ConnectionStringToBlobStorage]",
          "ContainerName": "[ContainerName]"
        }
      }
    },
  }
}

Put this file in the same location as the site's appsettings.json file. Add it to the csproj file as a dependency on the appsettings.json file. It should look like this:

<Content Include="appsettings.*.json">
  <DependentUpon>appsettings.config</DependentUpon>
</Content>

Create the DevOps Service Connection

You'll need a Service Connection to give your pipeline the ability to deploy.‌

  1. In DevOps, go to the Project Settings -> Service Connections

  2. Create a new Azure Resource Manager service connection

  3. Select Service Principal (automatic)

  4. Select the Blend Azure subscription (Blend Pay-as-you-go) and the Resource Group that the App Service lives in (for example, Blend-Interactive)

  5. Leave "Grant access permission to all pipelines" checked

  6. Save‌

Add the azure-pipelines.yml file

Create an azure-pipelines.yml file in the root of your project. The content should be similar to the following:
- This file will be used for all environment releases and configured with variables for each pipeline.

trigger:
- qa

pool: 'Default'

# Required Pipeline Variables
# webAppName: the azure web app name.
# slack_success_text: text to display in slack for success.
# slack_failure_text: text to dispaly in slack for failure.
# slack_channel: slack channel id.
# slack_token: slack token for Blend Bot App.

variables:
  proj: '.\pathto\proj.csproj'
  siteFolder: 'SiteFolder'
  buildConfiguration: 'Release'

steps:
- task: UseDotNet@2
  displayName: 'Install .NET 5.0 SDK'
  inputs:
    version: '5.0.x'

- task: DotNetCoreCLI@2
  displayName: 'Restore packages'
  inputs:
    command: 'restore'
    projects: '$(proj)'
    feedsToUse: 'config'
    nugetConfigPath: '.\nuget.config'

- task: Npm@1
  displayName: 'Install NPM dependencies'
  inputs:
    command: 'install'

- task: gulp@0
  displayName: 'Gulp Build'
  inputs:
    gulpFile: 'gulpfile.js'
    targets: 'build'
    gulpjs: 'node_modules/gulp/bin/gulp.js'
    enableCodeCoverage: false

- task: DotNetCoreCLI@2
  displayName: 'Build Solution'
  inputs:
    command: 'build'
    projects: '$(proj)'
    arguments: '--configuration $(buildConfiguration)'

- task: DotNetCoreCLI@2
  displayName: 'Publish Project'
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: false

- task: AzureRmWebAppDeployment@4
  inputs:
    ConnectionType: 'AzureRM'
    azureSubscription: 'Blend Azure Access'
    appType: 'webApp'
    WebAppName: '$(webAppName)'
    packageForLinux: '$(build.artifactstagingdirectory)/$(siteFolder)'
    enableCustomDeployment: true
    DeploymentType: webDeploy

- task: AzureAppServiceManage@0
  inputs:
    azureSubscription: 'Blend Azure Access'
    Action: 'Restart Azure App Service'
    WebAppName: '$(webAppName)'

- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      $headers = @{
          Authorization="Bearer ${env:TOKEN}"
      }
      
      $text = iex "`"${env:SLACK_SUCCESS_TEXT}`""
      
      $payload = @{
          "icon_emoji" = ":large_green_circle:"
          "text" = "${text}"
          "channel" = "${env:SLACK_CHANNEL}"
      }
      
      [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
      Invoke-WebRequest `
          -UseBasicParsing `
          -Headers $headers `
          -Body (ConvertTo-Json -Compress -InputObject $payload) `
          -Method Post `
          -ContentType "application/json" `
          -Uri "https://slack.com/api/chat.postMessage"
    errorActionPreference: 'continue'
  env:
    TOKEN: $(SLACK_TOKEN)

- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      $headers = @{
          Authorization="Bearer ${env:TOKEN}"
      }
      
      $text = iex "`"${env:SLACK_FAILURE_TEXT}`""
      
      $payload = @{
          "icon_emoji" = ":red_circle:"
          "text" = "${text}"
          "channel" = "${env:SLACK_CHANNEL}"
      }
      
      [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
      Invoke-WebRequest `
          -UseBasicParsing `
          -Headers $headers `
          -Body (ConvertTo-Json -Compress -InputObject $payload) `
          -Method Post `
          -ContentType "application/json" `
          -Uri "https://slack.com/api/chat.postMessage"
  env:
    TOKEN: $(SLACK_TOKEN)
  condition: failed()

Commit all the new and updated files and merge to master.‌

Create the Pipeline in Azure‌

Finally, with all this set up, you can create a pipeline to run the build.‌

  1. Go to Pipelines -> New Pipeline

  2. Choose Azure Git as your source

  3. Select the repository for your project

  4. Select "Existing Azure Pipeline YAML" at the bottom

  5. Choose the branch you want to deploy, and the path to the azure-pipelines.yml