Create Azure DevOps Pipeline for React App deployment to Azure app service

 Disclaimer: All opinions in this post are mine and not my employer (Microsoft). If you know of a more correct or performant way to accomplish work discussed in this post, please let me know at email javascript-developer@outlook.com. Many projects I work on are in progress by the time I work on them. I can't change previous design or architecture choices, but just solve a specific technical issue. 

Secrets stored in Azure Key Vault

All secrets for the React app are stored in Azure Key Vault. These secrets need to be pulled from Key Vault and set into the environment so that the `npm build` script uses those values. In order for the Azure DevOps Pipeline to connect to Azure Key Vault, you need to complete some work before you develop your Pipeline:

  • Create a Key Vault and store your React build secrets, such as an Azure Functions key, used to authenticate and use the Function. Your secret doesn't have to have the same name as your React build variable. Please don't try. Key vault secrets don't allow underscores in names anyway. Just give the variable a human readable name. The pipeline can map between the secret name and the build environment name.
  • Create a connection from Pipelines to Key Vault - In Azure DevOps, in the project settings, add a service connection to Azure Key Vault. This process creates a service principal. You can find all your service principals in Azure Portal, under the Azure Active Directory section. Service Principals are part of Azure App Registrations. 
  • Set up Azure Key Vault access policies - In the Azure portal, find your Key Vault, and add the Pipeline's Service Principal for `list` and `get`. 

Create an Azure DevOps Pipeline to build React app

The React app is deployed to an Azure app service wrapped in a .NET Core application. The vmImage is `windows-latest`. 

The YAML file is:


# ASP.NET Core (.NET Framework)


# Build and test ASP.NET Core projects targeting the full .NET Framework.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core

trigger:
main

pool:
  vmImage'windows-latest'

# Variables used in this pipeline
# The `dinatrue` variables is a test used in the echo command to understand the syntax for container:
# bringing in variables.
variables:
  solution'**/*.sln'
  buildPlatform'Any CPU'
  buildConfiguration'Release'
  dinatrue'hello dina'
  buildDate$[format('{0:yyyy}{0:MM}{0:dd}', pipeline.startTime)]


steps:

# Get React app secrets from Key Vault
# Key Vault is used for projects beyond this single client app. If the Key Vault
# were only for this client app, change the `SecretsFilter` value to `*`.
taskAzureKeyVault@2
  inputs:
    azureSubscription'SQL Projects (98c...)'
    KeyVaultName'MSTwitterKeyVault'
    SecretsFilter'PublicApiMessageBeforeLoginKey,PublicApiGetUtcNowKey,PublicApiUrl,ServerUri'
    RunAsPreJobfalse

# Verify/debug variables
taskCmdLine@2
  inputs:
    script'echo %dinatrue% %buildDate%'

# Set Key vault secrets to React app environment variables
# Verify/debug values with SET command
# secrets' values will be `***` on purpose
taskCmdLine@2
  inputs:
    script'SET > env.log && cat env.log'
  env:
    REACT_APP_APP_SERVER_BASE_URL_PUBLIC_API_APP_MESSAGE_BEFORE_LOGIN_KEY$(PublicApiMessageBeforeLoginKey)
    REACT_APP_APP_SERVER_BASE_URL_PUBLIC_API_GET_UTC_NOW_KEY$(PublicApiGetUtcNowKey)
    REACT_APP_APP_SERVER_BASE_URL_PUBLIC_API$(PublicApiUrl)
    REACT_APP_SERVER_URL$(ServerUri)
    REACT_APP_CACHE_BUST$(buildDate)

# Get source code from repo
taskNuGetCommand@2
  inputs:
    restoreSolution'$(solution)'

# Build project, which ultimately builds React app into `$(build.artifactStagingDirectory)\WebApp.zip`
taskVSBuild@1
  inputs:
    solution'$(solution)'
    msbuildArgs'/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
    platform'$(buildPlatform)'
    configuration'$(buildConfiguration)'

# Deploy Zip file to Azure app service, slot named `client-stage` using webDeploy
taskAzureRmWebAppDeployment@4
  inputs:
    ConnectionType'AzureRM'
    azureSubscription'SQL Projects (98c...)'
    appType'webApp'
    WebAppName'MSTwitterApp'
    deployToSlotOrASEtrue
    ResourceGroupName'MSTwitterBot'
    SlotName'client-stage'
    packageForLinux'$(build.artifactStagingDirectory)\WebApp.zip'
    enableCustomDeploymenttrue
    DeploymentType'webDeploy'


Popular posts from this blog

Yet once more into the breech (of altered programming logic)

Simple WP7 Mango App for Background Tasks, Toast, and Tiles: Code Explanation

How to convert SVG data to a Png Image file Using InkScape