Deploy Azure App Service and Function Apps
To deploy your application to Azure App Service or Function Apps, you can use
the
release-azure-appsvc
resusable workflow.
Overview
This workflow builds your application using turbo, packages it into a zip
artifact, and deploys it to Azure App Service or Function Apps. If a staging
slot is available, it performs a blue-green deployment.
It also supports canary deployment, allowing you to redirect a percentage of traffic to the new deployment before swapping it with the production slot.
Requirements
- The repository must be a JavaScript monorepo, with
YarnorPNPMas package manager andturboas build tool. - The workspace being deployed must have a
buildscript in itspackage.json - The repository must have been initialized with the azure-github-environment-bootstrap module, which creates the required environment, permissions and roles to perform the deployment.
Features
Artifact building
This workflow builds the application and packages it into a zip artifact, which
contains the code and its dependencies stored in the node_modules folder, and
can be deployed to Azure App Service and Function Apps.
The build is performed using the turbo build command from the root of the
monorepo. The workspace being deployed must have a build script in its
package.json and be tracked in the turbo.json file.
Example of turbo.json file:
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**/*.ts"],
"outputs": ["dist/**", "bin/**"]
}
}
}
Deploying Next.js apps
This worklow supports deploying Next.js apps in standalone mode. To make your
application deployable, you must set the output: "standalone" option in your
next.config.ts file.
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "standalone",
// other Next.js configuration options
// ...
};
export default nextConfig;
Auto-approve staging slot deployments
When the web app has a staging slot, the workflow will first deploy the
artifact to it and then swap it with the production slot.
This deployment requires an approval that can be automated by using a GitHub Bot user with the appropriate permissions.
This feature is enabled by default, but you can disable it by setting the
disable_auto_staging_deploy input to true.
Enabling Auto-Approval
To use the Auto-Approval for staging slot deployments, you need a PAT with required permissions stored in your GitHub repository.
-
Ask your Engineering Leader to create a Personal Access Token (PAT) with the following permissions to your repository:
Permission Access Level Actions Read Contents Read Deployments Read and write Environments Read The PAT should be associated with a user (e.g.,
pagopa-bot) that has permission to approve deployments in the repository. -
Edit the bootstrap module (
./infra/bootstrapper) to add the PAT as Github Repository Secret, via Terraform. The secret must be namedGH_TOKEN_DEPLOYMENT_APPROVAL.data "azurerm_key_vault_secret" "gh_token_deployment_approval" {
name = "gh-token-deployment-approval"
key_vault_id = module.core_values.common_key_vault.id
}
resource "github_actions_secret" "gh_token_deployment_approval" {
repository = var.repository.name
secret_name = "GH_TOKEN_DEPLOYMENT_APPROVAL"
plaintext_value = data.azurerm_key_vault_secret.gh_token_deployment_approval.value
}
Canary deployments
This workflow supports canary deployments by executing the canary-monitor.sh
script, which should be located in the root directory of your repository. After
deploying to the staging slot, this script will run to determine the
percentage of traffic that should be routed to the new deployment.
By default, when the canary-monitor.sh script is not present, the workflow
will route 100% of the traffic to the new deployment.
Enabling Canary Deployments
To enable canary deployments, you need to create a canary-monitor.sh script in
the root directory of your repository. This script should contain the logic to
determine the percentage of traffic to route to the new deployment.
The script will be called with the following arguments:
bash canary-monitor.sh <resource_group_name> <web_app_name> <current_percentage>
And it should return a JSON containing the new percentage of traffic to route
and a delayMs value to wait before the next check, like this:
{
"nextPercentage": 50,
"delayMs": 60000
}
If the script returns a non-zero exit code, the workflow will stop and will redirect all the traffic to the production slot, effectively rolling back the deployment.
Safe swapping
To avoid deploying non-healthy applications, the workflow requires the web app to have set the following variables:
WEBSITE_SWAP_WARMUP_PING_PATH: The path to ping to check if the app is healthy before swapping.WEBSITE_SWAP_WARMUP_PING_STATUSES: The HTTP status codes that are considered healthy (e.g.,200,202,204).
If these variables are not set, the workflow will stop and will not deploy the
code, even to the staging slot.
These variables are set automatically by the DX
azure_app_service
and
azure-function-app
modules, so make sure to use their latest version.
Usage
To use this workflow, invoke it from your own GitHub Actions workflow file.
name: Deploy (my-app)
on:
push:
branches:
- main
jobs:
deploy_app:
uses: pagopa/dx/.github/workflows/release-azure-appsvc-v1.yaml@main
name: Deploy My App
with:
workspace_name: "my-app"
environment: "app-prod"
resource_group_name: "my-resource-group"
web_app_name: "my-app-func-01"
Migration Guide
From web_app_deploy.yaml and function_app_deploy.yaml
-
Replace workflow referenced in the
useskey with the newrelease-azure-appsvc-v1.yamlworkflow.deploy_app:
uses: pagopa/dx/.github/workflows/function_app_deploy.yaml@main
name: Deploy My App
with:
workspace_name: "my-app"
environment: "app-prod"
resource_group_name: "my-resource-group"
function_app_name: "my-app-func-01"
use_staging_slot: true -
Remove the
use_staging_slotinput (the new workflow calls azure at runtime to check if the staging slot is available).deploy_app:
uses: pagopa/dx/.github/workflows/release-azure-appsvc-v1.yaml@main
name: Deploy My App
with:
workspace_name: "my-app"
environment: "app-prod"
resource_group_name: "my-resource-group"
function_app_name: "my-app-func-01" -
Replace the
function_app_nameinput withweb_app_name. The termweb_appis used by Azure to refer to both App Services and Function Apps.deploy_app:
uses: pagopa/dx/.github/workflows/release-azure-appsvc-v1.yaml@main
name: Deploy My App
with:
workspace_name: "my-app"
environment: "app-prod"
resource_group_name: "my-resource-group"
web_app_name: "my-app-func-01" -
Disable the auto-approval of staging slot deployments by setting the
disable_auto_staging_deployinput totrue. This settings can disabled once you configure the Auto-Approval for staging slot deployments.deploy_app:
uses: pagopa/dx/.github/workflows/release-azure-appsvc-v1.yaml@main
name: Deploy My App
with:
workspace_name: "my-app"
environment: "app-prod"
resource_group_name: "my-resource-group"
web_app_name: "my-app-func-01"
disable_auto_staging_deploy: true