Cloud Networking
Cloud Networking
Azure App Service is an HTTP-based service for hosting web applications, REST APIs, and mobile back ends. You
can develop in your favorite language, be it .NET, .NET Core, Java, Ruby, Node.js, PHP, or Python. Applications run
and scale with ease on both Windows and Linux-based environments.
App Service not only adds the power of Microsoft Azure to your application, such as security, load balancing,
autoscaling, and automated management. You can also take advantage of its DevOps capabilities, such as
continuous deployment from Azure DevOps, GitHub, Docker Hub, and other sources, package management,
staging environments, custom domain, and TLS/SSL certificates.
With App Service, you pay for the Azure compute resources you use. The compute resources you use are
determined by the App Service plan that you run your apps on. For more information, see Azure App Service
plans overview.
NOTE
Linux and Windows App Service plans can now share resource groups. This limitation has been lifted from the platform
and existing resource groups have been updated to support this.
Next steps
Create your first web app.
ASP.NET Core (on Windows or Linux)
ASP.NET (on Windows)
PHP (on Windows or Linux)
Ruby (on Linux)
Node.js (on Windows or Linux)
Java (on Windows or Linux)
Python (on Linux)
HTML (on Windows or Linux)
Custom container (Windows or Linux)
App Service Environment overview
5/18/2022 • 7 minutes to read • Edit Online
An App Service Environment is an Azure App Service feature that provides a fully isolated and dedicated
environment for running App Service apps securely at high scale.
NOTE
This article covers the features, benefits, and use cases of App Service Environment v3, which is used with App Service
Isolated v2 plans.
Usage scenarios
App Service Environments have many use cases, including:
Internal line-of-business applications.
Applications that need more than 30 App Service plan instances.
Single-tenant systems to satisfy internal compliance or security requirements.
Network-isolated application hosting.
Multi-tier applications.
There are many networking features that enable apps in a multi-tenant App Service to reach network-isolated
resources or become network-isolated themselves. These features are enabled at the application level. With an
App Service Environment, no added configuration is required for the apps to be on a virtual network. The apps
are deployed into a network-isolated environment that's already on a virtual network. If you really need a
complete isolation story, you can also deploy your App Service Environment onto dedicated hardware.
Dedicated environment
An App Service Environment is a single-tenant deployment of Azure App Service that runs on your virtual
network.
Applications are hosted in App Service plans, which are created in an App Service Environment. An App Service
plan is essentially a provisioning profile for an application host. As you scale out your App Service plan, you
create more application hosts with all the apps in that App Service plan on each host. A single App Service
Environment v3 can have up to 200 total App Service plan instances across all the App Service plans combined.
A single App Service Isolated v2 (Iv2) plan can have up to 100 instances by itself.
When you're deploying onto dedicated hardware (hosts), you're limited in scaling across all App Service plans to
the number of cores in this type of environment. An App Service Environment that's deployed on dedicated
hosts has 132 vCores available. I1v2 uses two vCores, I2v2 uses four vCores, and I3v2 uses eight vCores per
instance.
Feature differences
App Service Environment v3 differs from earlier versions in the following ways:
There are no networking dependencies on the customer's virtual network. You can secure all inbound and
outbound traffic and route outbound traffic as you want.
You can deploy an App Service Environment v3 that's enabled for zone redundancy. You set zone redundancy
only during creation and only in regions where all App Service Environment v3 dependencies are zone
redundant.
You can deploy an App Service Environment v3 on a dedicated host group. Host group deployments aren't
zone redundant.
Scaling is much faster than with an App Service Environment v2. Although scaling still isn't immediate, as in
the multi-tenant service, it's a lot faster.
Front-end scaling adjustments are no longer required. App Service Environment v3 front ends automatically
scale to meet your needs and are deployed on better hosts.
Scaling no longer blocks other scale operations within the App Service Environment v3. Only one scale
operation can be in effect for a combination of OS and size. For example, while your Windows small App
Service plan is scaling, you could kick off a scale operation to run at the same time on a Windows medium or
anything else other than Windows small.
You can reach apps in an internal-VIP App Service Environment v3 across global peering. Such access wasn't
possible in earlier versions.
A few features that were available in earlier versions of App Service Environment aren't available in App Service
Environment v3. For example, you can no longer do the following:
Send SMTP traffic. You can still have email triggered alerts but your app can't send outbound traffic on port
25.
Monitor your traffic with Network Watcher or network security group (NSG) flow logs.
Configure an IP-based Transport Layer Security (TLS) or Secure Sockets Layer (SSL) binding with your apps.
Configure a custom domain suffix.
Perform a backup and restore operation on a storage account behind a firewall.
Pricing
With App Service Environment v3, the pricing model varies depending on the type of App Service Environment
deployment you have. The three pricing models are:
App Ser vice Environment v3 : If the App Service Environment is empty, there's a charge as though you
have one instance of Windows I1v2. The one instance charge isn't an additive charge but is applied only if the
App Service Environment is empty.
Zone redundant App Ser vice Environment v3 : There's a minimum charge of nine instances. There's no
added charge for availability zone support if you have nine or more App Service plan instances. If you have
fewer than nine instances (of any size) across App Service plans in the zone redundant App Service
Environment, the difference between nine and the running instance count is charged as additional Windows
I1v2 instances.
Dedicated host App Ser vice Environment v3 : With a dedicated host deployment, you're charged for two
dedicated hosts per our pricing when you create the App Service Environment v3 and then, as you scale,
you're charged a small percentage of the Isolated v2 rate per core.
Reserved Instance pricing for Isolated v2 is available and is described in How reservation discounts apply to
Azure App Service. The pricing, along with Reserved Instance pricing, is available at App Service pricing under
the Isolated v2 plan.
Regions
App Service Environment v3 is available in the following regions:
Central US East US
UAE North
UK South
UK West
West Central US
West Europe
West US
West US 2
N O RM A L A N D DEDIC AT ED H O ST REGIO N S AVA IL A B IL IT Y Z O N E REGIO N S
West US 3
US Gov Texas
US Gov Arizona
US Gov Virginia
Next steps
Whitepaper on Using App Service Environment v3 in Compliance-Oriented Industries
Quickstart: Deploy an ASP.NET web app
5/18/2022 • 15 minutes to read • Edit Online
In this quickstart, you'll learn how to create and deploy your first ASP.NET web app to Azure App Service. App
Service supports various versions of .NET apps, and provides a highly scalable, self-patching web hosting
service. ASP.NET web apps are cross-platform and can be hosted on Linux or Windows. When you're finished,
you'll have an Azure resource group consisting of an App Service hosting plan and an App Service with a
deployed web application.
Prerequisites
.NET 6.0
.NET Framework 4.8
.NET 6.0
.NET Framework 4.8
Install the latest .NET 6.0 SDK.
An Azure account with an active subscription. Create an account for free.
The Azure CLI.
The .NET SDK (includes runtime and CLI).
.NET 6.0
.NET Framework 4.8
Install the latest .NET 6.0 SDK.
An Azure account with an active subscription. Create an account for free.
The Azure PowerShell.
The .NET SDK (includes runtime and CLI).
.NET 6.0
.NET Framework 4.8
Install the latest .NET 6.0 SDK.
1. In the terminal window, create a new folder named MyFirstAzureWebApp, and open it in Visual Studio
Code.
mkdir MyFirstAzureWebApp
code MyFirstAzureWebApp
.NET 6.0
.NET Framework 4.8
4. From the Terminal in Visual Studio Code, run the application locally using the dotnet run command.
.NET 6.0
.NET Framework 4.8
You'll see the template ASP.NET Core 6.0 web app displayed in the page.
1. Open a terminal window on your machine to a working directory. Create a new .NET web app using the
dotnet new webapp command, and then change directories into the newly created app.
.NET 6.0
.NET Framework 4.8
2. From the same terminal session, run the application locally using the dotnet run command.
.NET 6.0
.NET Framework 4.8
You'll see the template ASP.NET Core 6.0 web app displayed in the page.
3. Choose the Specific target , either Azure App Ser vice (Linux) or Azure App Ser vice (Windows) .
Then, select Next .
IMPORTANT
When targeting ASP.NET Framework 4.8, use Azure App Ser vice (Windows) .
4. Your options depend on whether you're signed in to Azure already and whether you have a Visual Studio
account linked to an Azure account. Select either Add an account or Sign in to sign in to your Azure
subscription. If you're already signed in, select the account you want.
5. To the right of App Ser vice instances , select + .
6. For Subscription , accept the subscription that is listed or select a new one from the drop-down list.
7. For Resource group , select New . In New resource group name , enter myResourceGroup and select
OK .
8. For Hosting Plan , select New .
9. In the Hosting Plan: Create new dialog, enter the values specified in the following table:
SET T IN G SUGGEST ED VA L UE DESC RIP T IO N
10. In Name , enter a unique app name that includes only the valid characters are a-z , A-Z , 0-9 , and - .
You can accept the automatically generated unique name. The URL of the web app is
http://<app-name>.azurewebsites.net , where <app-name> is your app name.
You'll see the ASP.NET Core 6.0 web app displayed in the page.
1. In Visual Studio Code, open the Command Palette , Ctrl+Shift+P.
2. Search for and select "Azure App Service: Deploy to Web App".
3. Respond to the prompts as follows:
a. Select MyFirstAzureWebApp as the folder to deploy.
b. Select Add Config when prompted.
c. If prompted, sign in to your Azure account.
d. Select your Subscription .
e. Select Create new Web App... Advanced .
f. For Enter a globally unique name , use a name that's unique across all of Azure (valid characters
are a-z , 0-9 , and - ). A good pattern is to use a combination of your company name and an app
identifier.
g. Select Create new resource group and provide a name like myResourceGroup .
h. When prompted to Select a runtime stack :
For .NET 6.0, select .NET 6
For .NET Framework 4.8, select ASP.NET V4.8
a. Select an operating system (Windows or Linux).
For .NET Framework 4.8, Windows will be selected implicitly.
b. Select a location near you.
c. Select Create a new App Ser vice plan , provide a name, and select the F1 Free pricing tier.
d. Select Skip for now for the Application Insights resource.
4. In the popup Always deploy the workspace "MyFirstAzureWebApp" to <app-name>" , select Yes
so that Visual Studio Code deploys to the same App Service app every time you're in that workspace.
5. When publishing completes, select Browse Website in the notification and select Open when
prompted.
.NET 6.0
.NET Framework 4.8
You'll see the ASP.NET Core 6.0 web app displayed in the page.
1. Sign into your Azure account by using the az login command and following the prompt:
az login
2. Deploy the code in your local MyFirstAzureWebApp directory using the az webapp up command:
az webapp up --sku F1 --name <app-name> --os-type <os>
If the az command isn't recognized, ensure you have the Azure CLI installed as described in
Prerequisites.
Replace <app-name> with a name that's unique across all of Azure (valid characters are a-z , 0-9 , and
- ). A good pattern is to use a combination of your company name and an app identifier.
The --sku F1 argument creates the web app on the Free pricing tier. Omit this argument to use a
faster premium tier, which incurs an hourly cost.
Replace <os> with either linux or windows . You must use windows when targeting ASP.NET
Framework 4.8.
You can optionally include the argument --location <location-name> where <location-name> is an
available Azure region. You can retrieve a list of allowable regions for your Azure account by running
the az account list-locations command.
The command might take a few minutes to complete. While running, it provides messages about creating
the resource group, the App Service plan, and hosting app, configuring logging, then performing ZIP
deployment. Then it shows a message with the app's URL:
.NET 6.0
.NET Framework 4.8
You'll see the ASP.NET Core 6.0 web app displayed in the page.
NOTE
Azure PowerShell is recommended for creating apps on the Windows hosting platform. To create apps on Linux, use a
different tool, such as Azure CLI.
1. Sign into your Azure account by using the Connect-AzAccount command and following the prompt:
Connect-AzAccount
Replace <app-name> with a name that's unique across all of Azure (valid characters are a-z , 0-9 , and
- ). A combination of your company name and an app identifier is a good pattern.
You can optionally include the parameter -Location <location-name> where <location-name> is an
available Azure region. You can retrieve a list of allowable regions for your Azure account by running
the Get-AzLocation command.
The command might take a few minutes to complete. While running, it creates a resource group, an App
Service plan, and the App Service resource.
3. From the application root folder, prepare your local MyFirstAzureWebApp application for deployment
using the dotnet publish command:
4. Change to the release directory and create a zip file from the contents:
.NET 6.0
.NET Framework 4.8
cd bin\Release\net6.0\publish
Compress-Archive -Path * -DestinationPath deploy.zip
5. Publish the zip file to the Azure app using the Publish-AzWebApp command:
NOTE
-ArchivePath needs the full path of the zip file.
.NET 6.0
.NET Framework 4.8
You'll see the ASP.NET Core 6.0 web app displayed in the page.
Update the app and redeploy
Follow these steps to update and redeploy your web app:
1. In Solution Explorer , under your project, open Index.cshtml.
2. Replace the first <div> element with the following code:
<div class="jumbotron">
<h1>.NET Azure</h1>
<p class="lead">Example .NET app to Azure App Service.</p>
</div>
You'll see the updated ASP.NET Core 6.0 web app displayed in the page.
1. Open Index.cshtml.
2. Replace the first <div> element with the following code:
<div class="jumbotron">
<h1>.NET Azure</h1>
<p class="lead">Example .NET app to Azure App Service.</p>
</div>
.NET 6.0
.NET Framework 4.8
You'll see the updated ASP.NET Core 6.0 web app displayed in the page.
In the local directory, open the Index.cshtml file. Replace the first <div> element:
<div class="jumbotron">
<h1>.NET Azure</h1>
<p class="lead">Example .NET app to Azure App Service.</p>
</div>
Save your changes, then redeploy the app using the az webapp up command again:
.NET 6.0
.NET Framework 4.8
ASP.NET Core 6.0 is cross-platform, based on your previous deployment replace <os> with either linux or
windows .
This command uses values that are cached locally in the .azure/config file, including the app name, resource
group, and App Service plan.
Once deployment has completed, switch back to the browser window that opened in the Browse to the app
step, and hit refresh.
.NET 6.0
.NET Framework 4.8
You'll see the updated ASP.NET Core 6.0 web app displayed in the page.
1. In the local directory, open the Index.cshtml file. Replace the first <div> element:
<div class="jumbotron">
<h1>.NET Azure</h1>
<p class="lead">Example .NET app to Azure App Service.</p>
</div>
2. From the application root folder, prepare your local MyFirstAzureWebApp application for deployment
using the dotnet publish command:
3. Change to the release directory and create a zip file from the contents:
.NET 6.0
.NET Framework 4.8
cd bin\Release\net6.0\publish
Compress-Archive -Path * -DestinationPath deploy.zip
4. Publish the zip file to the Azure app using the Publish-AzWebApp command:
5. Once deployment has completed, switch back to the browser window that opened in the Browse to the
app step, and hit refresh.
.NET 6.0
.NET Framework 4.8
You'll see the updated ASP.NET Core 6.0 web app displayed in the page.
On the App Ser vices page, select the name of your web app.
The Over view page for your web app, contains options for basic management like browse, stop, start, restart,
and delete. The left menu provides further pages for configuring your app.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, you can delete them by deleting the resource group.
1. From your web app's Over view page in the Azure portal, select the myResourceGroup link under
Resource group .
2. On the resource group page, make sure that the listed resources are the ones you want to delete.
3. Select Delete , type myResourceGroup in the text box, and then select Delete .
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, you can delete them by deleting the resource group.
1. From your web app's Over view page in the Azure portal, select the myResourceGroup link under
Resource group .
2. On the resource group page, make sure that the listed resources are the ones you want to delete.
3. Select Delete , type myResourceGroup in the text box, and then select Delete .
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following PowerShell command:
Next steps
In this quickstart, you created and deployed an ASP.NET web app to Azure App Service.
.NET 6.0
.NET Framework 4.8
Advance to the next article to learn how to create a .NET Core app and connect it to a SQL Database:
Tutorial: ASP.NET Core app with SQL database
Configure ASP.NET Core app
Create a Node.js web app in Azure
5/18/2022 • 12 minutes to read • Edit Online
In this quickstart, you'll learn how to create and deploy your first Node.js (Express) web app to Azure App
Service. App Service supports various versions of Node.js on both Linux and Windows.
This quickstart configures an App Service app in the Free tier and incurs no cost for your Azure subscription.
TIP
If you have already completed the Node.js tutorial, you can skip ahead to Deploy to Azure.
1. Create a Node.js application using the Express Generator, which is installed by default with Node.js and
NPM.
Deploy to Azure
Before you continue, ensure that you have all the prerequisites installed and configured.
NOTE
For your Node.js application to run in Azure, it needs to listen on the port provided by the PORT environment variable.
In your generated Express app, this environment variable is already used in the startup script bin/www (search for
process.env.PORT ).
Sign in to Azure
1. In the terminal, ensure you're in the myExpressApp directory, then start Visual Studio Code with the
following command:
code .
2. In Visual Studio Code, in the Activity Bar, select the Azure logo.
3. In the App Ser vice explorer, select Sign in to Azure... and follow the instructions.
In Visual Studio Code, you should see your Azure email address in the Status Bar and your subscription in
the AZURE APP SERVICE explorer.
I ran into an issue
Configure the App Service app and deploy code
1. In the App Ser vice explorer, select the Deploy to Web App icon.
Deploy to Linux
Deploy to Windows
Deploy to Linux
Deploy to Windows
If the az command isn't recognized, ensure you have the Azure CLI installed as described in Set up your
initial environment.
Replace <app_name> with a name that's unique across all of Azure (valid characters are a-z , 0-9 , and - ). A
good pattern is to use a combination of your company name and an app identifier.
The --sku F1 argument creates the web app on the Free pricing tier, which incurs a no cost.
You can optionally include the argument --location <location-name> where <location_name> is an available
Azure region. You can retrieve a list of allowable regions for your Azure account by running the
az account list-locations command.
The command creates a Linux app for Node.js by default. To create a Windows app instead, use the
--os-type argument.
If you see the error, "Could not auto-detect the runtime stack of your app," ensure you're running the
command in the myExpressApp directory (See Troubleshooting auto-detect issues with az webapp up).
The command may take a few minutes to complete. While running, it provides messages about creating the
resource group, the App Service plan, and the app resource, configuring logging, and doing ZIP deployment. It
then gives the message, "You can launch the app at http://<app-name>.azurewebsites.net", which is the app's
URL on Azure.
NOTE
The az webapp up command does the following actions:
Create a default resource group.
Create a default App Service plan.
Create an app with the specified name.
Zip deploy all files from the current working directory, with build automation enabled.
Cache the parameters locally in the .azure/config file so that you don't need to specify them again when deploying
later with az webapp up or other Azure CLI commands. The cached values are used automatically by default.
4. Under Instance details , type a globally unique name for your web app and select Code . Select Node 14
LTS Runtime stack , an Operating System , and a Region you want to serve your app from.
5. Under App Ser vice Plan , select Create new App Service Plan. Type myAppServicePlan for the name. To
change to the Free tier, select Change size , select Dev/Test tab, select F1 , and select the Apply button at
the bottom of the page.
7. After validation runs, select the Create button at the bottom of the page.
8. After deployment is complete, select Go to resource .
Get FTP credentials
Azure App Service supports two types of credentials for FTP/S deployment. These credentials aren't the
same as your Azure subscription credentials. In this section, you get the application-scope credentials to use
with FileZilla.
1. From the App Service app page, select Deployment Center in the left-hand menu and select FTPS
credentials tab.
Redeploy updates
You can deploy changes to this app by making edits in Visual Studio Code, saving your files, and then redeploy
to your Azure app. For example:
1. From the sample project, open views/index.ejs and change
to
<p>Welcome to Azure</p>
2. In the App Ser vice explorer, select the Deploy to Web App icon again, confirm by clicking Deploy
again.
3. Wait for deployment to complete, then select Browse Website in the notification popup. You should see
that the Welcome to Express message has been changed to Welcome to Azure! .
2. Save your changes, then redeploy the app using the az webapp up command again with no arguments:
az webapp up
This command uses values that are cached locally in the .azure/config file, such as the app name, resource
group, and App Service plan.
3. Once deployment is complete, refresh the webpage http://<app-name>.azurewebsites.net . You should see
that the Welcome to Express message has been changed to Welcome to Azure! .
2. Save your changes, then redeploy the app using your FTP client again.
3. Once deployment is complete, refresh the webpage http://<app-name>.azurewebsites.net . You should see
that the Welcome to Express message has been changed to Welcome to Azure! .
Stream Logs
You can stream log output (calls to console.log() ) from the Azure app directly in the Visual Studio Code output
window.
1. In the App Ser vice explorer, right-click the app node and select Star t Streaming Logs .
2. If asked to restart the app, select Yes . Once the app is restarted, the Visual Studio Code output window
opens with a connection to the log stream.
3. After a few seconds, the output window shows a message indicating that you're connected to the log-
streaming service. You can generate more output activity by refreshing the page in the browser.
The command uses the resource group name cached in the .azure/config file.
You can also include the --logs parameter with then az webapp up command to automatically open the log
stream on deployment.
Refresh the app in the browser to generate console logs, which include messages describing HTTP requests to
the app. If no output appears immediately, try again in 30 seconds.
To stop log streaming at any time, press Ctrl +C in the terminal.
You can access the console logs generated from inside the app and the container in which it runs. You can
stream log output (calls to console.log() ) from the Node.js app directly in the Azure portal.
1. In the same App Ser vice page for your app, use the left menu to scroll to the Monitoring section and
select Log stream .
2. After a few seconds, the output window shows a message indicating that you're connected to the log-
streaming service. You can generate more output activity by refreshing the page in the browser.
Connecting...
2021-10-26T21:04:14 Welcome, you are now connected to log-streaming service.
Starting Log Tail -n 10 of existing logs ----
/appsvctmp/volatile/logs/runtime/81b1b83b27ea1c3d598a1cdec28c71c4074ce66c735d0be57f15a8d0
7cb3178e.log
2021-10-26T21:04:08.614384810Z: [INFO]
2021-10-26T21:04:08.614393710Z: [INFO] # Enter the source directory to make sure the
script runs where the user expects
2021-10-26T21:04:08.614399010Z: [INFO] cd "/home/site/wwwroot"
2021-10-26T21:04:08.614403210Z: [INFO]
2021-10-26T21:04:08.614407110Z: [INFO] export
NODE_PATH=/usr/local/lib/node_modules:$NODE_PATH
2021-10-26T21:04:08.614411210Z: [INFO] if [ -z "$PORT" ]; then
2021-10-26T21:04:08.614415310Z: [INFO] export PORT=8080
2021-10-26T21:04:08.614419610Z: [INFO] fi
2021-10-26T21:04:08.614423411Z: [INFO]
2021-10-26T21:04:08.614427211Z: [INFO] node /opt/startup/default-static-site.js
Ending Log Tail of existing logs ---
Clean up resources
In the preceding steps, you created Azure resources in a resource group. The create steps in this quickstart put
all the resources in this resource group. To clean up, you just need to remove the resource group.
1. In the Azure extension of Visual Studio, expand the Resource Groups explorer.
2. Expand the subscription, right-click the resource group you created earlier, and select Delete .
3. When prompted, confirm your deletion by entering the name of the resource group you're deleting. Once
you confirm, the resource group is deleted, and you see a notification when it's done.
I ran into an issue
In the preceding steps, you created Azure resources in a resource group. The resource group has a name like
"appsvc_rg_Linux_CentralUS" depending on your location.
If you don't expect to need these resources in the future, delete the resource group by running the following
command:
The command uses the resource group name cached in the .azure/config file.
The --no-wait argument allows the command to return before the operation is complete.
When no longer needed, you can delete the resource group, App service, and all related resources.
1. From your App Service overview page, select the resource group you created in the Create Azure
resources step.
2. From the resource group page, select Delete resource group . Confirm the name of the resource group
to finish deleting the resources.
Next steps
Congratulations, you've successfully completed this quickstart!
Tutorial: Node.js app with MongoDB
Configure Node.js app
Check out the other Azure extensions.
Cosmos DB
Azure Functions
Docker Tools
Azure CLI Tools
Azure Resource Manager Tools
Or get them all by installing the Node Pack for Azure extension pack.
Create a PHP web app in Azure App Service
5/18/2022 • 11 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This quickstart tutorial shows
how to deploy a PHP app to Azure App Service on Windows.
You create the web app using the Azure CLI in Cloud Shell, and you use Git to deploy sample PHP code to the
web app.
You can follow the steps here using a Mac, Windows, or Linux machine. Once the prerequisites are installed, it
takes about five minutes to complete the steps.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this quickstart:
Install Git
Install PHP
TIP
The branch name change isn't required by App Service. However, since many repositories are changing their
default branch to main , this quickstart also shows you how to deploy a repository from main .
Run the app locally
1. Run the application locally so that you see how it should look when you deploy it to Azure. Open a
terminal window and use the php command to launch the built-in PHP web server.
php -S localhost:8080
O P T IO N EXA M P L E/ L IN K
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE --is-linux
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"freeOfferExpirationTime": null,
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "linux",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
When the web app has been created, the Azure CLI shows output similar to the following example:
You've created an empty new web app, with git deployment enabled.
NOTE
The URL of the Git remote is shown in the deploymentLocalGitUrl property, with the format
https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git . Save this URL as you need it later.
2. Browse to your newly created web app. Replace <app-name> with your unique app name created in the
prior step.
http://<app-name>.azurewebsites.net
2. Back in the local terminal window, add an Azure remote to your local Git repository. Replace
<deploymentLocalGitUrl-from-create-step> with the URL of the Git remote that you saved from Create a
web app.
3. Push to the Azure remote to deploy your app with the following command. When Git Credential Manager
prompts you for credentials, make sure you enter the credentials you created in Configure a
deployment user , not the credentials you use to sign in to the Azure portal.
This command may take a few minutes to run. While running, it displays information similar to the
following example:
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 352 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Updating branch 'main'.
remote: Updating submodules.
remote: Preparing deployment for commit id '25f18051e9'.
remote: Generating deployment script.
remote: Running deployment command...
remote: Handling Basic Web Site deployment.
remote: Kudu sync from: '/home/site/repository' to: '/home/site/wwwroot'
remote: Copying file: '.gitignore'
remote: Copying file: 'LICENSE'
remote: Copying file: 'README.md'
remote: Copying file: 'index.php'
remote: Ignoring: .git
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
To https://<app-name>.scm.azurewebsites.net/<app-name>.git
cc39b1e..25f1805 main -> main
http://<app-name>.azurewebsites.net
The PHP sample code is running in an Azure App Service web app.
2. In the local terminal window, commit your changes in Git, and then push the code changes to Azure.
git commit -am "updated output"
git push azure main
3. Once deployment has completed, return to the browser window that opened during the Browse to the
app step, and refresh the page.
The web app menu provides different options for configuring your app.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
PHP with MySQL
Configure PHP app
Azure App Service provides a highly scalable, self-patching web hosting service. This quickstart shows how to
deploy a PHP app to Azure App Service on Linux.
You create and deploy the web app using Azure CLI.
You can follow the steps here using a Mac, Windows, or Linux machine. Once the prerequisites are installed, it
takes about five minutes to complete the steps.
To complete this quickstart, you need:
1. An Azure account with an active subscription. Create an account for free.
2. Git
3. PHP
4. Azure CLI to run commands in any shell to provision and configure Azure resources.
2. To run the application locally, use the php command to launch the built-in PHP web server.
php -S localhost:8080
az webapp up \
--sku F1 \
--logs
If the az command isn't recognized, be sure you have Azure CLI installed.
The --sku F1 argument creates the web app on the Free pricing tier, which incurs a no cost.
The --logs flag configures default logging required to enable viewing the log stream immediately after
launching the webapp.
You can optionally specify a name with the argument --name <app-name> . If you don't provide one, then a
name will be automatically generated.
You can optionally include the argument --location <location-name> where <location_name> is an
available Azure region. You can retrieve a list of allowable regions for your Azure account by running the
az account list-locations command.
If you see the error, "Could not auto-detect the runtime stack of your app," make sure you're running the
command in the code directory (See Troubleshooting auto-detect issues with az webapp up).
The command may take a few minutes to complete. While running, it provides messages about creating the
resource group, the App Service plan, and the app resource, configuring logging, and doing ZIP deployment. It
then gives the message, "You can launch the app at http://<app-name>.azurewebsites.net", which is the app's
URL on Azure.
NOTE
The az webapp up command does the following actions:
Create a default resource group.
Create a default App Service plan.
Create an app with the specified name.
Zip deploy all files from the current working directory, with build automation enabled.
Cache the parameters locally in the .azure/config file so that you don't need to specify them again when deploying
later with az webapp up or other Azure CLI commands. The cached values are used automatically by default.
2. Save your changes, then redeploy the app using the az webapp up command again with no arguments:
az webapp up
3. Once deployment has completed, return to the browser window that opened during the Browse to the
app step, and refresh the page.
Your web app's Over view page will be displayed. Here, you can perform basic management tasks like
Browse , Stop , Restar t , and Delete .
The web app menu provides different options for configuring your app.
Clean up resources
When you're finished with the sample app, you can remove all of the resources for the app from Azure. It will
not incur extra charges and keep your Azure subscription uncluttered. Removing the resource group also
removes all resources in the resource group and is the fastest way to remove all Azure resources for your app.
Delete the resource group by using the az group delete command.
Next steps
PHP with MySQL
Configure PHP app
Quickstart: Create a Java app on Azure App Service
5/18/2022 • 8 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This quickstart shows how to
use the Azure CLI with the Azure Web App Plugin for Maven to deploy a .jar file, or .war file. Use the tabs to
switch between Java SE and Tomcat instructions.
Java SE
Tomcat
JBoss EAP
If Maven isn't your preferred development tool, check out our similar tutorials for Java developers:
Gradle
IntelliJ IDEA
Eclipse
Visual Studio Code
If you don't have an Azure subscription, create an Azure free account before you begin.
O P T IO N EXA M P L E/ L IN K
cd gs-spring-boot/complete
The deployment process to Azure App Service will use your Azure credentials from the Azure CLI automatically.
If the Azure CLI is not installed locally, then the Maven plugin will authenticate with Oauth or device login. For
more information, see authentication with Maven plugins.
Run the Maven command below to configure the deployment. This command will help you to set up the App
Service operating system, Java version, and Tomcat version.
mvn com.microsoft.azure:azure-webapp-maven-plugin:2.5.0:config
Java SE
Tomcat
JBoss EAP
1. If prompted with Subscription option, select the proper Subscription by entering the number printed
at the line start.
2. When prompted with Web App option, select the default option, <create> , by pressing enter.
3. When prompted with OS option, select Windows by entering 1 .
4. When prompted with javaVersion option, select Java 11 by entering 2 .
5. When prompted with Pricing Tier option, select P1v2 by entering 10 .
6. Finally, press enter on the last prompt to confirm your selections.
Your summary output will look similar to the snippet shown below.
Java SE
Tomcat
JBoss EAP
1. When prompted with Subscription option, select the proper Subscription by entering the number
printed at the line start.
2. When prompted with Web App option, select the default option, <create> , by pressing enter.
3. When prompted with OS option, select Linux by pressing enter.
4. When prompted with javaVersion option, select Java 11 by entering 2 .
5. When prompted with Pricing Tier option, select P1v2 by entering 9 .
6. Finally, press enter on the last prompt to confirm your selections.
Please confirm webapp properties
Subscription Id : ********-****-****-****-************
AppName : spring-boot-1599007116351
ResourceGroup : spring-boot-1599007116351-rg
Region : centralus
PricingTier : P1v2
OS : Linux
Web server stack : Java SE
Deploy to slot : false
Confirm (Y/N)? : Y
[INFO] Saving configuration to pom.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 20.925 s
[INFO] Finished at: 2020-09-01T17:38:51-07:00
[INFO] ------------------------------------------------------------------------
You can modify the configurations for App Service directly in your pom.xml . Some common configurations are
listed below:
Java SE
Tomcat
JBoss EAP
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't need the resources in the
future, delete the resource group from portal, or by running the following command in the Cloud Shell:
az group delete --name <your resource group name; for example: helloworld-1558400876966-rg> --yes
Next steps
Connect to Azure DB for PostgreSQL with Java
Set up CI/CD
Pricing Information
Aggregate Logs and Metrics
Scale up
Azure for Java Developers Resources
Configure your Java app
Quickstart: Deploy a Python (Django or Flask) web
app to Azure App Service
5/18/2022 • 19 minutes to read • Edit Online
In this quickstart, you'll deploy a Python web app (Django or Flask) to Azure App Service. Azure App Service is a
fully managed web hosting service that supports Python 3.7 and higher apps hosted in a Linux server
environment.
To complete this quickstart, you need:
1. An Azure account with an active subscription. Create an account for free.
2. Python 3.9 or higher installed locally.
1 - Sample application
This quickstart can be completed using either Flask or Django. A sample application in each framework is
provided to help you follow along with this quickstart. Download or clone the sample application to your local
workstation.
Flask
Django
cd msdocs-python-flask-webapp-quickstart
py -m venv .venv
.venv\scripts\activate
Azure portal
VS Code
Azure CLI
Sign in to the Azure portal and follow these steps to create your Azure App Service resources.
IN ST RUC T IO N S SC REEN SH OT
On the Create Web App page, fill out the form as follows.
1. Resource Group → Select Create new and use a
name of msdocs-python-webapp-quickstart.
2. Name → msdocs-python-webapp-quickstart-XYZ
where XYZ is any three random characters. This name
must be unique across Azure.
3. Runtime stack → Python 3.9 .
4. Region → Any Azure region near you.
5. App Ser vice Plan → Under Sku and size , select
Change size to select a different App Service plan.
For this example, select Dev / Test at the top of the screen
and then select the B1 (Basic) plan. The B1 Basic plan will
incur a small charge against your Azure account but is
recommended for better performance over the F1 (Free)
plan.
Since the previous step created the necessary resources and deployed your application in a single step, you can
move on to 4 - Browse to the app.
Having issues? Refer first to the Troubleshooting guide, otherwise, let us know.
5 - Stream logs
Azure App Service captures all messages output to the console to assist you in diagnosing issues with your
application. The sample apps include print() statements to demonstrate this capability.
Flask
Django
@app.route('/')
def index():
print('Request for index page received')
return render_template('index.html')
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),
'favicon.ico', mimetype='image/vnd.microsoft.icon')
@app.route('/hello', methods=['POST'])
def hello():
name = request.form.get('name')
if name:
print('Request for hello page received with name=%s' % name)
The contents of the App Service diagnostic logs can be reviewed in the Azure portal, VS Code, or using the
Azure CLI.
Azure portal
VS Code
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
Select the Log stream item from the menu under the
Monitoring section. Refresh the home page in the app or
attempt other requests to generate some log messages.
You will see any log messages generated by your app and
messages generated by the service in the output.
Having issues? Refer first to the Troubleshooting guide, otherwise, let us know.
Clean up resources
When you're finished with the sample app, you can remove all of the resources for the app from Azure. It will
not incur extra charges and keep your Azure subscription uncluttered. Removing the resource group also
removes all resources in the resource group and is the fastest way to remove all Azure resources for your app.
Azure portal
VS Code
Azure CLI
Follow these steps while signed-in to the Azure portal to delete a resource group.
IN ST RUC T IO N S SC REEN SH OT
Next steps
Tutorial: Python (Django) web app with PostgreSQL
Configure Python app
Add user sign-in to a Python web app
Tutorial: Run Python app in custom container
Create a Ruby on Rails App in App Service
5/18/2022 • 6 minutes to read • Edit Online
Azure App Service on Linux provides a highly scalable, self-patching web hosting service using the Linux
operating system. This quickstart tutorial shows how to deploy a Ruby on Rails app to App Service on Linux
using the Cloud Shell.
NOTE
The Ruby development stack only supports Ruby on Rails at this time. If you want to use a different platform, such as
Sinatra, or if you want to use an unsupported Ruby version, you need to run it in a custom container.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Install Ruby 2.6 or higher
Install Git
TIP
The branch name change isn't required by App Service. However, since many repositories are changing their
default branch to main , this tutorial also shows you how to deploy a repository from main . For more
information, see Change deployment branch.
Run the application locally
1. Install the required gems. There's a Gemfile included in the sample, so just run the following command:
bundle install
3. Using your web browser, navigate to http://localhost:3000 to test the app locally.
O P T IO N EXA M P L E/ L IN K
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE --is-linux
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"freeOfferExpirationTime": null,
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "linux",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
When the web app has been created, the Azure CLI shows output similar to the following example:
You've created an empty new web app, with git deployment enabled.
NOTE
The URL of the Git remote is shown in the property, with the format
deploymentLocalGitUrl
https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git . Save this URL as you need it later.
2. Browse to the app to see your newly created web app with built-in image. Replace <app-name> with
your web app name.
http://<app_name>.azurewebsites.net
2. Back in the local terminal window, add an Azure remote to your local Git repository. Replace
<deploymentLocalGitUrl-from-create-step> with the URL of the Git remote that you saved from Create a
web app.
3. Push to the Azure remote to deploy your app with the following command. When Git Credential Manager
prompts you for credentials, make sure you enter the credentials you created in Configure a
deployment user , not the credentials you use to sign in to the Azure portal.
This command may take a few minutes to run. While running, it displays information similar to the
following example:
remote: Using turbolinks 5.2.0
remote: Using uglifier 4.1.20
remote: Using web-console 3.7.0
remote: Bundle complete! 18 Gemfile dependencies, 78 gems now installed.
remote: Bundled gems are installed into `/tmp/bundle`
remote: Zipping up bundle contents
remote: .......
remote: ~/site/repository
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
remote: App container will begin restart within 10 seconds.
To https://<app-name>.scm.azurewebsites.net/<app-name>.git
a6e73a2..ae34be9 main -> main
http://<app-name>.azurewebsites.net
NOTE
While the app is restarting, you may observe the HTTP status code Error 503 Server unavailable in the browser, or
the Hey, Ruby developers! default page. It may take a few minutes for the app to fully restart.
Clean up deployment
After the sample script has been run, the following command can be used to remove the resource group and all
resources associated with it.
Next steps
Tutorial: Ruby on Rails with Postgres
Configure Ruby app
Create a WordPress site
5/18/2022 • 2 minutes to read • Edit Online
In this quickstart, you'll learn how to create and deploy your first WordPress site to Azure App Service using
Azure portal.
This quickstart configures WordPress in App Service on Linux. It uses the Basic tier and incurs a cost for your
Azure subscription.
IMPORTANT
WordPress in App Service on Linux is in preview. View the announcement.
After November 28, 2022, PHP will only be supported on App Service on Linux.
4. In the Basics tab, under Project details , make sure the correct subscription is selected and then choose
to Create new resource group. Type myResourceGroup for the name and select a Region you want to
serve your app from.
5. Under Instance details , type a globally unique name for your web app and choose Linux (preview) for
Operating System . Select Basic for Hosting plan . See the table below for app and database SKUs for
given hosting plans. You can view hosting plans details in the announcement. For pricing, visit App
Service pricing and Azure Database for MySQL pricing.
6. Under WordPress Settings , type an Admin Email , Admin Username , and Admin Password . The
Admin Email here is used for WordPress administrative sign-in only.
7. Select the Review + create tab. After validation runs, select the Create button at the bottom of the page
to create the WordPress site.
NOTE
App Service creates environment variables and application settings needed for WordPress/PHP configuration. See
Environment variables and app settings in Azure App Service for more information.
8. Browse to your site URL and verify the app is running properly. The site may take a few minutes to load. If
you receive an error, allow a few more minutes then refresh the browser.
9. To access the WordPress Admin page, browse to /wp-admin and use the credentials you created in the
WordPress settings step.
Clean up resources
When no longer needed, you can delete the resource group, App service, and all related resources.
1. From your App Service overview page, click the resource group you created in the Create WordPress site
using Azure portal step.
2. From the resource group page, select Delete resource group . Confirm the name of the resource group
to finish deleting the resources.
Next steps
Congratulations, you've successfully completed this quickstart!
Tutorial: PHP app with MySQL
Configure PHP app
Create a static HTML web app in Azure
5/18/2022 • 3 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This quickstart shows how to
deploy a basic HTML+CSS site to Azure App Service. You'll complete this quickstart in Cloud Shell, but you can
also run these commands locally with Azure CLI.
NOTE
For information regarding hosting static HTML files in a serverless environment, please see Static Web Apps.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Download the sample
In the Cloud Shell, create a quickstart directory and then change to it.
mkdir quickstart
cd $HOME/quickstart
Next, run the following command to clone the sample app repository to your quickstart directory.
cd html-docs-hello-world
{
"app_url": "https://<app_name>.azurewebsites.net",
"location": "westeurope",
"name": "<app_name>",
"os": "Windows",
"resourcegroup": "appsvc_rg_Windows_westeurope",
"serverfarm": "appsvc_asp_Windows_westeurope",
"sku": "FREE",
"src_path": "/home/<username>/quickstart/html-docs-hello-world ",
< JSON data removed for brevity. >
}
Make a note of the resourceGroup value. You need it for the clean up resources section.
Save your changes and exit nano. Use the command ^O to save and ^X to exit.
You'll now redeploy the app with the same az webapp up command.
Once deployment has completed, switch back to the browser window that opened in the Browse to the app
step, and refresh the page.
Manage your new Azure app
To manage the web app you created, in the Azure portal, search for and select App Ser vices .
On the App Ser vices page, select the name of your Azure app.
You see your web app's Overview page. Here, you can perform basic management tasks like browse, stop, start,
restart, and delete.
The left menu provides different pages for configuring your app.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell.
Remember that the resource group name was automatically generated for you in the create a web app step.
az group delete --name appsvc_rg_Windows_westeurope
Next steps
Map custom domain
Quickstart: Create App Service app using an ARM
template
5/18/2022 • 5 minutes to read • Edit Online
Get started with Azure App Service by deploying an app to the cloud using an Azure Resource Manager
template (ARM template) and Azure CLI in Cloud Shell. Because you use a free App Service tier, you incur no
costs to complete this quickstart.
An ARM template is a JavaScript Object Notation (JSON) file that defines the infrastructure and configuration for
your project. The template uses declarative syntax. In declarative syntax, you describe your intended deployment
without writing the sequence of programming commands to create the deployment.
If your environment meets the prerequisites and you're familiar with using ARM templates, select the Deploy to
Azure button. The template will open in the Azure portal.
Use the following button to deploy on Linux :
Prerequisites
If you don't have an Azure subscription, create an Azure free account before you begin.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"webAppName": {
"type": "string",
"defaultValue": "[concat('webApp-', uniqueString(resourceGroup().id))]",
"minLength": 2,
"metadata": {
"description": "Web app name."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"sku": {
"type": "string",
"defaultValue": "F1",
"defaultValue": "F1",
"metadata": {
"description": "The SKU of App Service Plan."
}
},
"language": {
"type": "string",
"defaultValue": ".net",
"allowedValues": [
".net",
"php",
"node",
"html"
],
"metadata": {
"description": "The language stack of the app."
}
},
"helloWorld": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "true = deploy a sample Hello World app."
}
},
"repoUrl": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Optional Git Repo URL"
}
}
},
"variables": {
"appServicePlanPortalName": "[concat('AppServicePlan-', parameters('webAppName'))]",
"gitRepoReference": {
".net": "https://github.com/Azure-Samples/app-service-web-dotnet-get-started",
"node": "https://github.com/Azure-Samples/nodejs-docs-hello-world",
"php": "https://github.com/Azure-Samples/php-docs-hello-world",
"html": "https://github.com/Azure-Samples/html-docs-hello-world"
},
"gitRepoUrl": "[if(bool(parameters('helloWorld')), variables('gitRepoReference')
[toLower(parameters('language'))], parameters('repoUrl'))]",
"configReference": {
".net": {
"comments": ".Net app. No additional configuration needed."
},
"html": {
"comments": "HTML app. No additional configuration needed."
},
"php": {
"phpVersion": "7.4"
},
"node": {
"appSettings": [
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "12.15.0"
}
]
}
}
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2020-06-01",
"name": "[variables('appServicePlanPortalName')]",
"location": "[parameters('location')]",
"sku": {
"sku": {
"name": "[parameters('sku')]"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2020-06-01",
"name": "[parameters('webAppName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]"
],
"properties": {
"siteConfig": "[variables('configReference')[parameters('language')]]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]"
},
"resources": [
{
"condition": "[contains(variables('gitRepoUrl'),'http')]",
"type": "sourcecontrols",
"apiVersion": "2020-06-01",
"name": "web",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('webAppName'))]"
],
"properties": {
"repoUrl": "[variables('gitRepoUrl')]",
"branch": "master",
"isManualIntegration": true
}
}
]
}
]
}
The template used in this quickstart is from Azure Quickstart Templates. It deploys an App Service plan and an
App Service app on Linux. It's compatible with all supported programming languages on App Service.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.5.6.12127",
"templateHash": "10602523904429381366"
}
},
"parameters": {
"webAppName": {
"type": "string",
"defaultValue": "[format('webApp-{0}', uniqueString(resourceGroup().id))]",
"minLength": 2,
"metadata": {
"description": "Web app name."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"sku": {
"type": "string",
"defaultValue": "F1",
"metadata": {
"description": "The SKU of App Service Plan."
}
},
"linuxFxVersion": {
"type": "string",
"defaultValue": "DOTNETCORE|3.0",
"metadata": {
"description": "The Runtime stack of current web app"
}
},
"repoUrl": {
"type": "string",
"defaultValue": " ",
"metadata": {
"description": "Optional Git Repo URL"
}
}
},
"variables": {
"appServicePlanPortalName": "[format('AppServicePlan-{0}', parameters('webAppName'))]"
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('appServicePlanPortalName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('sku')]"
},
"kind": "linux",
"properties": {
"reserved": true
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('webAppName')]",
"location": "[parameters('location')]",
"properties": {
"httpsOnly": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
"siteConfig": {
"linuxFxVersion": "[parameters('linuxFxVersion')]",
"minTlsVersion": "1.2",
"ftpsState": "FtpsOnly"
}
},
"identity": {
"type": "SystemAssigned"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]"
]
},
{
"condition": "[contains(parameters('repoUrl'), 'http')]",
"type": "Microsoft.Web/sites/sourcecontrols",
"apiVersion": "2021-02-01",
"name": "[format('{0}/{1}', parameters('webAppName'), 'web')]",
"properties": {
"repoUrl": "[parameters('repoUrl')]",
"branch": "master",
"isManualIntegration": true
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('webAppName'))]"
]
}
]
}
To deploy a different language stack, update linuxFxVersion with appropriate values. Samples are shown below.
To show current versions, run the following command in the Cloud Shell:
az webapp config show --resource-group myResourceGroup --name <app-name> --query linuxFxVersion
L A N GUA GE EXA M P L E
.NET linuxFxVersion="DOTNETCORE|3.0"
PHP linuxFxVersion="PHP|7.4"
Node.js linuxFxVersion="NODE|10.15"
Python linuxFxVersion="PYTHON|3.7"
Ruby linuxFxVersion="RUBY|2.6"
NOTE
You can find more Azure App Service template samples here.
Clean up resources
When no longer needed, delete the resource group.
Next steps
Deploy from local Git
ASP.NET Core with SQL Database
Python with Postgres
PHP with MySQL
Connect to Azure SQL database with Java
Map custom domain
Run a custom container in Azure
5/18/2022 • 9 minutes to read • Edit Online
Azure App Service provides pre-defined application stacks on Windows like ASP.NET or Node.js, running on IIS.
However, the pre-configured application stacks lock down the operating system and prevent low-level access.
Custom Windows containers don't have these restrictions, and let developers fully customize the containers and
give containerized applications full access to Windows functionality.
This quickstart shows how to deploy an ASP.NET app, in a Windows image, to Azure Container Registry from
Visual Studio. You run the app in a custom container in Azure App Service.
Prerequisites
To complete this tutorial:
Install Docker for Windows.
Switch Docker to run Windows containers.
Install Visual Studio 2022 with the ASP.NET and web development and Azure development workloads.
In Visual Studio 2022 Community, ensure .NET Framework project and item templates component is
selected with ASP.NET and web development workload . If you've installed Visual Studio 2022 already:
Install the latest updates in Visual Studio by selecting Help > Check for Updates .
Add the workloads in Visual Studio by selecting Tools > Get Tools and Features .
3. In Configure your new project , under Project name , name the application myfirstazurewebapp.
Under Framework , select .NET Framework 4.8 and then select Create .
4. You can deploy any type of ASP.NET web app to Azure. For this quickstart, choose the MVC template.
5. Under Authentication , select None . Under Advanced , select Docker suppor t and uncheck
Configure for HTTPS . Select Create .
6. If the Dockerfile file isn't opened automatically, open it from the Solution Explorer .
7. You need a supported parent image. Change the parent image by replacing the FROM line with the
following code and save the file:
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
8. From the Visual Studio menu, select Debug > Star t Without Debugging to run the web app locally.
3. In Specific Target , select Azure Container Registr y , and then select Next .
4. In Publish , make sure the correct subscription is chosen. In Container registries select the + button to
create a new Azure Container Registry.
5. In Create new , make sure the correct subscription is chosen. Under Resource group , select New and
type myResourceGroup for the name, and select OK . Under SKU , select Basic . Under Registr y location ,
select a location of the registry then select Create .
6. In Publish , under Container Registr y , select the registry you created, and then select Finish .
Wait for the deployment to complete. The Publish page now shows the repository name. Select the copy
button to copy the Repositor y name for later.
1. Click Go to resource .
2. In the overview of this resource, follow the link next to URL .
A new browser page opens to the following page:
Wait a few minutes and try again, until you get the default ASP.NET home page:
Congratulations! You're running your first custom Windows container in Azure App Service.
https://<app_name>.scm.azurewebsites.net/api/logstream
<div class="jumbotron">
<h1>ASP.NET in Azure!</h1>
<p class="lead">This is a simple app that we've built that demonstrates how to deploy a .NET app
to Azure App Service.</p>
</div>
3. To redeploy to Azure, right-click the myfirstazurewebapp project in Solution Explorer and choose
Publish .
4. On the publish page, select Publish and wait for publishing to complete.
5. To tell App Service to pull in the new image from Docker Hub, restart the app. Back in the app page in the
portal, click Restar t > Yes .
Browse to the custom container again. As you refresh the webpage, the app should revert to the "Starting up"
page at first, then display the updated webpage again after a few minutes.
Next steps
Migrate to Windows container in Azure
Or, check out other resources:
Configure custom container
App Service on Linux provides pre-defined application stacks on Linux with support for languages such as .NET,
PHP, Node.js and others. You can also use a custom Docker image to run your web app on an application stack
that isn't already defined in Azure. This quickstart shows you how to deploy an image from an Azure Container
Registry (ACR) to App Service.
Prerequisites
An Azure account
Docker
Visual Studio Code
The Azure App Service extension for VS Code. You can use this extension to create, manage, and deploy Linux
Web Apps on the Azure Platform as a Service (PaaS).
The Docker extension for VS Code. You can use this extension to simplify the management of local Docker
images and commands and to deploy built app images to Azure.
IMPORTANT
Be sure to set the Admin User option to Enable when you create the Azure container registry. You can also set it from
the Access keys section of your registry page in the Azure portal. This setting is required for App Service access. For
managed identity, see Deploy from ACR tutorial.
Sign in
1. Launch Visual Studio Code.
2. Select the Azure logo in the Activity Bar, navigate to the APP SERVICE explorer, then select Sign in to
Azure and follow the instructions.
3. In the Status Bar at the bottom, verify your Azure account email address. In the APP SERVICE explorer,
your subscription should be displayed.
4. In the Activity Bar, select the Docker logo. In the REGISTRIES explorer, verify that the container registry
you created appears.
Check prerequisites
Verify that you have Docker installed and running. The following command will display the Docker version if it's
running.
docker --version
.NET
Node.js
Python
Java
FROM mcr.microsoft.com/appsvc/dotnetcore:lts
In this Dockerfile, the parent image is one of the built-in .NET containers of App Service. You can find the source
files for it in the Azure-App-Service/ImageBuilder GitHub repository, under GenerateDockerFiles/dotnetcore. Its
Dockerfile copies a simple .NET app into /defaulthome/hostingstart . Your Dockerfile simply starts that app.
2. Open the Command Palette, and type Docker Images: Build Image . Type Enter to run the command.
3. In the image tag box, specify the tag you want in the following format:
<acr-name>.azurecr.io/<image-name>/<tag> , where <acr-name> is the name of the container registry you
created. Press Enter .
4. When the image finishes building, click Refresh at the top of the IMAGES explorer and verify that the
image is built successfully.
Next steps
Congratulations, you've successfully completed this quickstart.
The App Service app pulls from the container registry every time it starts. If you rebuild your image, you just
need to push it to your container registry, and the app pulls in the updated image when it restarts. To tell your
app to pull in the updated image immediately, restart it.
Configure custom container
Custom container tutorial
Multi-container app tutorial
Other Azure extensions:
Cosmos DB
Azure Functions
Azure CLI Tools
Azure Resource Manager Tools
Azure Tools extension pack includes all the extensions above.
Create a multi-container (preview) app using a
Docker Compose configuration
5/18/2022 • 3 minutes to read • Edit Online
NOTE
Multi-container is in preview.
Web App for Containers provides a flexible way to use Docker images. This quickstart shows how to deploy a
multi-container app (preview) to Web App for Containers in the Cloud Shell using a Docker Compose
configuration.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
This article requires version 2.0.32 or later of the Azure CLI. If using Azure Cloud Shell, the latest version is
already installed.
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
In the Cloud Shell, create a quickstart directory and then change to it.
mkdir quickstart
cd $HOME/quickstart
Next, run the following command to clone the sample app repository to your quickstart directory. Then change
to the multicontainerwordpress directory.
cd multicontainerwordpress
Create a resource group
A resource group is a logical container into which Azure resources, such as web apps, databases, and storage
accounts, are deployed and managed. For example, you can choose to delete the entire resource group in one
simple step later.
In the Cloud Shell, create a resource group with the az group create command. The following example creates
a resource group named myResourceGroup in the South Central US location. To see all supported locations for
App Service on Linux in Standard tier, run the az appservice list-locations --sku S1 --linux-workers-enabled
command.
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"adminSiteName": null,
"appServicePlanName": "myAppServicePlan",
"geoRegion": "South Central US",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "linux",
"location": "South Central US",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
In your Cloud Shell terminal, create a multi-container web app in the myAppServicePlan App Service plan with
the az webapp create command. Don't forget to replace <app_name> with a unique app name (valid characters
are a-z , 0-9 , and - ).
When the web app has been created, the Azure CLI shows output similar to the following example:
{
"additionalProperties": {},
"availabilityState": "Normal",
"clientAffinityEnabled": true,
"clientCertEnabled": false,
"cloningInfo": null,
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"defaultHostName": "<app_name>.azurewebsites.net",
"enabled": true,
< JSON data removed for brevity. >
}
Clean up deployment
After the sample script has been run, the following command can be used to remove the resource group and all
resources associated with it.
az group delete --name myResourceGroup
Next steps
Tutorial: Multi-container WordPress app
Configure a custom container
Create an App Service app on Azure Arc (Preview)
5/18/2022 • 2 minutes to read • Edit Online
In this quickstart, you create an App Service app to an Azure Arc-enabled Kubernetes cluster (Preview). This
scenario supports Linux apps only, and you can use a built-in language stack or a custom container.
Prerequisites
Set up your Azure Arc-enabled Kubernetes to run App Service.
Because these CLI commands are not yet part of the core CLI set, add them with the following commands:
customLocationGroup="<resource-group-containing-custom-location>"
customLocationName="<name-of-custom-location>"
3. Create an app
The following example creates a Node.js app. Replace <app-name> with a name that's unique within your cluster
(valid characters are a-z , 0-9 , and - ). To see all supported runtimes, run az webapp list-runtimes --os linux
.
az webapp create \
--resource-group myResourceGroup \
--name <app-name> \
--custom-location $customLocationId \
--runtime 'NODE|12-lts'
Get a sample Node.js app using Git and deploy it using ZIP deploy. Replace <app-name> with your web app
name.
Navigate to the Log Analytics workspace that's configured with your App Service extension, then click Logs in
the left navigation. Run the following sample query to show logs over the past 72 hours. Replace <app-name>
with your web app name. If there's an error when running a query, try again in 10-15 minutes (there may be a
delay for Log Analytics to start receiving logs from your application).
The application logs for all the apps hosted in your Kubernetes cluster are logged to the Log Analytics
workspace in the custom log table named AppServiceConsoleLogs_CL .
Log_s contains application logs for a given App Service and AppName_s contains the App Service app name.
In addition to logs you write via your application code, the Log_s column also contains logs on container startup,
shutdown, and Function Apps.
You can learn more about log queries in getting started with Kusto.
az webapp create \
--resource-group myResourceGroup \
--name <app-name> \
--custom-location $customLocationId \
--deployment-container-image-name mcr.microsoft.com/appsvc/node:12-lts
To update the image after the app is create, see Change the Docker image of a custom container
Next steps
Configure an ASP.NET Core app
Configure a Node.js app
Configure a PHP app
Configure a Linux Python app
Configure a Java app
Configure a Linux Ruby app
Configure a custom container
Tutorial: Map an existing custom DNS name to
Azure App Service
5/18/2022 • 8 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This tutorial shows you how to
map an existing custom Domain Name System (DNS) name to App Service. To migrate a live site and its DNS
domain name to App Service with no downtime, see Migrate an active DNS name to Azure.
In this tutorial, you learn how to:
Map a subdomain by using a CNAME record.
Map a root domain by using an A record.
Map a wildcard domain by using a CNAME record.
Redirect the default URL to a custom directory.
2. On the App Ser vices page, select the name of your Azure app.
You see the management page of the App Service app.
To add a custom domain to your app, you need to verify your ownership of the domain by adding a
verification ID as a TXT record with your domain provider.
3. In the left pane of your app page, select Custom domains .
4. Copy the ID in the Custom Domain Verification ID box in the Custom Domains page for the next
step.
WARNING
Adding domain verification IDs to your custom domain can prevent dangling DNS entries and help to avoid
subdomain takeovers. For custom domains you previously configured without this verification ID, you should
protect them from the same risk by adding the verification ID to your DNS record. For more information on this
common high-severity threat, see Subdomain takeover.
3. (A record only) To map an A record, you need the app's external IP address. In the Custom domains
page, copy the value of IP address .
3. Create the DNS records
1. Sign in to the website of your domain provider.
You can use Azure DNS to manage DNS records for your domain and configure a custom DNS name for
Azure App Service. For more information, see Tutorial: Host your domain in Azure DNS.
2. Find the page for managing DNS records.
Every domain provider has its own DNS records interface, so consult the provider's documentation. Look
for areas of the site labeled Domain Name , DNS , or Name Ser ver Management .
Often, you can find the DNS records page by viewing your account information and then looking for a
link such as My domains . Go to that page, and then look for a link that's named something like Zone
file , DNS Records , or Advanced configuration .
The following screenshot is an example of a DNS records page:
A
CNAME
Wildcard (CNAME)
For a root domain like contoso.com , create two records according to the following table:
REC O RD T Y P E H O ST VA L UE C O M M EN T S
To map a subdomain like www.contoso.com with an A record instead of a recommended CNAME record,
your A record and TXT record should look like the following table instead:
REC O RD T Y P E H O ST VA L UE C O M M EN T S
1. In the left pane of the app page in the Azure portal, select Custom domains .
It might take some time for the new custom domain to be reflected in the app's Custom Domains page.
Refresh the browser to update the data.
NOTE
A warning label for your custom domain means that it's not yet bound to a TLS/SSL certificate. Any HTTPS request
from a browser to your custom domain will receive an error or warning, depending on the browser. To add a TLS
binding, see Secure a custom DNS name with a TLS/SSL binding in Azure App Service.
If you missed a step or made a typo somewhere earlier, a verification error appears at the bottom of the
page.
5. Test in a browser
Browse to the DNS names that you configured earlier.
If you receive an HTTP 404 (Not Found) error when you browse to the URL of your custom domain, the two
most common causes are:
The custom domain configured is missing an A record or a CNAME record. You may have deleted the DNS
record after you've enabled the mapping in your app. Check if the DNS records are properly configured
using an online DNS lookup tool.
The browser client has cached the old IP address of your domain. Clear the cache, and test DNS resolution
again. On a Windows machine, you clear the cache with ipconfig /flushdns .
Azure CLI
PowerShell
The following command adds a configured custom DNS name to an App Service app.
Next steps
Secure a custom DNS name with a TLS/SSL binding in Azure App Service
Secure a custom DNS name with a TLS/SSL binding
in Azure App Service
5/18/2022 • 7 minutes to read • Edit Online
This article shows you how to secure the custom domain in your App Service app or function app by creating a
certificate binding. When you're finished, you can access your App Service app at the https:// endpoint for
your custom DNS name (for example, https://www.contoso.com ).
Prerequisites
To follow this how-to guide:
Create an App Service app
Map a domain name to your app or buy and configure it in Azure
Add a private certificate to your app
NOTE
The easiest way to add a private certificate is to create a free App Service managed certificate.
On the App Ser vices page, select the name of your web app.
Check to make sure that your web app is not in the F1 or D1 tier. Your web app's current tier is highlighted by a
dark blue box.
Custom SSL is not supported in the F1 or D1 tier. If you need to scale up, follow the steps in the next section.
Otherwise, close the Scale up page and skip the Scale up your App Service plan section.
Scale up your App Service plan
Select any of the non-free tiers (B1 , B2 , B3 , or any tier in the Production category). For additional options, click
See additional options .
Click Apply .
When you see the following notification, the scale operation is complete.
In Custom Domain , select the custom domain you want to add a binding for.
If your app already has a certificate for the selected custom domain, go to Create binding directly. Otherwise,
keep going.
Add a certificate for custom domain
If your app has no certificate for the selected custom domain, then you have two options:
Upload PFX Cer tificate - Follow the workflow at Upload a private certificate, then select this option here.
Impor t App Ser vice Cer tificate - Follow the workflow at Import an App Service certificate, then select
this option here.
NOTE
You can also Create a free certificate or Import a Key Vault certificate, but you must do it separately and then return to
the TLS/SSL Binding dialog.
Create binding
Use the following table to help you configure the TLS binding in the TLS/SSL Binding dialog, then click Add
Binding .
Custom domain The domain name to add the TLS/SSL binding for.
TLS/SSL Type SNI SSL - Multiple SNI SSL bindings may be added.
This option allows multiple TLS/SSL certificates to
secure multiple domains on the same IP address.
Most modern browsers (including Internet Explorer,
Chrome, Firefox, and Opera) support SNI (for more
information, see Server Name Indication).
IP SSL - Only one IP SSL binding may be added. This
option allows only one TLS/SSL certificate to secure a
dedicated public IP address. After you configure the
binding, follow the steps in Remap records for IP SSL.
IP SSL is supported only in Standard tier or above.
Once the operation is complete, the custom domain's TLS/SSL state is changed to Secure .
NOTE
A Secure state in the Custom domains means that it is secured with a certificate, but App Service doesn't check if the
certificate is self-signed or expired, for example, which can also cause browsers to show an error or warning.
Test HTTPS
In various browsers, browse to https://<your.custom.domain> to verify that it serves up your app.
Your application code can inspect the protocol via the "x-appservice-proto" header. The header will have a value
of http or https .
NOTE
If your app gives you certificate validation errors, you're probably using a self-signed certificate.
If that's not the case, you may have left out intermediate certificates when you export your certificate to the PFX file.
Prevent IP changes
Your inbound IP address can change when you delete a binding, even if that binding is IP SSL. This is especially
important when you renew a certificate that's already in an IP SSL binding. To avoid a change in your app's IP
address, follow these steps in order:
1. Upload the new certificate.
2. Bind the new certificate to the custom domain you want without deleting the old one. This action replaces the
binding instead of removing the old one.
3. Delete the old certificate.
Enforce HTTPS
By default, anyone can still access your app using HTTP. You can redirect all HTTP requests to the HTTPS port.
In your app page, in the left navigation, select TLS/SSL settings . Then, in HTTPS Only , select On .
When the operation is complete, navigate to any of the HTTP URLs that point to your app. For example:
http://<app_name>.azurewebsites.net
http://contoso.com
http://www.contoso.com
# Before continuing, go to your DNS configuration UI for your custom domain and follow the
# instructions at https://aka.ms/appservicecustomdns to configure a CNAME record for the
# hostname "www" and point it your web app's default domain name.
# Upgrade App Service plan to Basic tier (minimum required by custom SSL certificates)
Set-AzAppServicePlan -Name $webappname -ResourceGroupName $webappname `
-Tier Basic
More resources
Use a TLS/SSL certificate in your code in Azure App Service
FAQ : App Service Certificates
Tutorial: Deploy an ASP.NET Core and Azure SQL
Database app to Azure App Service
5/18/2022 • 17 minutes to read • Edit Online
In this tutorial, you'll learn how to deploy an ASP.NET Core app to Azure App Service and connect to an Azure
SQL Database. Azure App Service is a highly scalable, self-patching, web-hosting service that can easily deploy
apps on Windows or Linux. Although this tutorial uses an ASP.NET Core 6.0 app, the process is the same for
other versions of ASP.NET Core and ASP.NET Framework.
This article assumes you're familiar with .NET and have it installed locally. You'll also need an Azure account with
an active subscription. If you don't have an Azure account, you can create one for free.
Sign in to the Azure portal and follow these steps to create your Azure App Service resources:
IN ST RUC T IO N S SC REEN SH OT
On the Create Web App page, fill out the form as follows.
1. Resource Group → Select Create new and enter a
name of msdocs-core-sql.
2. Name → Enter a unique name of your choice, such
as coreSqlXYZ, where XYZ are letters or numbers of
your choosing. This App Service name must be
unique across Azure.
3. Publish → Code
4. Runtime stack → .NET 6.0
5. Operating System → Windows
6. Region → Any Azure region near you.
7. App Ser vice Plan → Select Create New and give
your App Service plan a name of
MyAppSer vicePlan .
8. Select Change size under Sku and size settings to
select the App Service plan specifications.
Sign in to the Azure portal and follow these steps to create your Azure App Service resources:
IN ST RUC T IO N S SC REEN SH OT
IN ST RUC T IO N S SC REEN SH OT
Azure portal
Azure CLI
Sign in to the Azure portal and follow the steps to create your Azure App Service resources:
IN ST RUC T IO N S SC REEN SH OT
Next, in the search bar at the top of the Azure portal, search
for the coreSqlXYZ App Service you created previously and
select it to navigate to the overview page.
IN ST RUC T IO N S SC REEN SH OT
Next, update the appsettings.json file in our local app code with the Connection String of our Azure SQL
Database. The update allows us to run migrations locally against our database hosted in Azure. Replace the
username and password placeholders with the values you chose when creating your database.
"ConnectionStrings": {
"MyDbConnection": "Server=tcp:<your-server-name>.database.windows.net,1433;
Initial Catalog=coredb;
Persist Security Info=False;
User ID=<username>;Password=<password>;
Encrypt=True;
TrustServerCertificate=False;"
}
Finally, run the following commands to install the necessary CLI tools for Entity Framework Core. Create an
initial database migration file and apply those changes to update the database:
Azure portal
Visual Studio Code
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
IN ST RUC T IO N S SC REEN SH OT
Select the Log stream item from the menu under the
Monitoring section. Refresh the home page in the app or
attempt other requests to generate some log messages.
You will see any log messages generated by your app and
messages generated by the service in the output.
Clean up resources
When you're finished, you can delete all of the resources from Azure by deleting the resource group for the
application. It deletes all of the resources contained inside the group.
Azure portal
Visual Studio Code
Azure CLI
Follow these steps while signed-in to the Azure portal to delete a resource group:
IN ST RUC T IO N S SC REEN SH OT
Next steps
Advance to the next tutorial to learn how to map a custom DNS name to your app.
Tutorial: Map custom DNS name to your app
Or, check out other resources:
Tutorial: Connect to SQL Database from App Service without secrets using a managed identity
Configure ASP.NET Core app
Tutorial: Deploy an ASP.NET app to Azure with
Azure SQL Database
5/18/2022 • 11 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This tutorial shows you how to
deploy a data-driven ASP.NET app in App Service and connect it to Azure SQL Database. When you're finished,
you have an ASP.NET app running in Azure and connected to SQL Database.
Prerequisites
To complete this tutorial:
Install Visual Studio 2022 with the ASP.NET and web development and Azure development workloads.
If you've installed Visual Studio already, add the workloads in Visual Studio by clicking Tools > Get Tools and
Features .
NOTE
Don't select Create yet.
Create a resource group
A resource group is a logical container into which Azure resources, such as web apps, databases, and storage
accounts, are deployed and managed. For example, you can choose to delete the entire resource group in one
simple step later.
1. Next to Resource Group , click New .
SET T IN G SUGGEST ED VA L UE F O R M O RE IN F O RM AT IO N
NOTE
Be sure to configure the SQL Database from the Publish page instead of the Connected Ser vices page.
6. Click OK .
7. In the Azure SQL Database dialog, keep the default generated Database Name . Select Create and
wait for the database resources to be created.
Configure database connection
1. When the wizard finishes creating the database resources, click Next .
2. In the Database connection string Name , type MyDbConnection. This name must match the
connection string that is referenced in Models/MyDatabaseContext.cs.
3. In Database connection user name and Database connection password , type the administrator
username and password you used in Create a server.
4. Make sure Azure App Settings is selected and click Finish .
NOTE
If you see Local user secrets files instead, you must have configured SQL Database from the Connected
Ser vices page instead of the Publish page.
Once Visual Studio finishes creating the firewall setting for your SQL Database instance, your connection
shows up in SQL Ser ver Object Explorer .
Here, you can perform the most common database operations, such as run queries, create views and
stored procedures, and more.
2. Expand your connection > Databases > <your database> > Tables . Right-click on the Todoes table
and select View Data .
Enable-Migrations
3. Add a migration:
Add-Migration AddProperty
Update-Database
5. Type Ctrl+F5 to run the app. Test the edit, details, and create links.
If the application loads without errors, then Code First Migrations has succeeded. However, your page still looks
the same because your application logic is not using this new property yet.
Use the new property
Make some changes in your code to use the Done property. For simplicity in this tutorial, you're only going to
change the Index and Create views to see the property in action.
1. Open Controllers\TodosController.cs.
2. Find the Create() method on line 52 and add Done to the list of properties in the Bind attribute. When
you're done, your Create() method signature looks like the following code:
3. Open Views\Todos\Create.cshtml.
4. In the Razor code, you should see a <div class="form-group"> element that uses model.Description , and
then another <div class="form-group"> element that uses model.CreatedDate . Immediately following
these two elements, add another <div class="form-group"> element that uses model.Done :
<div class="form-group">
@Html.LabelFor(model => model.Done, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.Done)
@Html.ValidationMessageFor(model => model.Done, "", new { @class = "text-danger" })
</div>
</div>
</div>
5. Open Views\Todos\Index.cshtml.
6. Search for the empty <th></th> element. Just above this element, add the following Razor code:
<th>
@Html.DisplayNameFor(model => model.Done)
</th>
7. Find the <td> element that contains the Html.ActionLink() helper methods. Above this <td> , add
another <td> element with the following Razor code:
<td>
@Html.DisplayFor(modelItem => item.Done)
</td>
That's all you need to see the changes in the Index and Create views.
8. Type Ctrl+F5 to run the app.
You can now add a to-do item and check Done . Then it should show up in your homepage as a completed item.
Remember that the Edit view doesn't show the Done field, because you didn't change the Edit view.
Enable Code First Migrations in Azure
Now that your code change works, including database migration, you publish it to your Azure app and update
your SQL Database with Code First Migrations too.
1. Just like before, right-click your project and select Publish .
2. Click More actions > Edit to open the publish settings.
3. In the MyDatabaseContext dropdown, select the database connection for your Azure SQL Database.
4. Select Execute Code First Migrations (runs on application star t) , then click Save .
All your existing to-do items are still displayed. When you republish your ASP.NET application, existing data in
your SQL Database is not lost. Also, Code First Migrations only changes the data schema and leaves your
existing data intact.
However, you don't see any of the trace messages yet. That's because when you first select View
Streaming Logs , your Azure app sets the trace level to Error , which only logs error events (with the
Trace.TraceError() method).
TIP
You can experiment with different trace levels to see what types of messages are displayed for each level. For
example, the Information level includes all logs created by Trace.TraceInformation() ,
Trace.TraceWarning() , and Trace.TraceError() , but not logs created by Trace.WriteLine() .
5. In your browser navigate to your app again at http://<your app name>.azurewebsites.net, then try
clicking around the to-do list application in Azure. The trace messages are now streamed to the Output
window in Visual Studio.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, you can delete them by deleting the resource group.
1. From your web app's Over view page in the Azure portal, select the myResourceGroup link under
Resource group .
2. On the resource group page, make sure that the listed resources are the ones you want to delete.
3. Select Delete , type myResourceGroup in the text box, and then select Delete .
Next steps
In this tutorial, you learned how to:
Create a database in Azure SQL Database
Connect an ASP.NET app to SQL Database
Deploy the app to Azure
Update the data model and redeploy the app
Stream logs from Azure to your terminal
Advance to the next tutorial to learn how to easily improve the security of your connection Azure SQL Database.
Tutorial: Connect to SQL Database from App Service without secrets using a managed identity
More resources:
Configure ASP.NET app
Want to optimize and save on your cloud spending?
Start analyzing costs with Cost Management
Tutorial: Build a PHP and MySQL app in Azure App
Service
5/18/2022 • 21 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service using the Windows operating
system. This tutorial shows how to create a PHP app in Azure and connect it to a MySQL database. When you're
finished, you'll have a Laravel app running on Azure App Service on Windows.
Azure App Service provides a highly scalable, self-patching web hosting service using the Linux operating
system. This tutorial shows how to create a PHP app in Azure and connect it to a MySQL database. When you're
finished, you'll have a Laravel app running on Azure App Service on Linux.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
mysql -u root -p
If you're prompted for a password, enter the password for the root account. If you don't remember your root
account password, see MySQL: How to Reset the Root Password.
If your command runs successfully, then your MySQL server is running. If not, ensure that your local MySQL
server is started by following the MySQL post-installation steps.
Create a database locally
1. At the mysql prompt, create a database.
quit
Create a PHP app locally
In this step, you get a Laravel sample application, configure its database connection, and run it locally.
Clone the sample
In the terminal window, cd to a working directory.
1. Clone the sample repository and change to the repository root.
TIP
The branch name change isn't required by App Service. But, since many repositories are changing their default
branch to main , this tutorial also shows you how to deploy a repository from main . For more information, see
Change deployment branch.
composer install
APP_ENV=local
APP_DEBUG=true
APP_KEY=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=sampledb
DB_USERNAME=root
DB_PASSWORD=<root_password>
For information on how Laravel uses the .env file, see Laravel Environment Configuration.
Run the sample locally
1. Run Laravel database migrations to create the tables the application needs. To see which tables are
created in the migrations, look in the database/migrations directory in the Git repository.
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
Create a MySQL server
In the Cloud Shell, create a server in Azure Database for MySQL with the az mysql server create command.
In the following command, substitute a unique server name for the <mysql-server-name> placeholder, a user
name for the <admin-user>, and a password for the <admin-password> placeholder. The server name is used
as part of your MySQL endpoint ( https://<mysql-server-name>.mysql.database.azure.com ), so the name needs to
be unique across all servers in Azure. For details on selecting MySQL DB SKU, see Create an Azure Database for
MySQL server.
az mysql server create --resource-group myResourceGroup --name <mysql-server-name> --location "West Europe"
--admin-user <admin-user> --admin-password <admin-password> --sku-name B_Gen5_1
When the MySQL server is created, the Azure CLI shows information similar to the following example:
{
"administratorLogin": "<admin-user>",
"administratorLoginPassword": null,
"fullyQualifiedDomainName": "<mysql-server-name>.mysql.database.azure.com",
"id": "/subscriptions/00000000-0000-0000-0000-
000000000000/resourceGroups/myResourceGroup/providers/Microsoft.DBforMySQL/servers/<mysql-
server-name>",
"location": "westeurope",
"name": "<mysql-server-name>",
"resourceGroup": "myResourceGroup",
...
- < Output has been truncated for readability >
}
TIP
You can be even more restrictive in your firewall rule by using only the outbound IP addresses your app uses.
2. In the Cloud Shell, run the command again to allow access from your local computer by replacing <your-
ip-address> with your local IPv4 IP address.
3. Create a database user called phpappuser and give it all privileges in the sampledb database. For
simplicity of the tutorial, use MySQLAzure2017 as the password.
quit
APP_ENV=production
APP_DEBUG=true
APP_KEY=
DB_CONNECTION=mysql
DB_HOST=<mysql-server-name>.mysql.database.azure.com
DB_DATABASE=sampledb
DB_USERNAME=phpappuser@<mysql-server-name>
DB_PASSWORD=MySQLAzure2017
MYSQL_SSL=true
TIP
To secure your MySQL connection information, this file is already excluded from the Git repository (See .gitignore in the
repository root). Later, you learn how to set up the environment variables in App Service to connect to your database in
Azure Database for MySQL. With environment variables, you don't need the .env file in App Service.
'mysql' => [
...
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => (env('MYSQL_SSL') && extension_loaded('pdo_mysql')) ? [
PDO::MYSQL_ATTR_SSL_KEY => '/ssl/BaltimoreCyberTrustRoot.crt.pem',
] : []
],
The certificate BaltimoreCyberTrustRoot.crt.pem is provided in the repository for convenience in this tutorial.
Test the application locally
1. Run Laravel database migrations with .env.production as the environment file to create the tables in your
MySQL database in Azure Database for MySQL. Remember that .env.production has the connection
information to your MySQL database in Azure.
2. .env.production doesn't have a valid application key yet. Generate a new one for it in the terminal.
4. Go to http://localhost:8000 . If the page loads without errors, the PHP application is connecting to the
MySQL database in Azure.
5. Add a few tasks in the page.
6. To stop PHP, enter Ctrl + C in the terminal.
Commit your changes
Run the following Git commands to commit your changes:
git add .
git commit -m "database.php updates"
Deploy to Azure
In this step, you deploy the MySQL-connected PHP application to Azure App Service.
Configure a deployment user
FTP and local Git can deploy to an Azure web app by using a deployment user. Once you configure your
deployment user, you can use it for all your Azure deployments. Your account-level deployment username and
password are different from your Azure subscription credentials.
To configure the deployment user, run the az webapp deployment user set command in Azure Cloud Shell.
Replace <username> and <password> with a deployment user username and password.
The username must be unique within Azure, and for local Git pushes, must not contain the ‘@’ symbol.
The password must be at least eight characters long, with two of the following three elements: letters,
numbers, and symbols.
az webapp deployment user set --user-name <username> --password <password>
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
Create an App Service plan
In the Cloud Shell, create an App Service plan with the az appservice plan create command.
The following example creates an App Service plan named myAppServicePlan in the Free pricing tier:
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"adminSiteName": null,
"appServicePlanName": "myAppServicePlan",
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "app",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
In the Cloud Shell, create an App Service plan with the az appservice plan create command.
The following example creates an App Service plan named myAppServicePlan in the Free pricing tier:
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE --is-linux
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"freeOfferExpirationTime": null,
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "linux",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
# Bash
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --runtime
"PHP|7.2" --deployment-local-git
# PowerShell
az --% webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --runtime
"PHP|7.2" --deployment-local-git
When the web app has been created, the Azure CLI shows output similar to the following example:
You’ve created an empty new web app, with git deployment enabled.
NOTE
The URL of the Git remote is shown in the property, with the format
deploymentLocalGitUrl
https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git . Save this URL as you need it later.
# Bash
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --runtime
"PHP|7.2" --deployment-local-git
# PowerShell
az --% webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --runtime
"PHP|7.2" --deployment-local-git
When the web app has been created, the Azure CLI shows output similar to the following example:
You’ve created an empty new web app, with git deployment enabled.
NOTE
The URL of the Git remote is shown in the property, with the format
deploymentLocalGitUrl
https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git . Save this URL as you need it later.
az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings DB_HOST="
<mysql-server-name>.mysql.database.azure.com" DB_DATABASE="sampledb" DB_USERNAME="phpappuser@<mysql-server-
name>" DB_PASSWORD="MySQLAzure2017" MYSQL_SSL="true"
You can use the PHP getenv method to access the settings. the Laravel code uses an env wrapper over the PHP
getenv . For example, the MySQL configuration in config/database.php looks like the following code:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
...
],
2. In the Cloud Shell, set the application key in the App Service app by using the
az webapp config appsettings set command. Replace the placeholders <app-name> and
<outputofphpartisankey:generate>.
APP_DEBUG="true"tells Laravel to return debugging information when the deployed app encounters
errors. When running a production application, set it to false , which is more secure.
Set the virtual application path
Set the virtual application path for the app. This step is required because the Laravel application lifecycle begins
in the public directory instead of the application's root directory. Other PHP frameworks whose lifecycle start in
the root directory can work without manual configuration of the virtual application path.
In the Cloud Shell, set the virtual application path by using the az resource update command. Replace the
<app-name> placeholder.
By default, Azure App Service points the root virtual application path (/) to the root directory of the deployed
application files (sites\wwwroot).
Laravel application lifecycle begins in the public directory instead of the application's root directory. The default
PHP Docker image for App Service uses Apache, and it doesn't let you customize the DocumentRoot for Laravel.
But you can use .htaccess to rewrite all requests to point to /public instead of the root directory. In the
repository root, an .htaccess is added already for this purpose. With it, your Laravel application is ready to be
deployed.
For more information, see Change site root.
Push to Azure from Git
1. Since you're deploying the main branch, you need to set the default deployment branch for your App
Service app to main (see Change deployment branch). In the Cloud Shell, set the DEPLOYMENT_BRANCH app
setting with the az webapp config appsettings set command.
az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings
DEPLOYMENT_BRANCH='main'
2. Back in the local terminal window, add an Azure remote to your local Git repository. Replace
<deploymentLocalGitUrl-from-create-step> with the URL of the Git remote that you saved from Create a
web app.
3. Push to the Azure remote to deploy your app with the following command. When Git Credential Manager
prompts you for credentials, make sure you enter the credentials you created in Configure a
deployment user , not the credentials you use to sign in to the Azure portal.
This command may take a few minutes to run. While running, it displays information similar to the
following example:
NOTE
You may notice that the deployment process installs Composer packages at the end. App Service does not run these
automations during default deployment, so this sample repository has three additional files in its root directory to enable
it:
.deployment - This file tells App Service to run bash deploy.sh as the custom deployment script.
deploy.sh - The custom deployment script. If you review the file, you will see that it runs
php composer.phar install after npm install .
composer.phar - The Composer package manager.
You can use this approach to add any step to your Git-based deployment to App Service. For more information, see
Custom Deployment Script.
1. Since you're deploying the main branch, you need to set the default deployment branch for your App
Service app to main (see Change deployment branch). In the Cloud Shell, set the DEPLOYMENT_BRANCH app
setting with the az webapp config appsettings set command.
3. Push to the Azure remote to deploy your app with the following command. When Git Credential Manager
prompts you for credentials, make sure you enter the credentials you created in Configure a
deployment user , not the credentials you use to sign in to the Azure portal.
This command may take a few minutes to run. While running, it displays information similar to the
following example:
3. This command shows you the name of the migration file that's generated. Find this file in
database/migrations and open it.
4. Replace the up method with the following code:
6. In the local terminal window, run Laravel database migrations to make the change in the local database.
Based on the Laravel naming convention, the model Task (see app/Task.php) maps to the tasks table
by default.
Update application logic
1. Open the routes/web.php file. The application defines its routes and business logic here.
2. At the end of the file, add a route with the following code:
/**
* Toggle Task completeness
*/
Route::post('/task/{id}', function ($id) {
error_log('INFO: post /task/'.$id);
$task = Task::findOrFail($id);
$task->complete = !$task->complete;
$task->save();
return redirect('/');
});
The preceding code makes a simple update to the data model by toggling the value of complete .
Update the view
1. Open the resources/views/tasks.blade.php file. Find the <tr> opening tag and replace it with:
The preceding code changes the row color depending on whether the task is complete.
2. In the next line, you have the following code:
The preceding code adds the submit button that references the route that you defined earlier.
Test the changes locally
1. In the local terminal window, run the development server from the root directory of the Git repository.
2. To see the task status change, go to http://localhost:8000 and select the checkbox.
git add .
git commit -m "added complete checkbox"
git push azure main
3. Once the git push is complete, go to the Azure app and test the new functionality.
If you add any task, they're retained in the database. Updates to the data schema leave existing data intact.
Once log streaming has started, refresh the Azure app in the browser to get some web traffic. You can now see
console logs piped to the terminal. If you don't see console logs immediately, check again in 30 seconds.
To stop log streaming at any time, enter Ctrl +C.
To access the console logs generated from inside your application code in App Service, turn on diagnostics
logging by running the following command in the Cloud Shell:
az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging
filesystem --level Verbose
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
TIP
A PHP application can use the standard error_log() to output to the console. The sample application uses this approach in
app/Http/routes.php.
As a web framework, Laravel uses Monolog as the logging provider. To see how to get Monolog to output messages to
the console, see PHP: How to use monolog to log to console (php://out).
You see your app's Overview page. In this page, you can do basic management tasks like stop, start,
restart, browse, and delete.
The left menu provides pages for configuring your app.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
In this tutorial, you learned how to:
Create a MySQL database in Azure
Connect a PHP app to MySQL
Deploy the app to Azure
Update the data model and redeploy the app
Stream diagnostic logs from Azure
Manage the app in the Azure portal
Advance to the next tutorial to learn how to map a custom DNS name to the app.
Tutorial: Map custom DNS name to your app
Or, check out other resources:
Configure PHP app
Deploy a Node.js + MongoDB web app to Azure
5/18/2022 • 27 minutes to read • Edit Online
In this tutorial, you'll deploy a sample Express.js app using a MongoDB database to Azure. The Express.js app
will be hosted in Azure App Service, which supports hosting Node.js apps in both Linux (Node versions 12, 14,
and 16) and Windows (versions 12 and 14) server environments. The MongoDB database will be hosted in
Azure Cosmos DB, a cloud native database offering a 100% MongoDB compatible API.
This article assumes you're already familiar with Node.js development and have Node and MongoDB installed
locally. You'll also need an Azure account with an active subscription. If you don't have an Azure account, you can
create one for free.
Sample application
To follow along with this tutorial, clone or download the sample application from the repository
https://github.com/Azure-Samples/msdocs-nodejs-mongodb-azure-sample-app.
Sign in to the Azure portal and follow these steps to create your Azure App Service resources.
IN ST RUC T IO N S SC REEN SH OT
On the Create Web App page, fill out the form as follows.
1. Resource Group → Select Create new and use a name
of msdocs-expressjs-mongodb-tutorial.
2. Name → msdocs-expressjs-mongodb-XYZ where
XYZ is any three random characters. This name must
be unique across Azure.
3. Publish → Code .
4. Runtime stack → Node 14 LTS.
5. Operating System → Linux.
6. Region → Any Azure region near you.
7. Linux Plan → Select Create new and use a name of
msdocs-expressjs-mongodb-plan .
8. Sku and size → Select Change size to select a
different App Service plan.
For this example, select Dev / Test at the top of the screen
and select B1 (Basic) plan. The B1 Basic plan will incur a small
charge against your Azure account but offers better
performance than the F1 (Free) plan.
You must sign in to the Azure portal to finish these steps to create a Cosmos DB.
IN ST RUC T IO N S SC REEN SH OT
Azure portal
VS Code
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
To deploy your application code directly from VS Code, you must have the Azure Tools extension pack installed
and be signed into Azure from VS Code.
Download Azure Tools extension pack
IN ST RUC T IO N S SC REEN SH OT
Find the App Ser vice section in the Azure Tools extension
and then locate your web app under the correct
subscription. Right-click on the web app and then select
Deploy to Web App... from the menu.
The contents of the App Service diagnostic logs can be reviewed in the Azure portal, VS Code, or using the
Azure CLI.
Azure portal
VS Code
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
Select the Log stream item from the menu under the
Monitoring section. Refresh the home page in the app or
attempt other requests to generate some log messages.
You will see any log messages generated by your app and
messages generated by the service in the output.
From the main page in Kudu, you can access information about the application hosting environment, app
settings, deployments, and browse the files in the wwwroot directory.
Selecting the Deployments link under the REST API header will show you a history of deployments of your web
app.
Selecting the Site wwwroot link under the Browse Directory heading lets you browse and view the files on the
web server.
Clean up resources
When you're finished, you can delete all the resources from Azure by deleting the resource group for the
application.
Azure portal
VS Code
Azure CLI
Follow these steps while you're signed-in to the Azure portal to delete a resource group.
IN ST RUC T IO N S SC REEN SH OT
Next steps
JavaScript on Azure developer center
Configure Node.js app in App Service
Build a Ruby and Postgres app in Azure App
Service on Linux
5/18/2022 • 13 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This tutorial shows how to
create a Ruby app and connect it to a PostgreSQL database. When you're finished, you'll have a Ruby on Rails
app running on App Service on Linux.
Prerequisites
To complete this tutorial:
Install Git
Install Ruby 2.6
Install Ruby on Rails 5.1
Install and run PostgreSQL
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
If your connection is successful, your Postgres database is running. If not, make sure that your local
Postgres database is started by following the steps at Downloads - PostgreSQL Core Distribution.
2. Type \q to exit the Postgres client.
3. Create a Postgres user that can create databases by running the following command, using your signed-
in Linux username.
rake db:create
rake db:migrate
rails server
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
2. Create the Postgres database in Azure with the az postgres up command, as shown in the following
example. Replace <postgresql-name> with a unique name (the server endpoint is https://<postgresql-
name>.postgres.database.azure.com). For <admin-username> and <admin-password>, specify
credentials to create an administrator user for this Postgres server.
This command may take a while because it's doing the following:
Creates a resource group called myResourceGroup , if it doesn't exist. Every Azure resource needs to be
in one of these. --resource-group is optional.
Creates a Postgres server with the administrative user.
Creates a sampledb database.
Allows access from your local IP address.
Allows access from Azure services.
Create a database user with access to the sampledb database.
You can do all the steps separately with other az postgres commands and psql , but az postgres up
does all of them in one step for you.
When the command finishes, find the output lines that being with Ran Database Query: . They show the
database user that's created for you, with the username root and password Sampledb1 . You'll use them
later to connect your app to the database.
TIP
--location <location-name> , can be set to any one of the Azure regions. You can get the regions available to
your subscription with the az account list-locations command. For production apps, put your database and
your app in the same location.
production:
<<: *default
host: <%= ENV['DB_HOST'] %>
database: <%= ENV['DB_DATABASE'] %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
export DB_HOST=<postgres-server-name>.postgres.database.azure.com
export DB_DATABASE=sampledb
export DB_USERNAME=root@<postgres-server-name>
export DB_PASSWORD=Sampledb1
2. Run Rails database migrations with the production values you just configured to create the tables in your
Postgres database in Azure Database for PostgreSQL.
3. When running in the production environment, the Rails application needs precompiled assets. Generate
the required assets with the following command:
rake assets:precompile
4. The Rails production environment also uses secrets to manage security. Generate a secret key.
rails secret
5. Save the secret key to the respective variables used by the Rails production environment. For
convenience, you use the same key for both variables.
export RAILS_MASTER_KEY=<output-of-rails-secret>
export SECRET_KEY_BASE=<output-of-rails-secret>
6. Enable the Rails production environment to serve JavaScript and CSS files.
export RAILS_SERVE_STATIC_FILES=true
8. Navigate to http://localhost:3000 . If the page loads without errors, the Ruby on Rails application is
connecting to the Postgres database in Azure.
9. Add a few tasks in the page.
10. To stop the Rails server, type Ctrl + C in the terminal.
Commit your changes
1. Run the following Git commands to commit your changes:
git add .
git commit -m "database.yml updates"
Deploy to Azure
In this step, you deploy the Postgres-connected Rails application to Azure App Service.
Configure a deployment user
FTP and local Git can deploy to an Azure web app by using a deployment user. Once you configure your
deployment user, you can use it for all your Azure deployments. Your account-level deployment username and
password are different from your Azure subscription credentials.
To configure the deployment user, run the az webapp deployment user set command in Azure Cloud Shell.
Replace <username> and <password> with a deployment user username and password.
The username must be unique within Azure, and for local Git pushes, must not contain the ‘@’ symbol.
The password must be at least eight characters long, with two of the following three elements: letters,
numbers, and symbols.
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
Create an App Service plan
In the Cloud Shell, create an App Service plan with the az appservice plan create command.
The following example creates an App Service plan named myAppServicePlan in the Free pricing tier:
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE --is-linux
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"freeOfferExpirationTime": null,
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "linux",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
When the web app has been created, the Azure CLI shows output similar to the following example:
You've created an empty new web app, with git deployment enabled.
NOTE
The URL of the Git remote is shown in the deploymentLocalGitUrl property, with the format
https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git . Save this URL as you need it later.
az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings DB_HOST="
<postgres-server-name>.postgres.database.azure.com" DB_DATABASE="sampledb" DB_USERNAME="root@<postgres-
server-name>" DB_PASSWORD="Sampledb1"
rails secret
2. In the following Cloud Shell command, replace the two <output-of-rails-secret> placeholders with the
new secret key you generated in the local terminal.
ASSETS_PRECOMPILE="true" tells the default Ruby container to precompile assets at each Git deployment.
For more information, see Precompile assets and Serve static assets.
Push to Azure from Git
1. Since you're deploying the main branch, you need to set the default deployment branch for your App
Service app to main (see Change deployment branch). In the Cloud Shell, set the DEPLOYMENT_BRANCH app
setting with the az webapp config appsettings set command.
2. In the local terminal, add an Azure remote to your local Git repository.
3. Push to the Azure remote to deploy the Ruby on Rails application. You are prompted for the password
you supplied earlier as part of the creation of the deployment user.
During deployment, Azure App Service communicates its progress with Git.
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 291 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Updating branch 'main'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'a5e076db9c'.
remote: Running custom deployment command...
remote: Running deployment command...
...
< Output has been truncated for readability >
Congratulations, you're running a data-driven Ruby on Rails app in Azure App Service.
params.require(:task).permit(:Description)
params.require(:task).permit(:Description, :Done)
Open the app/views/tasks/index.html.erb file, which is the Index page for all records.
Find the line <th><%= model_class.human_attribute_name(:Description) %></th> and insert the following
code directly below it:
4. In the same file, find the line <td><%= task.Description %></td> and insert the following code directly
below it:
<td><%= check_box "task", "Done", {:checked => task.Done, :disabled => true} %></td>
rails server
2. To see the task status change, navigate to http://localhost:3000 and add or edit items.
3. To stop the Rails server, type Ctrl + C in the terminal.
Publish changes to Azure
1. In the terminal, run Rails database migrations for the production environment to make the change in the
Azure database.
2. Commit all the changes in Git, and then push the code changes to Azure.
git add .
git commit -m "added complete checkbox"
git push azure main
3. Once the git push is complete, navigate to the Azure app and test the new functionality.
If you added any tasks, they are retained in the database. Updates to the data schema leave existing data
intact.
Stream diagnostic logs
To access the console logs generated from inside your application code in App Service, turn on diagnostics
logging by running the following command in the Cloud Shell:
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
You see your app's Overview page. Here, you can perform basic management tasks like stop, start,
restart, browse, and delete.
The left menu provides pages for configuring your app.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
In this tutorial, you learned how to:
Create a Postgres database in Azure
Connect a Ruby on Rails app to Postgres
Deploy the app to Azure
Update the data model and redeploy the app
Stream diagnostic logs from Azure
Manage the app in the Azure portal
Advance to the next tutorial to learn how to map a custom DNS name to your app.
Tutorial: Map custom DNS name to your app
Or, check out other resources:
Configure Ruby app
Deploy a Python (Django or Flask) web app with
PostgreSQL in Azure
5/18/2022 • 33 minutes to read • Edit Online
In this tutorial, you'll deploy a data-driven Python web app (Django or Flask ) with the Azure Database for
PostgreSQL relational database service. The Python app is hosted in a fully managed Azure App Ser vice
which supports Python 3.7 or higher in a Linux server environment. You can start with a basic pricing tier that
can be scaled up at any later time.
1 - Sample application
Sample Python applications using the Flask and Django framework are provided to help you follow along with
this tutorial. Download or clone one of the sample applications to your local workstation.
Flask
Django
cd msdocs-flask-postgresql-sample-app
Windows
macOS/Linux
py -m venv .venv
.venv/scripts/activate
NOTE
If you are following along with this tutorial with your own app, look at the requirements.txt file description in each
project's README.md file (Flask, Django) to see what packages you'll need.
For Django, you can use SQLite locally instead of PostgreSQL by following the instructions in the comments of
the settings.py file.
Create the restaurant and review database tables:
Flask
Django
flask db init
flask db migrate -m "initial migration"
flask run
Flask
Django
In a web browser, go to the sample application at http://localhost:5000 and add some restaurants and
restaurant reviews to see how the app works.
TIP
With Django, you can create users with the python manage.py createsuperuser command like you would with a typical
Django app. For more information, see the documentation for django django-admin and manage.py. Use the superuser
account to access the /admin portion of the web site. For Flask, use an extension such as Flask-admin to provide the
same functionality.
Azure portal
VS Code
Azure CLI
Sign in to the Azure portal and follow these steps to create your Azure App Service resource.
IN ST RUC T IO N S SC REEN SH OT
On the Create Web App page, fill out the form as follows:
1. Resource Group → Select Create new and use
a name of msdocs-python-postgres-webapp-rg.
2. Name → Use msdocs-python-postgres-webapp-
<unique-id>. The name must be unique across
Azure with the web app's URL
https://<app-service-
name>.azurewebsites.com
).
3. Runtime stack → Python 3.9
4. Region → Any Azure region near you.
5. App Ser vice Plan → Select Create new under
Linux Plan and use the name of msdocs-
python-postgres-webapp-plan.
6. App Ser vice Plan → Select Change size under
Sku and size to select a different App Service
plan.
Having issues? Refer first to the Troubleshooting guide, otherwise, let us know.
Azure portal
VS Code
Azure CLI
Sign in to the Azure portal and follow these steps to create your Azure Database for PostgreSQL resource.
IN ST RUC T IO N S SC REEN SH OT
On the Flexible ser ver page, fill out the form as follows:
1. Resource group → Select and use a name of
msdocs-python-postgres-webapp-rg.
2. Ser ver name → Enter a name such as msdocs-
python-postgres-webapp-db-<unique-id>. The
name must be unique across Azure with the
database server's URL
https://<server-
name>.postgres.database.azure.com
). Allowed characters are A - Z , 0 - 9 , and -
.
3. Region → Same Azure region used for the Web
App.
4. Data source → None
5. Workload type → Production
6. Compute + storage → Select Configure
ser ver to select a different Compute + storage
plan, which is discussed below.
7. Availability zone → Keep the default (which is
no preference).
8. Version → Keep the default (which is the latest
version).
IN ST RUC T IO N S SC REEN SH OT
Back on the main Flexible ser ver page, finish the basic
configuration:
1. Administrator account → Enter a Admin
username and Password to be used for the
database administrator account.
2. Select Next: Networking at the bottom of the
screen.
In your local environment using the PostgreSQL interactive terminal psql, connect to the PostgreSQL database
server, and create the restaurant database:
psql --host=<server-name>.postgres.database.azure.com \
--port=5432 \
--username=<admin-user> \
--dbname=postgres
The values of <server-name> and <admin-user> are the values from a previous step. If you have trouble
connecting, restart the database and try again.
Optionally, verify that the restaurant database was successfully created by running \c restaurant to change
the prompt from postgres (default) to the restaurant . Type \? to show help or \q to quit.
Having issues? Let us know.
4 - Allow web app to access the database
After the Azure Database for PostgreSQL server is created, configure access to the server from the web app by
adding a firewall rule. This can be done through the Azure portal or the Azure CLI.
If you're working in VS Code, right-click the database server and select Open in Por tal to go to the Azure
portal. Or, go to the Azure Cloud Shell and run the Azure CLI commands.
Azure portal
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
Having issues? Refer first to the Troubleshooting guide, otherwise, let us know.
Azure portal
VS Code
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
In the portal, go to the App Service page for the web app.
1. Select Configuration under Settings on the
left side.
2. Select Application settings at the top of the
page.
IN ST RUC T IO N S SC REEN SH OT
Having issues? Refer first to the Troubleshooting guide, otherwise, let us know.
NOTE
If you want to try an alternative approach to connect your app to the Postgres database in Azure, see the Service
Connector version of this tutorial. Service Connector is a new Azure service that is currently in public preview. Section 4.2
of that tutorial introduces a simplified process for creating the connection.
To deploy a web app from VS Code, you must have the Azure Tools extension pack installed and be signed into
Azure from VS Code.
IN ST RUC T IO N S SC REEN SH OT
IN ST RUC T IO N S SC REEN SH OT
Select your web app as the web app to deploy in the dialog
at the top of the screen.
Having issues? Refer first to the Troubleshooting guide, otherwise, let us know.
Azure portal
VS Code
Azure CLI
Navigate to page for the App Service instance in the Azure portal.
1. Select SSH , under Development Tools on the left side
2. Then Go to open an SSH console on the web app server. (It may take a minute to connect for the first time as
the web app container needs to start.)
NOTE
If you cannot connect to the SSH session, then the app itself has failed to start. Check the diagnostic logs for details.
For example, if you haven't created the necessary app settings in the previous section, the logs will indicate
KeyError: 'DBNAME' .
Step 2. In the SSH session, run the following command to migrate the models into the database schema (you
can paste commands using Ctrl +Shift +V ):
Flask
Django
When you deploy the Flask sample app to Azure App Service, the database tables are created automatically in
Azure PostgreSQL. If the tables aren't created, try the following command:
If you encounter any errors related to connecting to the database, check the values of the application settings of
the App Service created in the previous section, namely DBHOST , DBNAME , DBUSER , and DBPASS . Without those
settings, the migrate command can't communicate with the database.
TIP
In an SSH session, for Django you can also create users with the python manage.py createsuperuser command like
you would with a typical Django app. For more information, see the documentation for django django-admin and
manage.py. Use the superuser account to access the /admin portion of the web site. For Flask, use an extension such as
Flask-admin to provide the same functionality.
Flask
Django
Having issues? Let us know.
Flask
Django
def index(request):
print('Request for index page received')
restaurants =
Restaurant.objects.annotate(avg_rating=Avg('review__rating')).annotate(review_count=Count('review'))
return render(request, 'restaurant_review/index.html', {'restaurants': restaurants })
You can access the console logs generated from inside the container that hosts the app on Azure.
Azure portal
VS Code
Azure CLI
IN ST RUC T IO N S SC REEN SH OT
Select the Log stream item from the menu under the
Monitoring section. Refresh the home page in the app or
attempt other requests to generate some log messages.
You will see any log messages generated by your app and
messages generated by the service in the output.
Clean up resources
You can leave the app and database running as long as you want for further development work and skip ahead
to Next steps.
However, when you're finished with the sample app, you can remove all of the resources for the app from Azure
to ensure you don't incur other charges and keep your Azure subscription uncluttered. Removing the resource
group also removes all resources in the resource group and is the fastest way to remove all Azure resources for
your app.
Azure portal
VS Code
Azure CLI
Follow these steps while signed-in to the Azure portal to delete a resource group.
IN ST RUC T IO N S SC REEN SH OT
Next steps
Learn how to map a custom DNS name to your app:
Tutorial: Map custom DNS name to your app
Learn how App Service runs a Python app:
Configure Python app
Tutorial: Build a Java Spring Boot web app with
Azure App Service on Linux and Azure Cosmos DB
5/18/2022 • 6 minutes to read • Edit Online
This tutorial walks you through the process of building, configuring, deploying, and scaling Java web apps on
Azure. When you are finished, you will have a Spring Boot application storing data in Azure Cosmos DB running
on Azure App Service on Linux.
Prerequisites
Azure CLI, installed on your own computer.
Git
Java JDK
Maven
az login
az account set -s <your-subscription-id>
3. Create Azure Cosmos DB with the GlobalDocumentDB kind. The name of Cosmos DB must use only lower
case letters. Note down the documentEndpoint field in the response from the command.
cd initial/spring-todo-app
cp set-env-variables-template.sh .scripts/set-env-variables.sh
Edit .scripts/set-env-variables.sh in your favorite editor and supply Azure Cosmos DB connection info. For the
App Service Linux configuration, use the same region as before ( your-resource-group-region ) and resource
group ( your-azure-group-name ) used when creating the Cosmos DB database. Choose a WEBAPP_NAME that is
unique since it cannot duplicate any web app name in any Azure deployment.
export COSMOSDB_URI=<put-your-COSMOS-DB-documentEndpoint-URI-here>
export COSMOSDB_KEY=<put-your-COSMOS-DB-primaryMasterKey-here>
export COSMOSDB_DBNAME=<put-your-COSMOS-DB-name-here>
source .scripts/set-env-variables.sh
These environment variables are used in application.properties in the TODO list app. The fields in the
properties file set up a default repository configuration for Spring Data:
azure.cosmosdb.uri=${COSMOSDB_URI}
azure.cosmosdb.key=${COSMOSDB_KEY}
azure.cosmosdb.database=${COSMOSDB_DBNAME}
@Repository
public interface TodoItemRepository extends DocumentDbRepository<TodoItem, String> {
}
@Document
public class TodoItem {
private String id;
private String description;
private String owner;
private boolean finished;
Run the sample app
Use Maven to run the sample.
[INFO] SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
[INFO] SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
[INFO] WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
2018-10-28 15:04:32.101 INFO 7673 --- [ main] c.m.azure.documentdb.DocumentClient :
Initializing DocumentClient with serviceEndpoint [https://sample-cosmos-db-westus.documents.azure.com:443/],
ConnectionPolicy [ConnectionPolicy [requestTimeout=60, mediaRequestTimeout=300, connectionMode=Gateway,
mediaReadMode=Buffered, maxPoolSize=800, idleConnectionTimeout=60, userAgentSuffix=;spring-
data/2.0.6;098063be661ab767976bd5a2ec350e978faba99348207e8627375e8033277cb2,
retryOptions=com.microsoft.azure.documentdb.RetryOptions@6b9fb84d, enableEndpointDiscovery=true,
preferredLocations=null]], ConsistencyLevel [null]
[INFO] AnnotationMBeanExporter - Registering beans for JMX exposure on startup
[INFO] TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
[INFO] TodoApplication - Started TodoApplication in 45.573 seconds (JVM running for 76.534)
You can access Spring TODO App locally using this link once the app is started: http://localhost:8080/ .
If you see exceptions instead of the "Started TodoApplication" message, check that the bash script in the
previous step exported the environment variables properly and that the values are correct for the Azure Cosmos
DB database you created.
<!--*************************************************-->
<!-- Deploy to Java SE in App Service Linux -->
<!--*************************************************-->
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>2.5.0</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<appSettings>
<property>
<name>COSMOSDB_URI</name>
<value>${COSMOSDB_URI}</value>
</property>
<property>
<name>COSMOSDB_KEY</name>
<value>${COSMOSDB_KEY}</value>
</property>
<property>
<name>COSMOSDB_DBNAME</name>
<value>${COSMOSDB_DBNAME}</value>
</property>
<property>
<name>JAVA_OPTS</name>
<value>-Dserver.port=80</value>
</property>
</appSettings>
</configuration>
</plugin>
...
</plugins>
The output contains the URL to your deployed application (in this example,
https://spring-todo-app.azurewebsites.net ). You can copy this URL into your web browser or run the following
command in your Terminal window to load your app.
explorer https://spring-todo-app.azurewebsites.net
You should see the app running with the remote URL in the address bar:
Stream diagnostic logs
To access the console logs generated from inside your application code in App Service, turn on diagnostics
logging by running the following command in the Cloud Shell:
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
Clean up resources
If you don't need these resources for another tutorial (see Next steps), you can delete them by running the
following command in the Cloud Shell:
Next steps
Azure for Java Developers Spring Boot, Spring Data for Cosmos DB, Azure Cosmos DB and App Service Linux.
Learn more about running Java apps on App Service on Linux in the developer guide.
Java in App Service Linux dev guide
Migrate custom software to Azure App Service
using a custom container
5/18/2022 • 19 minutes to read • Edit Online
Azure App Service provides pre-defined application stacks on Windows like ASP.NET or Node.js, running on IIS.
The preconfigured Windows environment locks down the operating system from:
Administrative access.
Software installations.
Changes to the global assembly cache.
For more information, see Operating system functionality on Azure App Service.
You can deploy a custom-configured Windows image from Visual Studio to make OS changes that your app
needs. So it's easy to migrate on-premises app that requires custom OS and software configuration. This tutorial
demonstrates how to migrate to App Service an ASP.NET app that uses custom fonts installed in the Windows
font library. You deploy a custom-configured Windows image from Visual Studio to Azure Container Registry,
and then run it in App Service.
Prerequisites
To complete this tutorial:
Sign up for a Docker Hub account
Install Docker for Windows.
Switch Docker to run Windows containers.
Install Visual Studio 2022 with the ASP.NET and web development and Azure development workloads.
If you've installed Visual Studio 2022 already:
Install the latest updates in Visual Studio by clicking Help > Check for Updates .
Add the workloads in Visual Studio by clicking Tools > Get Tools and Features .
As the app uses an installed font, the app can't run in the App Service sandbox. However, you can deploy it using
a Windows container instead, because you can install the font in the Windows container.
Configure Windows container
In Solution Explorer, right-click the CustomFontSample project and select Add > Container Orchestration
Suppor t .
Select Docker Compose > OK .
Your project is now set to run in a Windows container. A Dockerfile is added to the CustomFontSample
project, and a docker-compose project is added to the solution.
From the Solution Explorer, open Dockerfile .
You need to use a supported parent image. Change the parent image by replacing the FROM line with the
following code:
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.7.2-windowsservercore-ltsc2019
At the end of the file, add the following line and save the file:
RUN ${source:-obj/Docker/publish/InstallFont.ps1}
You can find InstallFont.ps1 in the CustomFontSample project. It's a simple script that installs the font. You can
find a more complex version of the script in the Script Center.
NOTE
To test the Windows container locally, ensure that Docker is started on your local machine.
SET T IN G SUGGEST ED VA L UE F O R M O RE IN F O RM AT IO N
Sign in to Azure
Sign in to the Azure portal at https://portal.azure.com.
SET T IN G SUGGEST ED VA L UE F O R M O RE IN F O RM AT IO N
SET T IN G SUGGEST ED VA L UE
Image customfontsample
Tag latest
1. Select Go to resource .
2. In the app page, select the link under URL .
A new browser page is opened to the following page:
Wait a few minutes and try again, until you get the homepage with the beautiful font you expect:
Congratulations! You've migrated an ASP.NET application to Azure App Service in a Windows container.
https://<app-name>.scm.azurewebsites.net/api/logstream
Azure App Service uses the Docker container technology to host both built-in images and custom images. To see
a list of built-in images, run the Azure CLI command, 'az webapp list-runtimes --os linux'. If those images don't
satisfy your needs, you can build and deploy a custom image.
In this tutorial, you learn how to:
Push a custom Docker image to Azure Container Registry
Deploy the custom image to App Service
Configure environment variables
Pull image into App Service using a managed identity
Access diagnostic logs
Enable CI/CD from Azure Container Registry to App Service
Connect to the container using SSH
Completing this tutorial incurs a small charge in your Azure account for the container registry and can incur
more costs for hosting the container for longer than a month.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Install Docker, which you use to build Docker images. Installing Docker might require a computer restart.
After installing Docker, open a terminal window and verify that the docker is installed:
docker --version
Ensure that you include the --config core.autocrlf=input argument to guarantee proper line endings in files
that are used inside the Linux container:
Then, navigate to the folder:
cd docker-django-webapp-linux
FROM tiangolo/uwsgi-nginx-flask:python3.6
# ssh
ENV SSH_PASSWD "root:Docker!"
RUN apt-get update \
&& apt-get install -y --no-install-recommends dialog \
&& apt-get update \
&& apt-get install -y --no-install-recommends openssh-server \
&& echo "$SSH_PASSWD" | chpasswd
The first group of commands installs the app's requirements in the environment.
The second group of commands create an SSH server for secure communication between the container and
the host.
The last line, ENTRYPOINT ["init.sh"] , invokes init.sh to start the SSH service and Python server.
2. Test that the build works by running the Docker container locally:
This docker run command specifies the port with the -p argument followed by the name of the image.
-it lets you stop it with Ctrl+C .
TIP
If you're running on Windows and see the error, standard_init_linux.go:211: exec user process caused "no such file
or directory", the init.sh file contains CR-LF line endings instead of the expected LF endings. This error happens if
you used git to clone the sample repository but omitted the --config core.autocrlf=input parameter. In this
case, clone the repository again with the `--config`` argument. You might also see the error if you edited init.sh
and saved it with CRLF endings. In this case, save the file again with LF endings only.
3. Browse to http://localhost:8000 to verify the web app and container are functioning correctly.
You can change the --location value to specify a region near you.
The JSON output of this command provides two passwords along with the registry's user name.
3. Use the docker login command to sign in to the container registry:
Replace <registry-name> and <registry-username> with values from the previous steps. When prompted,
type in one of the passwords from the previous step.
You use the same registry name in all the remaining steps of this section.
4. When the log in is successful, tag your local Docker image to the registry:
5. Use the docker push command to push the image to the registry:
Uploading the image the first time might take a few minutes because it includes the base image.
Subsequent uploads are typically faster.
While you're waiting, you can complete the steps in the next section to configure App Service to deploy
from the registry.
6. Use the az acr repository list command to verify that the push was successful:
An App Service plan corresponds to the virtual machine that hosts the web app. By default, the previous
command uses an inexpensive B1 pricing tier that is free for the first month. You can control the tier with
the --sku parameter.
2. Create the web app with the az webpp create command:
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --
deployment-container-image-name <registry-name>.azurecr.io/appsvc-tutorial-custom-image:latest
Replace <app-name> with a name for the web app, which must be unique across all of Azure. Also replace
<registry-name> with the name of your registry from the previous section.
3. Use az webapp config appsettings set to set the WEBSITES_PORT environment variable as expected by the
app code:
Replace <app-name> with the name you used in the previous step.
For more information on this environment variable, see the readme in the sample's GitHub repository.
4. Enable the system-assigned managed identity for the web app by using the az webapp identity assign
command:
Replace <app-name> with the name you used in the previous step. The output of the command (filtered by
the --query and --output arguments) is the service principal of the assigned identity, which you use
shortly.
Managed identity allows you to grant permissions to the web app to access other Azure resources
without needing any specific credentials.
5. Retrieve your subscription ID with the az account show command, which you need in the next step:
TIP
If your app uses a user-assigned managed identity, set an additional AcrUserManagedIdentityID property to
specify its client ID:
Replace <app-name> with the name of your web app and replace <registry-name> in two places with the
name of your registry.
When using a registry other than Docker Hub (as this example shows), --docker-registry-server-url
must be formatted as https:// followed by the fully qualified domain name of the registry.
The message, "No credential was provided to access Azure Container Registry. Trying to look up..."
indicates that Azure is using the app's managed identity to authenticate with the container registry
rather than asking for a username and password.
If you encounter the error, "AttributeError: 'NoneType' object has no attribute 'reserved'", ensure that
your <app-name> is correct.
TIP
You can retrieve the web app's container settings at any time with the command
az webapp config container show --name <app-name> --resource-group myResourceGroup . The image is
specified in the property DOCKER_CUSTOM_IMAGE_NAME . When the web app is deployed through Azure DevOps or
Azure Resource Manager templates, the image can also appear in a property named LinuxFxVersion . Both
properties serve the same purpose. If both are present in the web app's configuration, LinuxFxVersion takes
precedence.
2. When the az webapp config container set command completes, the web app should be running in the
container on App Service.
To test the app, browse to https://<app-name>.azurewebsites.net , replacing <app-name> with the name of
your web app. On first access, it might take some time for the app to respond because App Service must
pull the entire image from the registry. If the browser times out, just refresh the page. Once the initial
image is pulled, subsequent tests will run much faster.
Access diagnostic logs
While you're waiting for the App Service to pull in the image, it's helpful to see exactly what App Service is doing
by streaming the container logs to your terminal.
1. Turn on container logging:
CI_CD_URL is a URL that App Service generates for you. Your registry should use this URL to notify App
Service that an image push occurred. It doesn't actually create the webhook for you.
2. Create a webhook in your container registry using the CI_CD_URL you got from the last step.
az acr webhook create --name appserviceCD --registry <registry-name> --uri '<ci-cd-url>' --actions
push --scope appsvc-tutorial-custom-image:latest
3. To test if your webhook is configured properly, ping the webhook and see if you get a 200 OK response.
eventId=$(az acr webhook ping --name appserviceCD --registry <registry-name> --query id --output tsv)
az acr webhook list-events --name appserviceCD --registry <registry-name> --query "[?
id=='$eventId'].eventResponseMessage"
TIP
To see all information about all webhook events, remove the --query parameter.
If you're streaming the container log, you should see the message after the webhook ping:
Starting container for site , because the webhook triggers the app to restart. Since you haven't made any
updates to the image, there's nothing new for App Service to pull.
7. When the image push is complete, the webhook notifies the App Service about the push, and App Service
tries to pull in the updated image. Wait a few minutes, and then verify that the update has been deployed
by browsing to https://<app-name>.azurewebsites.net .
NOTE
This configuration doesn't allow external connections to the container. SSH is available only through the Kudu/SCM Site.
The Kudu/SCM site is authenticated with your Azure account. root:Docker! should not be altered SSH. SCM/KUDU will use
your Azure Portal credentials. Changing this value will result in an error when using SSH.
The Dockerfile also copies the sshd_config file to the /etc/ssh/ folder and exposes port 2222 on the container:
# ...
Port 2222 is an internal port accessible only by containers within the bridge network of a private virtual
network.
Finally, the entry script, init.sh, starts the SSH server.
#!/bin/bash
service ssh start
Clean up resources
The resources you created in this article might incur ongoing costs. To clean up the resources, you only need to
delete the resource group that contains them:
Next steps
What you learned:
Deploy a custom image to a private container registry
Deploy and the custom image in App Service
Update and redeploy the image
Access diagnostic logs
Connect to the container using SSH
Push a custom Docker image to Azure Container Registry
Deploy the custom image to App Service
Configure environment variables
Pull image into App Service using a managed identity
Access diagnostic logs
Enable CI/CD from Azure Container Registry to App Service
Connect to the container using SSH
In the next tutorial, you learn how to map a custom DNS name to your app.
Tutorial: Map custom DNS name to your app
Or, check out other resources:
Configure custom container
Tutorial: Multi-container WordPress app
Tutorial: Create a multi-container (preview) app in
Web App for Containers
5/18/2022 • 11 minutes to read • Edit Online
NOTE
Multi-container is in preview.
Web App for Containers provides a flexible way to use Docker images. In this tutorial, you'll learn how to create
a multi-container app using WordPress and MySQL. You'll complete this tutorial in Cloud Shell, but you can also
run these commands locally with the Azure CLI command-line tool (2.0.32 or later).
In this tutorial, you learn how to:
Convert a Docker Compose configuration to work with Web App for Containers
Deploy a multi-container app to Azure
Add application settings
Use persistent storage for your containers
Connect to Azure Database for MySQL
Troubleshoot errors
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial, you need experience with Docker Compose.
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
mkdir tutorial
cd tutorial
Next, run the following command to clone the sample app repository to your tutorial directory. Then change to
the multicontainerwordpress directory.
cd multicontainerwordpress
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
Create an Azure App Service plan
In Cloud Shell, create an App Service plan in the resource group with the az appservice plan create command.
The following example creates an App Service plan named myAppServicePlan in the Standard pricing tier (
--sku S1 ) and in a Linux container ( --is-linux ).
When the App Service plan has been created, Cloud Shell shows information similar to the following example:
{
"adminSiteName": null,
"appServicePlanName": "myAppServicePlan",
"geoRegion": "South Central US",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "linux",
"location": "South Central US",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
When the web app has been created, Cloud Shell shows output similar to the following example:
{
"additionalProperties": {},
"availabilityState": "Normal",
"clientAffinityEnabled": true,
"clientCertEnabled": false,
"cloningInfo": null,
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"defaultHostName": "<app-name>.azurewebsites.net",
"enabled": true,
< JSON data removed for brevity. >
}
Congratulations , you've created a multi-container app in Web App for Containers. Next you'll configure your
app to use Azure Database for MySQL. Don't install WordPress at this time.
Creating the server may take a few minutes to complete. When the MySQL server is created, Cloud Shell shows
information similar to the following example:
{
"administratorLogin": "adminuser",
"administratorLoginPassword": null,
"fullyQualifiedDomainName": "<mysql-server-name>.database.windows.net",
"id": "/subscriptions/00000000-0000-0000-0000-
000000000000/resourceGroups/myResourceGroup/providers/Microsoft.DBforMySQL/servers/<mysql-
server-name>",
"location": "southcentralus",
"name": "<mysql-server-name>",
"resourceGroup": "myResourceGroup",
...
}
TIP
You can be even more restrictive in your firewall rule by using only the outbound IP addresses your app uses.
When the database has been created, Cloud Shell shows information similar to the following example:
{
"additionalProperties": {},
"charset": "latin1",
"collation": "latin1_swedish_ci",
"id": "/subscriptions/12db1644-4b12-4cab-ba54-
8ba2f2822c1f/resourceGroups/myResourceGroup/providers/Microsoft.DBforMySQL/servers/<mysql-
server-name>/databases/wordpress",
"name": "wordpress",
"resourceGroup": "myResourceGroup",
"type": "Microsoft.DBforMySQL/servers/databases"
}
When the app setting has been created, Cloud Shell shows information similar to the following example:
[
{
"name": "WORDPRESS_DB_HOST",
"slotSetting": false,
"value": "<mysql-server-name>.mysql.database.azure.com"
},
{
"name": "WORDPRESS_DB_USER",
"slotSetting": false,
"value": "adminuser@<mysql-server-name>"
},
{
"name": "WORDPRESS_DB_NAME",
"slotSetting": false,
"value": "wordpress"
},
{
"name": "WORDPRESS_DB_PASSWORD",
"slotSetting": false,
"value": "My5up3rStr0ngPaSw0rd!"
},
{
"name": "MYSQL_SSL_CA",
"slotSetting": false,
"value": "BaltimoreCyberTrustroot.crt.pem"
}
]
version: '3.3'
services:
wordpress:
image: mcr.microsoft.com/azuredocs/multicontainerwordpress
ports:
- "8000:80"
restart: always
Save your changes and exit nano. Use the command ^O to save and ^X to exit.
Update app with new configuration
In Cloud Shell, reconfigure your multi-container web app with the az webapp config container set command.
Don't forget to replace <app-name> with the name of the web app you created earlier.
When the app has been reconfigured, Cloud Shell shows information similar to the following example:
[
{
"name": "DOCKER_CUSTOM_IMAGE_NAME",
"value":
"COMPOSE|dmVyc2lvbjogJzMuMycKCnNlcnZpY2VzOgogICB3b3JkcHJlc3M6CiAgICAgaW1hZ2U6IG1zYW5nYXB1L3dvcmR
wcmVzcwogICAgIHBvcnRzOgogICAgICAgLSAiODAwMDo4MCIKICAgICByZXN0YXJ0OiBhbHdheXM="
}
]
When the app setting has been created, Cloud Shell shows information similar to the following example:
[
< JSON data removed for brevity. >
{
"name": "WORDPRESS_DB_NAME",
"slotSetting": false,
"value": "wordpress"
},
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"slotSetting": false,
"value": "TRUE"
}
]
version: '3.3'
services:
wordpress:
image: mcr.microsoft.com/azuredocs/multicontainerwordpress
volumes:
- ${WEBAPP_STORAGE_HOME}/site/wwwroot:/var/www/html
ports:
- "8000:80"
restart: always
After your command runs, it shows output similar to the following example:
[
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"slotSetting": false,
"value": "TRUE"
},
{
"name": "DOCKER_CUSTOM_IMAGE_NAME",
"value":
"COMPOSE|dmVyc2lvbjogJzMuMycKCnNlcnZpY2VzOgogICBteXNxbDoKICAgICBpbWFnZTogbXlzcWw6NS43CiAgICAgdm9
sdW1lczoKICAgICAgIC0gZGJfZGF0YTovdmFyL2xpYi9teXNxbAogICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgIGVudmlyb25
tZW50OgogICAgICAgTVlTUUxfUk9PVF9QQVNTV09SRDogZXhhbXBsZXBhc3MKCiAgIHdvcmRwcmVzczoKICAgICBkZXBlbmR
zX29uOgogICAgICAgLSBteXNxbAogICAgIGltYWdlOiB3b3JkcHJlc3M6bGF0ZXN0CiAgICAgcG9ydHM6CiAgICAgICAtICI
4MDAwOjgwIgogICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgIGVudmlyb25tZW50OgogICAgICAgV09SRFBSRVNTX0RCX1BBU1N
XT1JEOiBleGFtcGxlcGFzcwp2b2x1bWVzOgogICAgZGJfZGF0YTo="
}
]
version: '3.3'
services:
wordpress:
image: mcr.microsoft.com/azuredocs/multicontainerwordpress
ports:
- "8000:80"
restart: always
redis:
image: mcr.microsoft.com/oss/bitnami/redis:6.0.8
environment:
- ALLOW_EMPTY_PASSWORD=yes
restart: always
When the app setting has been created, Cloud Shell shows information similar to the following example:
[
< JSON data removed for brevity. >
{
"name": "WORDPRESS_DB_USER",
"slotSetting": false,
"value": "adminuser@<mysql-server-name>"
},
{
"name": "WP_REDIS_HOST",
"slotSetting": false,
"value": "redis"
}
]
After your command runs, it shows output similar to the following example:
[
{
"name": "DOCKER_CUSTOM_IMAGE_NAME",
"value":
"COMPOSE|dmVyc2lvbjogJzMuMycKCnNlcnZpY2VzOgogICBteXNxbDoKICAgICBpbWFnZTogbXlzcWw6NS43CiAgICAgdm9
sdW1lczoKICAgICAgIC0gZGJfZGF0YTovdmFyL2xpYi9teXNxbAogICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgIGVudmlyb25
tZW50OgogICAgICAgTVlTUUxfUk9PVF9QQVNTV09SRDogZXhhbXBsZXBhc3MKCiAgIHdvcmRwcmVzczoKICAgICBkZXBlbmR
zX29uOgogICAgICAgLSBteXNxbAogICAgIGltYWdlOiB3b3JkcHJlc3M6bGF0ZXN0CiAgICAgcG9ydHM6CiAgICAgICAtICI
4MDAwOjgwIgogICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgIGVudmlyb25tZW50OgogICAgICAgV09SRFBSRVNTX0RCX1BBU1N
XT1JEOiBleGFtcGxlcGFzcwp2b2x1bWVzOgogICAgZGJfZGF0YTo="
}
]
Click on Settings .
Click the Enable Object Cache button.
WordPress connects to the Redis server. The connection status appears on the same page.
Congratulations , you've connected WordPress to Redis. The production-ready app is now using Azure
Database for MySQL, persistent storage, and Redis . You can now scale out your App Service Plan to
multiple instances.
You see a log for each container and an additional log for the parent process. Copy the respective href value
into the browser to view the log.
Clean up deployment
After the sample script has been run, the following command can be used to remove the resource group and all
resources associated with it.
Next steps
In this tutorial, you learned how to:
Convert a Docker Compose configuration to work with Web App for Containers
Deploy a multi-container app to Azure
Add application settings
Use persistent storage for your containers
Connect to Azure Database for MySQL
Troubleshoot errors
Advance to the next tutorial to learn how to map a custom DNS name to your app.
Tutorial: Map custom DNS name to your app
Or, check out other resources:
Configure custom container
Environment variables and app settings reference
Tutorial: Authenticate and authorize users end-to-
end in Azure App Service
5/18/2022 • 17 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. In addition, App Service has
built-in support for user authentication and authorization. This tutorial shows how to secure your apps with App
Service authentication and authorization. It uses a ASP.NET Core app with an Angular.js front end as an example.
App Service authentication and authorization support all language runtimes, and you can learn how to apply it
to your preferred language by following the tutorial.
Azure App Service provides a highly scalable, self-patching web hosting service using the Linux operating
system. In addition, App Service has built-in support for user authentication and authorization. This tutorial
shows how to secure your apps with App Service authentication and authorization. It uses an ASP.NET Core app
with an Angular.js front end as an example. App Service authentication and authorization support all language
runtimes, and you can learn how to apply it to your preferred language by following the tutorial.
It also shows you how to secure a multi-tiered app, by accessing a secured back-end API on behalf of the
authenticated user, both from server code and from browser code.
These are only some of the possible authentication and authorization scenarios in App Service.
Here's a more comprehensive list of things you learn in the tutorial:
Enable built-in authentication and authorization
Secure apps against unauthenticated requests
Use Azure Active Directory as the identity provider
Access a remote app on behalf of the signed-in user
Secure service-to-service calls with token authentication
Use access tokens from server code
Use access tokens from client (browser) code
You can follow the steps in this tutorial on macOS, Linux, Windows.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial:
Install Git
Install the latest .NET Core 3.1 SDK
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
2. Navigate to http://localhost:5000 and try adding, editing, and removing todo items.
3. To stop ASP.NET Core, press Ctrl+C in the terminal.
4. Make sure the default branch is main .
TIP
The branch name change isn't required by App Service. However, since many repositories are changing their
default branch to main , this tutorial also shows you how to deploy a repository from main . For more
information, see Change deployment branch.
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
Create Azure resources
In the Cloud Shell, run the following commands to create two Windows web apps. Replace <front-end-app-
name> and <back-end-app-name> with two globally unique app names (valid characters are a-z , 0-9 , and
- ). For more information on each command, see Host a RESTful API with CORS in Azure App Service.
In the Cloud Shell, run the following commands to create two web apps. Replace <front-end-app-name> and
<back-end-app-name> with two globally unique app names (valid characters are a-z , 0-9 , and - ). For more
information on each command, see Create a .NET Core app in Azure App Service.
NOTE
Save the URLs of the Git remotes for your front-end app and back-end app, which are shown in the output from
az webapp create .
2. Back in the local terminal window , run the following Git commands to deploy to the back-end app.
Replace <deploymentLocalGitUrl-of-back-end-app> with the URL of the Git remote that you saved from
Create Azure resources. When prompted for credentials by Git Credential Manager, make sure that you
enter your deployment credentials, not the credentials you use to sign in to the Azure portal.
3. In the local terminal window, run the following Git commands to deploy the same code to the front-end
app. Replace <deploymentLocalGitUrl-of-front-end-app> with the URL of the Git remote that you saved
from Create Azure resources.
git remote add frontend <deploymentLocalGitUrl-of-front-end-app>
git push frontend main
http://<back-end-app-name>.azurewebsites.net
http://<front-end-app-name>.azurewebsites.net
NOTE
If your app restarts, you may have noticed that new data has been erased. This behavior by design because the sample
ASP.NET Core app uses an in-memory database.
2. Find the method that's decorated with [HttpGet] and replace the code inside the curly braces with:
The first line makes a GET /api/Todo/{id} call to the back-end API app.
4. Next, find the method that's decorated with [HttpPost] and replace the code inside the curly braces with:
The first line makes a POST /api/Todo call to the back-end API app.
5. Next, find the method that's decorated with [HttpPut("{id}")] and replace the code inside the curly
braces with:
The first line makes a PUT /api/Todo/{id} call to the back-end API app.
6. Next, find the method that's decorated with [HttpDelete("{id}")] and replace the code inside the curly
braces with:
The first line makes a DELETE /api/Todo/{id} call to the back-end API app.
7. Save all your changes. In the local terminal window, deploy your changes to the front-end app with the
following Git commands:
git add .
git commit -m "call back-end API"
git push frontend main
3. In your back-end app's left menu, select Authentication , and then click Add identity provider .
4. In the Add an identity provider page, select Microsoft as the Identity provider to sign in Microsoft
and Azure AD identities.
5. Accept the default settings and click Add .
6. The Authentication page opens. Copy the Client ID of the Azure AD application to a notepad. You need
this value later.
If you stop here, you have a self-contained app that's already secured by the App Service authentication and
authorization. The remaining sections show you how to secure a multi-app solution by "flowing" the
authenticated user from the front end to the back end.
Enable authentication and authorization for front-end app
Follow the same steps for the front-end app, but skip the last step. You don't need the client ID for the front-end
app. However, stay on the Authentication page for the front-end app because you'll use it in the next step.
If you like, navigate to http://<front-end-app-name>.azurewebsites.net . It should now direct you to a secured
sign-in page. After you sign in, you still can't access the data from the back-end app, because the back-end app
now requires Azure Active Directory sign-in from the front-end app. You need to do three things:
Grant the front end access to the back end
Configure App Service to return a usable token
Use the token in your code
TIP
If you run into errors and reconfigure your app's authentication/authorization settings, the tokens in the token store may
not be regenerated from the new settings. To make sure your tokens are regenerated, you need to sign out and sign back
in to your app. An easy way to do it is to use your browser in private mode, and close and reopen the browser in private
mode after changing the settings in your apps.
The commands effectively adds a loginParameters property with additional custom scopes. Here's an
explanation of the requested scopes:
, profile , and
openid email are requested by App Service by default already. For information, see OpenID
Connect Scopes.
api://<back-end-client-id>/user_impersonation is an exposed API in your back-end app registration. It's the
scope that gives you a JWT token that includes the back end app as a token audience.
offline_access is included here for convenience (in case you want to refresh tokens).
TIP
To view the api://<back-end-client-id>/user_impersonation scope in the Azure portal, go to the
Authentication page for the back-end app, click the link under Identity provider , then click Expose an API in the
left menu.
To configure the required scopes using a web interface instead, see the Microsoft steps at Refresh auth tokens.
Some scopes require admin or user consent. This requirement causes the consent request page to be displayed when
a user signs into the front-end app in the browser. To avoid this consent page, add the front end's app registration as
an authorized client application in the Expose an API page by clicking Add a client application and supplying the
client ID of the front end's app registration.
NOTE
For Linux apps, There's a temporary requirement to configure a versioning setting for the back-end app registration. In
the Cloud Shell, configure it with the following commands. Be sure to replace <back-end-client-id> with your back end's
client ID.
Your apps are now configured. The front end is now ready to access the back end with a proper access token.
For information on how to configure the access token for other providers, see Refresh identity provider tokens.
NOTE
These headers are injected for all supported languages. You access them using the standard pattern for each respective
language.
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"]);
}
This code adds the standard HTTP header Authorization: Bearer <access-token> to all remote API calls. In
the ASP.NET Core MVC request execution pipeline, OnActionExecuting executes just before the respective
action does, so each of your outgoing API call now presents the access token.
2. Save all your changes. In the local terminal window, deploy your changes to the front-end app with the
following Git commands:
git add .
git commit -m "add authorization header for server code"
git push frontend main
TIP
This section uses the standard HTTP methods to demonstrate the secure HTTP calls. However, you can use Microsoft
Authentication Library for JavaScript to help simplify the Angular.js application pattern.
Configure CORS
In the Cloud Shell, enable CORS to your client's URL by using the az webapp cors add command. Replace the
<back-end-app-name> and <front-end-app-name> placeholders.
This step is not related to authentication and authorization. However, you need it so that your browser allows the
cross-domain API calls from your Angular.js app. For more information, see Add CORS functionality.
Point Angular.js app to back-end API
1. In the local repository, open wwwroot/index.html.
2. In Line 51, set the variable to the HTTPS URL of your back-end app (
apiEndpoint
https://<back-end-app-name>.azurewebsites.net ). Replace <back-end-app-name> with your app name in
App Service.
3. In the local repository, open wwwroot/app/scripts/todoListSvc.js and see that apiEndpoint is prepended
to all the API calls. Your Angular.js app is now calling the back-end APIs.
Add access token to API calls
1. In wwwroot/app/scripts/todoListSvc.js, above the list of API calls (above the line getItems : function(){ ),
add the following function to the list:
setAuth: function (token) {
$http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
},
This function is called to set the default Authorization header with the access token. You call it in the next
step.
2. In the local repository, open wwwroot/app/scripts/app.js and find the following code:
$routeProvider.when("/Home", {
controller: "todoListCtrl",
templateUrl: "/App/Views/TodoList.html",
}).otherwise({ redirectTo: "/Home" });
$routeProvider.when("/Home", {
controller: "todoListCtrl",
templateUrl: "/App/Views/TodoList.html",
resolve: {
token: ['$http', 'todoListSvc', function ($http, todoListSvc) {
return $http.get('/.auth/me').then(function (response) {
todoListSvc.setAuth(response.data[0].access_token);
return response.data[0].access_token;
});
}]
},
}).otherwise({ redirectTo: "/Home" });
The new change adds the resolve mapping that calls /.auth/me and sets the access token. It makes sure
you have the access token before instantiating the todoListCtrl controller. That way all API calls by the
controller includes the token.
Deploy updates and test
1. Save all your changes. In the local terminal window, deploy your changes to the front-end app with the
following Git commands:
git add .
git commit -m "add authorization header for Angular"
git push frontend main
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
az group delete --name myAuthResourceGroup
Next steps
What you learned:
Enable built-in authentication and authorization
Secure apps against unauthenticated requests
Use Azure Active Directory as the identity provider
Access a remote app on behalf of the signed-in user
Secure service-to-service calls with token authentication
Use access tokens from server code
Use access tokens from client (browser) code
Advance to the next tutorial to learn how to map a custom DNS name to your app.
Map an existing custom DNS name to Azure App Service
Securely connect to Azure services and databases
from Azure App Service
5/18/2022 • 3 minutes to read • Edit Online
Your app service may need to connect to other Azure services such as a database, storage, or another app. This
overview recommends the more secure method for connecting.
C O N N EC T IO N M ET H O D W H EN TO USE
Direct connection from App Service managed identity Dependent service supports managed identity
Connect using Key Vault secrets from App Service managed Dependent service doesn't support managed identity.
identity
* Best for enterprise-level security.
* Connection includes non-Azure services such as GitHub,
Twitter, Facebook, Google
* Large team or automated connection string and secret
management
* Don't manage credentials manually.
* Credentials aren’t accessible to you.
* Manage connection information with environment
variables.
Connect with app settings * Best for small team or individual owner of Azure resources.
* Stage 1 of multi-stage migration to Azure.
* Temporary or proof-of-concept applications.
* Manually manage connection information with
environment variables.
Next steps
Learn how to use App Service managed identity with:
SQL server
SQL server
Azure storage
Microsoft Graph
Tutorial: Add app authentication to your web app
running on Azure App Service
5/18/2022 • 4 minutes to read • Edit Online
Learn how to enable authentication for your web app running on Azure App Service and limit access to users in
your organization.
In this tutorial, you learn how to:
Configure authentication for the web app.
Limit access to the web app to users in your organization by using Azure Active Directory (Azure AD) as the
identity provider.
Once the app service has the authenticated identity, your system needs to connect to backend ser vices as
the app :
Use managed identity. If managed identity isn't available, then use Key Vault.
The user identity doesn't need to flow further. Any additional security to reach backend services is
handled with the app service's identity.
1. Prerequisites
If you don't have an Azure subscription, create an Azure free account before you begin.
3. On your app's left menu, select Authentication , and then click Add identity provider .
4. In the Add an identity provider page, select Microsoft as the Identity provider to sign in Microsoft
and Azure AD identities.
5. For App registration > App registration type , select Create new app registration .
6. For App registration > Suppor ted account types , select Current tenant-single tenant .
7. In the App Ser vice authentication settings section, leave Authentication set to Require
authentication and Unauthenticated requests set to HTTP 302 Found redirect: recommended
for websites .
8. At the bottom of the Add an identity provider page, click Add to enable authentication for your web
app.
You now have an app that's secured by the App Service authentication and authorization.
NOTE
To allow accounts from other tenants, change the 'Issuer URL' to 'https://login.microsoftonline.com/common/v2.0'
by editing your 'Identity Provider' from the 'Authentication' blade.
4. To verify that access to your app is limited to users in your organization, start a browser in incognito or
private mode and go to https://<app-name>.azurewebsites.net .
5. You should be directed to a secured sign-in page, verifying that unauthenticated users aren't allowed
access to the site.
6. Sign in as a user in your organization to gain access to the site. You can also start up a new browser and
try to sign in by using a personal account to verify that users outside the organization don't have access.
5. Clean up resources
If you completed all the steps in this multipart tutorial, you created an app service, app service hosting plan, and
a storage account in a resource group. You also created an app registration in Azure Active Directory. When no
longer needed, delete these resources and app registration so that you don't continue to accrue charges.
In this tutorial, you learn how to:
Delete the Azure resources created while following the tutorial.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
This command might take several minutes to run.
Delete the app registration
From the portal menu, select Azure Active Director y > App registrations . Then select the application you
created.
Next steps
In this tutorial, you learned how to:
Configure authentication for the web app.
Limit access to the web app to users in your organization.
App service accesses storage
Configure an App Service app
5/18/2022 • 14 minutes to read • Edit Online
This article explains how to configure common settings for web apps, mobile back end, or API app.
NOTE
App settings can also be resolved from Key Vault using Key Vault references.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
2. In the app's left menu, select Configuration > Application settings .
By default, values for app settings are hidden in the portal for security. To see a hidden value of an app
setting, click its Value field. To see the hidden values of all app settings, click the Show values button.
3. To add a new app setting, click New application setting . To edit a setting, click the Edit button on the
right side.
4. In the dialog, you can stick the setting to the current slot.
App setting names can't contain periods ( . ). If an app setting contains a period, the period is replaced
with an underscore in the container.
NOTE
In a default Linux app service or a custom Linux container, any nested JSON key structure in the app setting name
like ApplicationInsights:InstrumentationKey needs to be configured in App Service as
ApplicationInsights__InstrumentationKey for the key name. In other words, any : should be replaced by
__ (double underscore).
5. When finished, click Update . Don't forget to click Save back in the Configuration page.
Edit app settings in bulk
Azure portal
Azure CLI
Azure PowerShell
Click the Advanced edit button. Edit the settings in the text area. When finished, click Update . Don't forget to
click Save back in the Configuration page.
App settings have the following JSON formatting:
[
{
"name": "<key-1>",
"value": "<value-1>",
"slotSetting": false
},
{
"name": "<key-2>",
"value": "<value-2>",
"slotSetting": false
},
...
]
For ASP.NET and ASP.NET Core developers, setting connection strings in App Service are like setting them in
<connectionStrings> in Web.config, but the values you set in App Service override the ones in Web.config. You
can keep development settings (for example, a database file) in Web.config and production secrets (for example,
SQL Database credentials) safely in App Service. The same code uses your development settings when you
debug locally, and it uses your production secrets when deployed to Azure.
For other language stacks, it's better to use app settings instead, because connection strings require special
formatting in the variable keys in order to access the values.
NOTE
There is one case where you may want to use connection strings instead of app settings for non-.NET languages: certain
Azure database types are backed up along with the app only if you configure a connection string for the database in your
App Service app. For more information, see What gets backed up. If you don't need this automated backup, then use app
settings.
At runtime, connection strings are available as environment variables, prefixed with the following connection
types:
SQLServer: SQLCONNSTR_
MySQL: MYSQLCONNSTR_
SQLAzure: SQLAZURECONNSTR_
Custom: CUSTOMCONNSTR_
PostgreSQL: POSTGRESQLCONNSTR_
For example, a MySQL connection string named connectionstring1 can be accessed as the environment variable
MYSQLCONNSTR_connectionString1 . For language-stack specific steps, see:
ASP.NET Core
Node.js
PHP
Python
Java
Ruby
Custom containers
Connection strings are always encrypted when stored (encrypted-at-rest).
NOTE
Connection strings can also be resolved from Key Vault using Key Vault references.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
Click the Advanced edit button. Edit the connection strings in the text area. When finished, click Update . Don't
forget to click Save back in the Configuration page.
Connection strings have the following JSON formatting:
[
{
"name": "name-1",
"value": "conn-string-1",
"type": "SQLServer",
"slotSetting": false
},
{
"name": "name-2",
"value": "conn-string-2",
"type": "PostgreSQL",
"slotSetting": false
},
...
]
Configure language stack settings
ASP.NET Core
Node.js
PHP
Python
Java
Ruby
In the Azure portal, search for and select App Ser vices , and then select your app. In the app's left menu, select
Configuration > General settings .
Here, you can configure some common settings for the app. Some settings require you to scale up to higher
pricing tiers.
Stack settings : The software stack to run the app, including the language and SDK versions.
For Linux apps, you can select the language runtime version and set an optional Star tup command or a
startup command file.
Platform settings : Lets you configure settings for the hosting platform, including:
FTP state : Allow only FTPS or disable FTP altogether.
Bitness : 32-bit or 64-bit. (Defaults to 32-bit for App Service created in the portal.)
WebSocket protocol : For ASP.NET SignalR or socket.io, for example.
Always On : Keeps the app loaded even when there's no traffic. When Always On is not turned on
(default), the app is unloaded after 20 minutes without any incoming requests. The unloaded app
can cause high latency for new requests because of its warm-up time. When Always On is turned
on, the front-end load balancer sends a GET request to the application root every five minutes. The
continuous ping prevents the app from being unloaded.
Always On is required for continuous WebJobs or for WebJobs that are triggered using a CRON
expression.
HTTP version : Set to 2.0 to enable support for HTTPS/2 protocol.
NOTE
Most modern browsers support HTTP/2 protocol over TLS only, while non-encrypted traffic continues to use
HTTP/1.1. To ensure that client browsers connect to your app with HTTP/2, secure your custom DNS name. For
more information, see Secure a custom DNS name with a TLS/SSL binding in Azure App Service.
ARR affinity : In a multi-instance deployment, ensure that the client is routed to the same instance for
the life of the session. You can set this option to Off for stateless applications.
Debugging : Enable remote debugging for ASP.NET, ASP.NET Core, or Node.js apps. This option turns off
automatically after 48 hours.
Incoming client cer tificates : require client certificates in mutual authentication.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
2. In the app's left menu, select Configuration > Default documents .
3. To add a default document, click New document . To remove a default document, click Delete to its right.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
2. In the app's left menu, select Configuration > Path mappings
3. Click New vir tual application or director y .
To map a virtual directory to a physical path, leave the Director y check box selected. Specify the
virtual directory and the corresponding relative (physical) path to the website root ( D:\home ).
To mark a virtual directory as a web application, clear the Director y check box.
4. Click OK .
Next steps
Environment variables and app settings reference
Configure a custom domain name in Azure App Service
Set up staging environments in Azure App Service
Secure a custom DNS name with a TLS/SSL binding in Azure App Service
Enable diagnostic logs
Scale an app in Azure App Service
Monitoring basics in Azure App Service
Change applicationHost.config settings with applicationHost.xdt
Tutorial: Connect to SQL Database from .NET App
Service without secrets using a managed identity
5/18/2022 • 12 minutes to read • Edit Online
App Service provides a highly scalable, self-patching web hosting service in Azure. It also provides a managed
identity for your app, which is a turn-key solution for securing access to Azure SQL Database and other Azure
services. Managed identities in App Service make your app more secure by eliminating secrets from your app,
such as credentials in the connection strings. In this tutorial, you'll add managed identity to the sample web app
you built in one of the following tutorials:
Tutorial: Build an ASP.NET app in Azure with Azure SQL Database
Tutorial: Build an ASP.NET Core and Azure SQL Database app in Azure App Service
When you're finished, your sample app will connect to SQL Database securely without the need of username
and passwords.
NOTE
The steps covered in this tutorial support the following versions:
.NET Framework 4.8 and above
.NET 6.0 and above
For guidance for Azure Database for MySQL or Azure Database for PostgreSQL in other language frameworks (Node.js,
Python, and Java), see Tutorial: Connect to Azure databases from App Service without secrets using a managed identity.
NOTE
Azure AD authentication is different from Integrated Windows authentication in on-premises Active Directory (AD DS).
AD DS and Azure AD use completely different authentication protocols. For more information, see Azure AD Domain
Services documentation.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
This article continues where you left off in either one of the following tutorials:
Tutorial: Build an ASP.NET app in Azure with SQL Database
Tutorial: Build an ASP.NET Core and SQL Database app in Azure App Service.
If you haven't already, follow one of the two tutorials first. Alternatively, you can adapt the steps for your own
.NET app with SQL Database.
To debug your app using SQL Database as the back end, make sure that you've allowed client connection from
your computer. If not, add the client IP by following the steps at Manage server-level IP firewall rules using the
Azure portal.
Prepare your environment for the Azure CLI.
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
TIP
To see the list of all user principal names in Azure AD, run az ad user list --query [].userPrincipalName .
3. Add this Azure AD user as an Active Directory admin using az sql server ad-admin create command in
the Cloud Shell. In the following command, replace <server-name> with the server name (without the
.database.windows.net suffix).
az sql server ad-admin create --resource-group myResourceGroup --server-name <server-name> --display-
name ADMIN --object-id $azureaduser
For more information on adding an Active Directory admin, see Provision an Azure Active Directory
administrator for your server
1. Visual Studio for Windows is integrated with Azure AD authentication. To enable development and
debugging in Visual Studio, add your Azure AD user in Visual Studio by selecting File > Account
Settings from the menu, and select Sign in or Add .
2. To set the Azure AD user for Azure service authentication, select Tools > Options from the menu, then
select Azure Ser vice Authentication > Account Selection . Select the Azure AD user you added and
select OK .
For more information about setting up your dev environment for Azure Active Directory authentication, see
Azure Identity client library for .NET.
You're now ready to develop and debug your app with the SQL Database as the back end, using Azure AD
authentication.
The steps you follow for your project depends on whether you're using Entity Framework (default for ASP.NET)
or Entity Framework Core (default for ASP.NET Core).
Entity Framework
Entity Framework Core
1. In Visual Studio, open the Package Manager Console and add the NuGet package Azure.Identity and
update Entity Framework:
2. In your DbContext object (in Models/MyDbContext.cs), add the following code to the default constructor.
var conn = (System.Data.SqlClient.SqlConnection)Database.Connection;
var credential = new Azure.Identity.DefaultAzureCredential();
var token = credential.GetToken(new Azure.Core.TokenRequestContext(new[] {
"https://database.windows.net/.default" }));
conn.AccessToken = token.Token;
This code uses Azure.Identity.DefaultAzureCredential to get a useable token for SQL Database from Azure
Active Directory and then adds it to the database connection. While you can customize
DefaultAzureCredential , by default it's already very versatile. When running in App Service, it uses app's
system-assigned managed identity. When running locally, it can get a token using the logged-in identity
of Visual Studio, Visual Studio Code, Azure CLI, and Azure PowerShell.
3. In Web.config, find the connection string called MyDbConnection and replace its connectionString value
with "server=tcp:<server-name>.database.windows.net;database=<db-name>;" . Replace <server-name> and
<db-name> with your server name and database name. This connection string is used by the default
constructor in Models/MyDbContext.cs.
That's every thing you need to connect to SQL Database. When debugging in Visual Studio, your code
uses the Azure AD user you configured in 2. Set up your dev environment. You'll set up SQL Database
later to allow connection from the managed identity of your App Service app.
4. Type Ctrl+F5 to run the app again. The same CRUD app in your browser is now connecting to the Azure
SQL Database directly, using Azure AD authentication. This setup lets you run database migrations from
Visual Studio.
NOTE
While the instructions in this section are for a system-assigned identity, a user-assigned identity can just as easily be used.
To do this. you would need the change the az webapp identity assign command to assign the desired user-assigned
identity. Then, when creating the SQL user, make sure to use the name of the user-assigned identity resource rather than
the site name.
NOTE
To enable managed identity for a deployment slot, add --slot <slot-name> and use the name of the slot in <slot-
name>.
NOTE
If you want, you can add the identity to an Azure AD group, then grant SQL Database access to the Azure AD group
instead of the identity. For example, the following commands add the managed identity from the previous step to a new
group called myAzureSQLDBAccessGroup:
1. In the Cloud Shell, sign in to SQL Database by using the SQLCMD command. Replace <server-name>
with your server name, <db-name> with the database name your app uses, and <aad-user-name> and
<aad-password> with your Azure AD user's credentials.
2. In the SQL prompt for the database you want, run the following commands to grant the permissions your
app needs. For example,
<identity-name> is the name of the managed identity in Azure AD. If the identity is system-assigned, the
name is always the same as the name of your App Service app. For a deployment slot, the name of its
system-assigned identity is <app-name>/slots/<slot-name>. To grant permissions for an Azure AD
group, use the group's display name instead (for example, myAzureSQLDBAccessGroup).
3. Type EXIT to return to the Cloud Shell prompt.
NOTE
The back-end services of managed identities also maintains a token cache that updates the token for a target
resource only when it expires. If you make a mistake configuring your SQL Database permissions and try to
modify the permissions after trying to get a token with your app, you don't actually get a new token with the
updated permissions until the cached token expires.
NOTE
Azure Active Directory and managed identities are not supported for on-premises SQL Server.
ASP.NET
ASP.NET Core
1. If you came from Tutorial: Build an ASP.NET app in Azure with SQL Database , publish your
changes in Visual Studio. In the Solution Explorer , right-click your DotNetAppSqlDb project and select
Publish .
IMPORTANT
Ensure that your app service name doesn't match with any existing App Registrations. This will lead to Principal ID
conflicts.
When the new webpage shows your to-do list, your app is connecting to the database using the managed
identity.
You should now be able to edit the to-do list as before.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
What you learned:
Enable managed identities
Grant SQL Database access to the managed identity
Configure Entity Framework to use Azure AD authentication with SQL Database
Connect to SQL Database from Visual Studio using Azure AD authentication
Map an existing custom DNS name to Azure App Service
Tutorial: Connect to Azure databases from App Service without secrets using a managed identity
Tutorial: Connect to Azure services that don't support managed identities (using Key Vault)
Tutorial: Isolate back-end communication with Virtual Network integration
Tutorial: Connect to Azure databases from App
Service without secrets using a managed identity
5/18/2022 • 25 minutes to read • Edit Online
App Service provides a highly scalable, self-patching web hosting service in Azure. It also provides a managed
identity for your app, which is a turn-key solution for securing access to Azure databases, including:
Azure SQL Database
Azure Database for MySQL
Azure Database for PostgreSQL
NOTE
This tutorial doesn't include guidance for Azure Cosmos DB, which supports Azure Active Directory authentication
differently. For information, see Cosmos DB documentation. For example: Use system-assigned managed identities to
access Azure Cosmos DB data.
Managed identities in App Service make your app more secure by eliminating secrets from your app, such as
credentials in the connection strings. This tutorial shows you how to connect to the above-mentioned databases
from App Service using managed identities.
What you will learn:
Configure an Azure AD user as an administrator for your Azure database.
Connect to your database as the Azure AD user.
Configure a system-assigned or user-assigned managed identity for an App Service app.
Grant database access to the managed identity.
Connect to the Azure database from your code (.NET Framework 4.8, .NET 6, Node.js, Python, Java) using a
managed identity.
Connect to the Azure database from your development environment using the Azure AD user.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Create an app in App Service based on .NET, Node.js, Python, or Java.
Create a database server with Azure SQL Database, Azure Database for MySQL, or Azure Database for
PostgreSQL.
You should be familiar with the standard connectivity pattern (with username and password) and be able to
connect successfully from your App Service app to your database of choice.
Prepare your environment for the Azure CLI.
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
NOTE
This user is different from the Microsoft account you used to sign up for your Azure subscription. It must be a user that
you created, imported, synced, or invited into Azure AD. For more information on allowed Azure AD users, see Azure AD
features and limitations in SQL Database.
1. If your Azure AD tenant doesn't have a user yet, create one by following the steps at Add or delete users
using Azure Active Directory.
2. Find the object ID of the Azure AD user using the az ad user list and replace <user-principal-name>.
The result is saved to a variable.
3. Add this Azure AD user as an Active Directory administrator using az sql server ad-admin create
command in the Cloud Shell. In the following command, replace <group-name> and <server-name>
with your own parameters.
For more information on adding an Active Directory administrator, see Provision an Azure Active
Directory administrator for your server
NOTE
To enable managed identity for a deployment slot, add --slot <slot-name> and use the name of the slot in
<slot-name>.
2. The identity needs to be granted permissions to access the database. In the Cloud Shell, sign in to your
database with the following command. Replace <server-name> with your server name, <database-
name> with the database name your app uses, and <aad-user-name> and <aad-password> with your
Azure AD user's credentials from 1. Grant database access to Azure AD user.
Azure SQL Database
Azure Database for MySQL
Azure Database for PostgreSQL
3. Run the following database commands to grant the permissions your app needs. For example,
System-assigned identity
User-assigned identity
.NET Framework
.NET 6
Node.js
Python
Java
1. In Visual Studio, open the Package Manager Console and add the NuGet packages you need:
Install-Package Azure.Identity
Install-Package System.Data.SqlClient
2. Connect to the Azure database by adding an access token. If you're using a user-assigned identity, make
sure you uncomment the applicable lines.
Azure SQL Database
Azure Database for MySQL
Azure Database for PostgreSQL
For a more detailed tutorial, see Tutorial: Connect to SQL Database from .NET App Service without secrets
using a managed identity.
1. Visual Studio for Windows is integrated with Azure AD authentication. To enable development and
debugging in Visual Studio, add your Azure AD user in Visual Studio by selecting File > Account
Settings from the menu, and select Sign in or Add .
2. To set the Azure AD user for Azure service authentication, select Tools > Options from the menu, then
select Azure Ser vice Authentication > Account Selection . Select the Azure AD user you added and
select OK .
For more information about setting up your dev environment for Azure Active Directory authentication, see
Azure Identity client library for .NET.
You're now ready to develop and debug your app with the SQL Database as the back end, using Azure AD
authentication.
The managed identity you're attempting to request a token for is not authorized to access the Azure database.
I made changes to App Service authentication or the associated app registration. Why do I still get the old token?
The back-end services of managed identities also maintain a token cache that updates the token for a target
resource only when it expires. If you modify the configuration after trying to get a token with your app, you
don't actually get a new token with the updated permissions until the cached token expires. The best way to
work around this is to test your changes with a new InPrivate (Edge)/private (Safari)/Incognito (Chrome)
window. That way, you're sure to start from a new authenticated session.
How do I add the managed identity to an Azure AD group?
If you want, you can add the identity to an Azure AD group, then grant access to the Azure AD group instead of
the identity. For example, the following commands add the managed identity from the previous step to a new
group called myAzureSQLDBAccessGroup:
To grant database permissions for an Azure AD group, see documentation for the respective database type.
I get the error mysql: unknown option '--enable-cleartext-plugin' .
If you're using a MariaDB client, the --enable-cleartext-plugin option isn't required.
I get the error SSL connection is required. Please specify SSL options and retry .
Connecting to the Azure database requires additional settings and is beyond the scope of this tutorial. For more
information, see one of the following links:
Configure TLS connectivity in Azure Database for PostgreSQL - Single Server Configure SSL connectivity in your
application to securely connect to Azure Database for MySQL
Next steps
What you learned:
Configure an Azure AD user as an administrator for your Azure database.
Connect to your database as the Azure AD user.
Configure a system-assigned or user-assigned managed identity for an App Service app.
Grant database access to the managed identity.
Connect to the Azure database from your code (.NET Framework 4.8, .NET 6, Node.js, Python, Java) using a
managed identity.
Connect to the Azure database from your development environment using the Azure AD user.
How to use managed identities for App Service and Azure Functions
Tutorial: Connect to SQL Database from .NET App Service without secrets using a managed identity
Tutorial: Connect to Azure services that don't support managed identities (using Key Vault)
Tutorial: Isolate back-end communication with Virtual Network integration
Tutorial: Access Azure services from a .NET web app
5/18/2022 • 9 minutes to read • Edit Online
Learn how to access Azure services, such as Azure Storage, from a web app (not a signed-in user) running on
Azure App Service by using managed identities. This tutorial demonstrates connecting to Azure Storage as an
example.
Any service that supports managed identity (B in the following image) can be securely accessed using this
tutorial:
Azure Storage
Azure SQL Database
Azure Key Vault
You want to add secure access to Azure services (Azure Storage, Azure SQL Database, Azure Key Vault, or other
services) from your web app. You could use a shared key, but then you have to worry about operational security
of who can create, deploy, and manage the secret. It's also possible that the key could be checked into GitHub,
which hackers know how to scan for. A safer way to give your web app access to data is to use managed
identities.
A managed identity from Azure Active Directory (Azure AD) allows App Service to access resources through
role-based access control (RBAC), without requiring app credentials. After assigning a managed identity to your
web app, Azure takes care of the creation and distribution of a certificate. People don't have to worry about
managing secrets or app credentials.
In this tutorial, you learn how to:
Create a system-assigned managed identity on a web app.
Create a storage account and an Azure Blob Storage container.
Access storage from a web app by using managed identities.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
A web application running on Azure App Service that has the App Service authentication/authorization
module enabled.
To create a general-purpose v2 storage account in the Azure portal, follow these steps.
1. On the Azure portal menu, select All ser vices . In the list of resources, enter Storage Accounts . As you
begin typing, the list filters based on your input. Select Storage Accounts .
2. In the Storage Accounts window that appears, select Create .
3. Select the subscription in which to create the storage account.
4. Under the Resource group field, select the resource group that contains your web app from the drop-
down menu.
5. Next, enter a name for your storage account. The name you choose must be unique across Azure. The
name also must be between 3 and 24 characters in length and can include numbers and lowercase letters
only.
6. Select a location (region) for your storage account, or use the default value.
7. Leave these fields set to their default values:
F IEL D VA L UE
Performance Standard
8. Select Review + Create to review your storage account settings and create the account.
9. Select Create .
To create a Blob Storage container in Azure Storage, follow these steps.
1. Go to your new storage account in the Azure portal.
2. In the left menu for the storage account, scroll to the Data storage section, and then select Containers .
3. Select the + Container button.
4. Type a name for your new container. The container name must be lowercase, must start with a letter or
number, and can include only letters, numbers, and the dash (-) character.
5. Set the level of public access to the container. The default level is Private (no anonymous access) .
6. Select OK to create the container.
Portal
PowerShell
Azure CLI
In the Azure portal, go into your storage account to grant your web app access. Select Access control (IAM) in
the left pane, and then select Role assignments . You'll see a list of who has access to the storage account. Now
you want to add a role assignment to a robot, the app service that needs access to the storage account. Select
Add > Add role assignment to open the Add role assignment page.
Assign the Storage Blob Data Contributor role to the App Ser vice at subscription scope. For detailed steps,
see Assign Azure roles using the Azure portal.
Your web app now has access to your storage account.
Install-Package Azure.Storage.Blobs
Install-Package Azure.Identity
.NET example
using System;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using System.IO;
using Azure.Identity;
static public async Task UploadBlob(string accountName, string containerName, string blobName, string
blobContents)
{
// Construct the blob container endpoint from the arguments.
string containerEndpoint = string.Format("https://{0}.blob.core.windows.net/{1}",
accountName,
containerName);
// Get a credential and create a client object for the blob container.
BlobContainerClient containerClient = new BlobContainerClient(new Uri(containerEndpoint),
new DefaultAzureCredential());
try
{
// Create the container if it does not exist.
await containerClient.CreateIfNotExistsAsync();
Clean up resources
If you're finished with this tutorial and no longer need the web app or associated resources, clean up the
resources you created.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
This command might take several minutes to run.
Delete the app registration
From the portal menu, select Azure Active Director y > App registrations . Then select the application you
created.
Next steps
In this tutorial, you learned how to:
Create a system-assigned managed identity.
Create a storage account and Blob Storage container.
Access storage from a web app by using managed identities.
Tutorial: Isolate back-end communication with Virtual Network integration
App Service accesses Microsoft Graph on behalf of the user
Map an existing custom DNS name to Azure App Service
Tutorial: Access Azure services from a JavaScript
web app
5/18/2022 • 9 minutes to read • Edit Online
Learn how to access Azure services, such as Azure Storage, from a web app (not a signed-in user) running on
Azure App Service by using managed identities. This tutorial demonstrates connecting to Azure Storage as an
example.
Any service that supports managed identity (B in the following image) can be securely accessed using this
tutorial:
Azure Storage
Azure SQL Database
Azure Key Vault
You want to add secure access to Azure services (Azure Storage, Azure SQL Database, Azure Key Vault, or other
services) from your web app. You could use a shared key, but then you have to worry about operational security
of who can create, deploy, and manage the secret. It's also possible that the key could be checked into GitHub,
which hackers know how to scan for. A safer way to give your web app access to data is to use managed
identities.
A managed identity from Azure Active Directory (Azure AD) allows App Service to access resources through
role-based access control (RBAC), without requiring app credentials. After assigning a managed identity to your
web app, Azure takes care of the creation and distribution of a certificate. People don't have to worry about
managing secrets or app credentials.
In this tutorial, you learn how to:
Create a system-assigned managed identity on a web app.
Create a storage account and an Azure Blob Storage container.
Access storage from a web app by using managed identities.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
A web application running on Azure App Service that has the App Service authentication/authorization
module enabled.
This step creates a new object ID, different than the app ID created in the Authentication/Authorization pane.
Copy the object ID of the system-assigned managed identity. You'll need it later.
Portal
PowerShell
Azure CLI
To create a general-purpose v2 storage account in the Azure portal, follow these steps.
1. On the Azure portal menu, select All ser vices . In the list of resources, enter Storage Accounts . As you
begin typing, the list filters based on your input. Select Storage Accounts .
2. In the Storage Accounts window that appears, select Create .
3. Select the subscription in which to create the storage account.
4. Under the Resource group field, select the resource group that contains your web app from the drop-
down menu.
5. Next, enter a name for your storage account. The name you choose must be unique across Azure. The
name also must be between 3 and 24 characters in length and can include numbers and lowercase letters
only.
6. Select a location (region) for your storage account, or use the default value.
7. Leave these fields set to their default values:
F IEL D VA L UE
Performance Standard
8. Select Review + Create to review your storage account settings and create the account.
9. Select Create .
To create a Blob Storage container in Azure Storage, follow these steps.
1. Go to your new storage account in the Azure portal.
2. In the left menu for the storage account, scroll to the Data storage section, and then select Containers .
3. Select the + Container button.
4. Type a name for your new container. The container name must be lowercase, must start with a letter or
number, and can include only letters, numbers, and the dash (-) character.
5. Set the level of public access to the container. The default level is Private (no anonymous access) .
6. Select OK to create the container.
In the Azure portal, go into your storage account to grant your web app access. Select Access control (IAM) in
the left pane, and then select Role assignments . You'll see a list of who has access to the storage account. Now
you want to add a role assignment to a robot, the app service that needs access to the storage account. Select
Add > Add role assignment to open the Add role assignment page.
Assign the Storage Blob Data Contributor role to the App Ser vice at subscription scope. For detailed steps,
see Assign Azure roles using the Azure portal.
Your web app now has access to your storage account.
JavaScript example
const { DefaultAzureCredential } = require("@azure/identity");
const { BlobServiceClient } = require("@azure/storage-blob");
const defaultAzureCredential = new DefaultAzureCredential();
try {
await containerClient.createIfNotExists();
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const uploadBlobResponse = await blockBlobClient.upload(blobContents, blobContents.length);
console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId);
} catch (error) {
console.log(error);
}
}
Clean up resources
If you're finished with this tutorial and no longer need the web app or associated resources, clean up the
resources you created.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
This command might take several minutes to run.
Delete the app registration
From the portal menu, select Azure Active Director y > App registrations . Then select the application you
created.
Next steps
In this tutorial, you learned how to:
Create a system-assigned managed identity.
Create a storage account and Blob Storage container.
Access storage from a web app by using managed identities.
Tutorial: Isolate back-end communication with Virtual Network integration
App Service accesses Microsoft Graph on behalf of the user
Map an existing custom DNS name to Azure App Service
Tutorial: Access Microsoft Graph from a secured
.NET app as the app
5/18/2022 • 5 minutes to read • Edit Online
Learn how to access Microsoft Graph from a web app running on Azure App Service.
You want to call Microsoft Graph for the web app. A safe way to give your web app access to data is to use a
system-assigned managed identity. A managed identity from Azure Active Directory allows App Service to
access resources through role-based access control (RBAC), without requiring app credentials. After assigning a
managed identity to your web app, Azure takes care of the creation and distribution of a certificate. You don't
have to worry about managing secrets or app credentials.
In this tutorial, you learn how to:
Create a system-assigned managed identity on a web app.
Add Microsoft Graph API permissions to a managed identity.
Call Microsoft Graph from a web app by using managed identities.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
A web application running on Azure App Service that has the App Service authentication/authorization
module enabled.
# Your tenant ID (in the Azure portal, under Azure Active Directory > Overview).
$TenantID="<tenant-id>"
$resourceGroup = "securewebappresourcegroup"
$webAppName="SecureWebApp-20201102125811"
# Check the Microsoft Graph documentation for the permission you need for the operation.
$PermissionName = "User.Read.All"
2. After executing the script, you can verify in the Azure portal that the requested API permissions are
assigned to the managed identity.
3. Go to Azure Active Director y , and then select Enterprise applications . This pane displays all the
service principals in your tenant. In Managed Identities , select the service principal for the managed
identity.
If you're following this tutorial, there are two service principals with the same display name
(SecureWebApp2020094113531, for example). The service principal that has a Homepage URL
represents the web app in your tenant. The service principal that appears in Managed Identities should
not have a Homepage URL listed and the Object ID should match the object ID value of the managed
identity in the previous step.
4. Select the service principal for the managed identity.
5. In Over view , select Permissions , and you'll see the added permissions for Microsoft Graph.
Call Microsoft Graph
The ChainedTokenCredential, ManagedIdentityCredential, and EnvironmentCredential classes are used to get a
token credential for your code to authorize requests to Microsoft Graph. Create an instance of the
ChainedTokenCredential class, which uses the managed identity in the App Service environment or the
development environment variables to fetch tokens and attach them to the service client. The following code
example gets the authenticated token credential and uses it to create a service client object, which gets the users
in the group.
To see this code as part of a sample application, see the:
Sample on GitHub.
Install the Microsoft.Identity.Web.MicrosoftGraph client library package
Install the Microsoft.Identity.Web.MicrosoftGraph NuGet package in your project by using the .NET Core
command-line interface or the Package Manager Console in Visual Studio.
.NET Core command-line
Open a command line, and switch to the directory that contains your project file.
Run the install commands.
Install-Package Microsoft.Identity.Web.MicrosoftGraph
.NET Example
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Azure.Identity;
using Microsoft.Graph.Core;
using System.Net.Http.Headers;
...
return Task.CompletedTask;
}));
// MSGraphUser is a DTO class being used to hold User information from the graph service client call
List<MSGraphUser> msGraphUsers = new List<MSGraphUser>();
try
{
var users =await graphServiceClient.Users.Request().GetAsync();
foreach(var u in users)
{
MSGraphUser user = new MSGraphUser();
user.userPrincipalName = u.UserPrincipalName;
user.displayName = u.DisplayName;
user.mail = u.Mail;
user.jobTitle = u.JobTitle;
msGraphUsers.Add(user);
}
}
catch(Exception ex)
{
string msg = ex.Message;
}
Users = msGraphUsers;
}
Clean up resources
If you're finished with this tutorial and no longer need the web app or associated resources, clean up the
resources you created.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
Learn how to access Microsoft Graph from a web app running on Azure App Service.
You want to call Microsoft Graph for the web app. A safe way to give your web app access to data is to use a
system-assigned managed identity. A managed identity from Azure Active Directory allows App Service to
access resources through role-based access control (RBAC), without requiring app credentials. After assigning a
managed identity to your web app, Azure takes care of the creation and distribution of a certificate. You don't
have to worry about managing secrets or app credentials.
In this tutorial, you learn how to:
Create a system-assigned managed identity on a web app.
Add Microsoft Graph API permissions to a managed identity.
Call Microsoft Graph from a web app by using managed identities.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
A web application running on Azure App Service that has the App Service authentication/authorization
module enabled.
# Your tenant ID (in the Azure portal, under Azure Active Directory > Overview).
$TenantID="<tenant-id>"
$resourceGroup = "securewebappresourcegroup"
$webAppName="SecureWebApp-20201102125811"
# Check the Microsoft Graph documentation for the permission you need for the operation.
$PermissionName = "User.Read.All"
2. After executing the script, you can verify in the Azure portal that the requested API permissions are
assigned to the managed identity.
3. Go to Azure Active Director y , and then select Enterprise applications . This pane displays all the
service principals in your tenant. In Managed Identities , select the service principal for the managed
identity.
If you're following this tutorial, there are two service principals with the same display name
(SecureWebApp2020094113531, for example). The service principal that has a Homepage URL
represents the web app in your tenant. The service principal that appears in Managed Identities should
not have a Homepage URL listed and the Object ID should match the object ID value of the managed
identity in the previous step.
4. Select the service principal for the managed identity.
5. In Over view , select Permissions , and you'll see the added permissions for Microsoft Graph.
Call Microsoft Graph with Node.js
Your web app now has the required permissions and also adds Microsoft Graph's client ID to the login
parameters.
The DefaultAzureCredential class from @azure/identity package is used to get a token credential for your code
to authorize requests to Azure Storage. Create an instance of the DefaultAzureCredential class, which uses the
managed identity to fetch tokens and attach them to the service client. The following code example gets the
authenticated token credential and uses it to create a service client object, which gets the users in the group.
To see this code as part of a sample application, see the:
sample on GitHub.
NOTE
The @azure/identity package isn't required in your web app for basic authentication/authorization or to authenticate
requests with Microsoft Graph. It's possible to securely call downstream APIs with only the App Service
authentication/authorization module enabled.
However, the App Service authentication/authorization is designed for more basic authentication scenarios. For more
complex scenarios (handling custom claims, for example), you need the @azure/identity package. There's a little more
setup and configuration work in the beginning, but the @azure/identity package can run alongside the App Service
authentication/authorization module. Later, when your web app needs to handle more complex scenarios, you can disable
the App Service authentication/authorization module and @azure/identity will already be a part of your app.
// graphController.js
try {
// get app's access token scoped to Microsoft Graph
const tokenResponse = await defaultAzureCredential.getToken("https://graph.microsoft.com/.default");
The previous code relies on the following getAuthenticatedClient function to return Microsoft Graph client.
// utils/graphHelper.js
return client;
}
Clean up resources
If you're finished with this tutorial and no longer need the web app or associated resources, clean up the
resources you created.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
Azure App Service can use managed identities to connect to back-end services without a connection string,
which eliminates connection secrets to manage and keeps your back-end connectivity secure in a production
environment. For back-end services that don't support managed identities and still requires connection secrets,
you can use Key Vault to manage connection secrets. This tutorial uses Cognitive Services as an example to
show you how it's done in practice. When you're finished, you have an app that makes programmatic calls to
Cognitive Services, without storing any connection secrets inside App Service.
Sample application
TIP
Azure Cognitive Services do support authentication through managed identities, but this tutorial uses the subscription
key authentication to demonstrate how you could connect to an Azure service that doesn't support managed identities
from App Services.
Prerequisites
Prepare your environment for the Azure CLI.
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
2. Create a Cognitive Services resource. Replace <cs-resource-name> with a unique name of your choice.
NOTE
--sku F0 creates a free tier Cognitive Services resource. Each subscription is limited to a quota of one free-tier
TextAnalytics resource. If you're already over the quota, use --sku S instead.
az webapp up --sku F1 --resource-group $groupName --name $appName --plan $appName --location $region
2. In the browser, navigate to your deploy app at <app-name>.azurewebsites.net and try out the language
detector with strings in various languages.
If you look at the application code, you may notice the debug output for the detection results in the same
font color as the background. You can see it by trying to highlight the white space directly below the
result.
az keyvault create --resource-group $groupName --name $vaultName --location $region --sku standard --
enable-rbac-authorization
The --enable-rbac-authorization parameter sets Azure role-based access control (RBAC) as the
permission model. This setting by default invalidates all access policies permissions.
2. Give yourself the Key Vault Secrets Officer RBAC role for the vault.
3. Enable the system-assigned managed identity for your app, and give it the Key Vault Secrets User RBAC
role for the vault.
az webapp identity assign --resource-group $groupName --name $appName --scope $vaultResourceId --role
"Key Vault Secrets User"
4. Add the Cognitive Services resource name and subscription key as secrets to the vault, and save their IDs
as environment variables for the next step.
5. Previously, you set the secrets as app settings CS_ACCOUNT_NAME and CS_ACCOUNT_KEY in your app. Now, set
them as key vault references instead.
6. In the browser, navigate to <app-name>.azurewebsites.net again. If you get detection results back, then
you're connecting to the Cognitive Services endpoint with key vault references.
Congratulations, your app is now connecting to Cognitive Services using secrets kept in your key vault, without
any changes to your application code.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
Tutorial: Isolate back-end communication with Virtual Network integration
Integrate your app with an Azure virtual network
App Service networking features
Tutorial: Secure Cognitive Service connection from
JavaScript App Service using Key Vault
5/18/2022 • 5 minutes to read • Edit Online
Azure App Service can use managed identities to connect to back-end services without a connection string,
which eliminates connection secrets to manage and keeps your back-end connectivity secure in a production
environment. For back-end services that don't support managed identities and still requires connection secrets,
you can use Key Vault to manage connection secrets. This tutorial uses Cognitive Services as an example to
show you how it's done in practice. When you're finished, you have an app that makes programmatic calls to
Cognitive Services, without storing any connection secrets inside App Service.
Sample application
TIP
Azure Cognitive Services do support authentication through managed identities, but this tutorial uses the subscription
key authentication to demonstrate how you could connect to an Azure service that doesn't support managed identities
from App Services.
Prerequisites
Prepare your environment for the Azure CLI.
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
2. Create a Cognitive Services resource. Replace <cs-resource-name> with a unique name of your choice.
NOTE
--sku F0 creates a free tier Cognitive Services resource. Each subscription is limited to a quota of one free-tier
TextAnalytics resource. If you're already over the quota, use --sku S instead.
az appservice plan create --resource-group $groupName --name $appName --sku FREE --location $region --is-
linux
az webapp create --resource-group $groupName --plan $appName --name $appName --runtime "node|14-lts"
az webapp config appsettings set --resource-group $groupName --name $appName --settings
SCM_DO_BUILD_DURING_DEPLOYMENT=true
az webapp deployment source config-zip --resource-group $groupName --name $appName --src ./default.zip
2. In the browser, navigate to your deploy app at <app-name>.azurewebsites.net and try out the language
detector with strings in various languages.
If you look at the application code, you may notice the debug output for the detection results in the same
font color as the background. You can see it by trying to highlight the white space directly below the
result.
Secure back-end connectivity
At the moment, connection secrets are stored as app settings in your App Service app. This approach is already
securing connection secrets from your application codebase. However, any contributor who can manage your
app can also see the app settings. In this step, you move the connection secrets to a key vault, and lock down
access so that only you can manage it and only the App Service app can read it using its managed identity.
1. Create a key vault. Replace <vault-name> with a unique name.
az keyvault create --resource-group $groupName --name $vaultName --location $region --sku standard --
enable-rbac-authorization
The --enable-rbac-authorization parameter sets Azure role-based access control (RBAC) as the
permission model. This setting by default invalidates all access policies permissions.
2. Give yourself the Key Vault Secrets Officer RBAC role for the vault.
3. Enable the system-assigned managed identity for your app, and give it the Key Vault Secrets User RBAC
role for the vault.
az webapp identity assign --resource-group $groupName --name $appName --scope $vaultResourceId --role
"Key Vault Secrets User"
4. Add the Cognitive Services resource name and subscription key as secrets to the vault, and save their IDs
as environment variables for the next step.
5. Previously, you set the secrets as app settings CS_ACCOUNT_NAME and CS_ACCOUNT_KEY in your app. Now, set
them as key vault references instead.
6. In the browser, navigate to <app-name>.azurewebsites.net again. If you get detection results back, then
you're connecting to the Cognitive Services endpoint with key vault references.
Congratulations, your app is now connecting to Cognitive Services using secrets kept in your key vault, without
any changes to your application code.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
Tutorial: Isolate back-end communication with Virtual Network integration
Integrate your app with an Azure virtual network
App Service networking features
Tutorial: Secure Cognitive Service connection from
PHP App Service using Key Vault
5/18/2022 • 5 minutes to read • Edit Online
Azure App Service can use managed identities to connect to back-end services without a connection string,
which eliminates connection secrets to manage and keeps your back-end connectivity secure in a production
environment. For back-end services that don't support managed identities and still requires connection secrets,
you can use Key Vault to manage connection secrets. This tutorial uses Cognitive Services as an example to
show you how it's done in practice. When you're finished, you have an app that makes programmatic calls to
Cognitive Services, without storing any connection secrets inside App Service.
Sample application
TIP
Azure Cognitive Services do support authentication through managed identities, but this tutorial uses the subscription
key authentication to demonstrate how you could connect to an Azure service that doesn't support managed identities
from App Services.
Prerequisites
Prepare your environment for the Azure CLI.
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
2. Create a Cognitive Services resource. Replace <cs-resource-name> with a unique name of your choice.
NOTE
--sku F0 creates a free tier Cognitive Services resource. Each subscription is limited to a quota of one free-tier
TextAnalytics resource. If you're already over the quota, use --sku S instead.
az appservice plan create --resource-group $groupName --name $appName --sku FREE --location $region
az webapp create --resource-group $groupName --plan $appName --name $appName
az webapp deployment source config-zip --resource-group $groupName --name $appName --src ./default.zip
2. In the browser, navigate to your deploy app at <app-name>.azurewebsites.net and try out the language
detector with strings in various languages.
If you look at the application code, you may notice the debug output for the detection results in the same
font color as the background. You can see it by trying to highlight the white space directly below the
result.
az keyvault create --resource-group $groupName --name $vaultName --location $region --sku standard --
enable-rbac-authorization
The --enable-rbac-authorization parameter sets Azure role-based access control (RBAC) as the
permission model. This setting by default invalidates all access policies permissions.
2. Give yourself the Key Vault Secrets Officer RBAC role for the vault.
3. Enable the system-assigned managed identity for your app, and give it the Key Vault Secrets User RBAC
role for the vault.
az webapp identity assign --resource-group $groupName --name $appName --scope $vaultResourceId --role
"Key Vault Secrets User"
4. Add the Cognitive Services resource name and subscription key as secrets to the vault, and save their IDs
as environment variables for the next step.
5. Previously, you set the secrets as app settings CS_ACCOUNT_NAME and CS_ACCOUNT_KEY in your app. Now, set
them as key vault references instead.
6. In the browser, navigate to <app-name>.azurewebsites.net again. If you get detection results back, then
you're connecting to the Cognitive Services endpoint with key vault references.
Congratulations, your app is now connecting to Cognitive Services using secrets kept in your key vault, without
any changes to your application code.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
Tutorial: Isolate back-end communication with Virtual Network integration
Integrate your app with an Azure virtual network
App Service networking features
Tutorial: Add user authentication to your web app
running on Azure App Service
5/18/2022 • 4 minutes to read • Edit Online
Learn how to enable authentication for your web app running on Azure App Service and limit access to users in
your organization.
In this tutorial, you learn how to:
Configure authentication for the web app.
Limit access to the web app to users in your organization by using Azure Active Directory (Azure AD) as the
identity provider.
Once the app service has the authenticated identity, your system needs to connect to backend ser vices as
the user :
A database example is a SQL database which imposes its own security for that identity on tables
A storage example is Blob Storage which imposes its own security for that identity on containers and
blobs
A user needs access to Microsoft Graph to access their own email.
1. Prerequisites
If you don't have an Azure subscription, create an Azure free account before you begin.
3. On your app's left menu, select Authentication , and then click Add identity provider .
4. In the Add an identity provider page, select Microsoft as the Identity provider to sign in Microsoft
and Azure AD identities.
5. For App registration > App registration type , select Create new app registration .
6. For App registration > Suppor ted account types , select Current tenant-single tenant .
7. In the App Ser vice authentication settings section, leave Authentication set to Require
authentication and Unauthenticated requests set to HTTP 302 Found redirect: recommended
for websites .
8. At the bottom of the Add an identity provider page, click Add to enable authentication for your web
app.
You now have an app that's secured by the App Service authentication and authorization.
NOTE
To allow accounts from other tenants, change the 'Issuer URL' to 'https://login.microsoftonline.com/common/v2.0'
by editing your 'Identity Provider' from the 'Authentication' blade.
4. To verify that access to your app is limited to users in your organization, start a browser in incognito or
private mode and go to https://<app-name>.azurewebsites.net .
5. You should be directed to a secured sign-in page, verifying that unauthenticated users aren't allowed
access to the site.
6. Sign in as a user in your organization to gain access to the site. You can also start up a new browser and
try to sign in by using a personal account to verify that users outside the organization don't have access.
5. Clean up resources
If you completed all the steps in this multipart tutorial, you created an app service, app service hosting plan, and
a storage account in a resource group. You also created an app registration in Azure Active Directory. When no
longer needed, delete these resources and app registration so that you don't continue to accrue charges.
In this tutorial, you learn how to:
Delete the Azure resources created while following the tutorial.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
This command might take several minutes to run.
Delete the app registration
From the portal menu, select Azure Active Director y > App registrations . Then select the application you
created.
Next steps
In this tutorial, you learned how to:
Configure authentication for the web app.
Limit access to the web app to users in your organization.
App service accesses Graph
Tutorial: Access Microsoft Graph from a secured
.NET app as the user
5/18/2022 • 7 minutes to read • Edit Online
Learn how to access Microsoft Graph from a web app running on Azure App Service.
You want to add access to Microsoft Graph from your web app and perform some action as the signed-in user.
This section describes how to grant delegated permissions to the web app and get the signed-in user's profile
information from Azure Active Directory (Azure AD).
In this tutorial, you learn how to:
Grant delegated permissions to a web app.
Call Microsoft Graph from a web app for a signed-in user.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
A web application running on Azure App Service that has the App Service authentication/authorization
module enabled.
IMPORTANT
If you don't configure App Service to return a usable access token, you receive a
CompactToken parsing failed with error code: 80049217 error when you call Microsoft Graph APIs in your code.
"identityProviders": {
"azureActiveDirectory": {
"enabled": true,
"login": {
"loginParameters":[
"response_type=code id_token",
"scope=openid offline_access profile https://graph.microsoft.com/User.Read"
]
}
}
}
},
5. Save your settings by selecting PUT . This setting can take several minutes to take effect. Your web app is
now configured to access Microsoft Graph with a proper access token. If you don't, Microsoft Graph
returns an error saying that the format of the compact token is incorrect.
NOTE
The Microsoft.Identity.Web library isn't required in your web app for basic authentication/authorization or to authenticate
requests with Microsoft Graph. It's possible to securely call downstream APIs with only the App Service
authentication/authorization module enabled.
However, the App Service authentication/authorization is designed for more basic authentication scenarios. For more
complex scenarios (handling custom claims, for example), you need the Microsoft.Identity.Web library or Microsoft
Authentication Library. There's a little more setup and configuration work in the beginning, but the Microsoft.Identity.Web
library can run alongside the App Service authentication/authorization module. Later, when your web app needs to
handle more complex scenarios, you can disable the App Service authentication/authorization module and
Microsoft.Identity.Web will already be a part of your app.
Install-Package Microsoft.Identity.Web.MicrosoftGraph
Install-Package Microsoft.Identity.Web
Startup.cs
In the Startup.cs file, the AddMicrosoftIdentityWebApp method adds Microsoft.Identity.Web to your web app. The
AddMicrosoftGraph method adds Microsoft Graph support.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
services.AddRazorPages();
}
}
appsettings.json
AzureAd specifies the configuration for the Microsoft.Identity.Web library. In the Azure portal, select Azure
Active Director y from the portal menu and then select App registrations . Select the app registration created
when you enabled the App Service authentication/authorization module. (The app registration should have the
same name as your web app.) You can find the tenant ID and client ID in the app registration overview page. The
domain name can be found in the Azure AD overview page for your tenant.
Graph specifies the Microsoft Graph endpoint and the initial scopes needed by the app.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "fourthcoffeetest.onmicrosoft.com",
"TenantId": "[tenant-id]",
"ClientId": "[client-id]",
// To call an API
"ClientSecret": "[secret-from-portal]", // Not required by this scenario
"CallbackPath": "/signin-oidc"
},
"Graph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
// Index.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Graph;
using System.IO;
using Microsoft.Identity.Web;
using Microsoft.Extensions.Logging;
Clean up resources
If you completed all the steps in this multipart tutorial, you created an app service, app service hosting plan, and
a storage account in a resource group. You also created an app registration in Azure Active Directory. When no
longer needed, delete these resources and app registration so that you don't continue to accrue charges.
In this tutorial, you learn how to:
Delete the Azure resources created while following the tutorial.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
Next steps
In this tutorial, you learned how to:
Grant delegated permissions to a web app.
Call Microsoft Graph from a web app for a signed-in user.
App service accesses Microsoft Graph as the app
Tutorial: Access Microsoft Graph from a secured
JavaScript app as the user
5/18/2022 • 5 minutes to read • Edit Online
Learn how to access Microsoft Graph from a web app running on Azure App Service.
You want to add access to Microsoft Graph from your web app and perform some action as the signed-in user.
This section describes how to grant delegated permissions to the web app and get the signed-in user's profile
information from Azure Active Directory (Azure AD).
In this tutorial, you learn how to:
Grant delegated permissions to a web app.
Call Microsoft Graph from a web app for a signed-in user.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
A web application running on Azure App Service that has the App Service authentication/authorization
module enabled.
IMPORTANT
If you don't configure App Service to return a usable access token, you receive a
CompactToken parsing failed with error code: 80049217 error when you call Microsoft Graph APIs in your code.
"identityProviders": {
"azureActiveDirectory": {
"enabled": true,
"login": {
"loginParameters":[
"response_type=code id_token",
"scope=openid offline_access profile https://graph.microsoft.com/User.Read"
]
}
}
}
},
5. Save your settings by selecting PUT . This setting can take several minutes to take effect. Your web app is
now configured to access Microsoft Graph with a proper access token. If you don't, Microsoft Graph
returns an error saying that the format of the compact token is incorrect.
// controllers/graphController.js
// get the name of the app service instance from environment variables
const appServiceName = process.env.WEBSITE_SITE_NAME;
try {
// get user's access token scoped to Microsoft Graph from session
// use token to create Graph client
const graphClient =
graphHelper.getAuthenticatedClient(req.session.protectedResources["graphAPI"].accessToken);
The previous code relies on the following getAuthenticatedClient function to return Microsoft Graph client.
// utils/graphHelper.js
return client;
}
Clean up resources
If you completed all the steps in this multipart tutorial, you created an app service, app service hosting plan, and
a storage account in a resource group. You also created an app registration in Azure Active Directory. When no
longer needed, delete these resources and app registration so that you don't continue to accrue charges.
In this tutorial, you learn how to:
Delete the Azure resources created while following the tutorial.
Delete the resource group
In the Azure portal, select Resource groups from the portal menu and select the resource group that contains
your app service and app service plan.
Select Delete resource group to delete the resource group and all the resources.
Next steps
In this tutorial, you learned how to:
Grant delegated permissions to a web app.
Call Microsoft Graph from a web app for a signed-in user.
App service accesses Microsoft Graph as the app
Tutorial: Authenticate and authorize users end-to-
end in Azure App Service
5/18/2022 • 17 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. In addition, App Service has
built-in support for user authentication and authorization. This tutorial shows how to secure your apps with App
Service authentication and authorization. It uses a ASP.NET Core app with an Angular.js front end as an example.
App Service authentication and authorization support all language runtimes, and you can learn how to apply it
to your preferred language by following the tutorial.
Azure App Service provides a highly scalable, self-patching web hosting service using the Linux operating
system. In addition, App Service has built-in support for user authentication and authorization. This tutorial
shows how to secure your apps with App Service authentication and authorization. It uses an ASP.NET Core app
with an Angular.js front end as an example. App Service authentication and authorization support all language
runtimes, and you can learn how to apply it to your preferred language by following the tutorial.
It also shows you how to secure a multi-tiered app, by accessing a secured back-end API on behalf of the
authenticated user, both from server code and from browser code.
These are only some of the possible authentication and authorization scenarios in App Service.
Here's a more comprehensive list of things you learn in the tutorial:
Enable built-in authentication and authorization
Secure apps against unauthenticated requests
Use Azure Active Directory as the identity provider
Access a remote app on behalf of the signed-in user
Secure service-to-service calls with token authentication
Use access tokens from server code
Use access tokens from client (browser) code
You can follow the steps in this tutorial on macOS, Linux, Windows.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial:
Install Git
Install the latest .NET Core 3.1 SDK
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
2. Navigate to http://localhost:5000 and try adding, editing, and removing todo items.
3. To stop ASP.NET Core, press Ctrl+C in the terminal.
4. Make sure the default branch is main .
TIP
The branch name change isn't required by App Service. However, since many repositories are changing their
default branch to main , this tutorial also shows you how to deploy a repository from main . For more
information, see Change deployment branch.
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
Create Azure resources
In the Cloud Shell, run the following commands to create two Windows web apps. Replace <front-end-app-
name> and <back-end-app-name> with two globally unique app names (valid characters are a-z , 0-9 , and
- ). For more information on each command, see Host a RESTful API with CORS in Azure App Service.
In the Cloud Shell, run the following commands to create two web apps. Replace <front-end-app-name> and
<back-end-app-name> with two globally unique app names (valid characters are a-z , 0-9 , and - ). For more
information on each command, see Create a .NET Core app in Azure App Service.
NOTE
Save the URLs of the Git remotes for your front-end app and back-end app, which are shown in the output from
az webapp create .
2. Back in the local terminal window , run the following Git commands to deploy to the back-end app.
Replace <deploymentLocalGitUrl-of-back-end-app> with the URL of the Git remote that you saved from
Create Azure resources. When prompted for credentials by Git Credential Manager, make sure that you
enter your deployment credentials, not the credentials you use to sign in to the Azure portal.
3. In the local terminal window, run the following Git commands to deploy the same code to the front-end
app. Replace <deploymentLocalGitUrl-of-front-end-app> with the URL of the Git remote that you saved
from Create Azure resources.
git remote add frontend <deploymentLocalGitUrl-of-front-end-app>
git push frontend main
http://<back-end-app-name>.azurewebsites.net
http://<front-end-app-name>.azurewebsites.net
NOTE
If your app restarts, you may have noticed that new data has been erased. This behavior by design because the sample
ASP.NET Core app uses an in-memory database.
2. Find the method that's decorated with [HttpGet] and replace the code inside the curly braces with:
The first line makes a GET /api/Todo/{id} call to the back-end API app.
4. Next, find the method that's decorated with [HttpPost] and replace the code inside the curly braces with:
The first line makes a POST /api/Todo call to the back-end API app.
5. Next, find the method that's decorated with [HttpPut("{id}")] and replace the code inside the curly
braces with:
The first line makes a PUT /api/Todo/{id} call to the back-end API app.
6. Next, find the method that's decorated with [HttpDelete("{id}")] and replace the code inside the curly
braces with:
The first line makes a DELETE /api/Todo/{id} call to the back-end API app.
7. Save all your changes. In the local terminal window, deploy your changes to the front-end app with the
following Git commands:
git add .
git commit -m "call back-end API"
git push frontend main
3. In your back-end app's left menu, select Authentication , and then click Add identity provider .
4. In the Add an identity provider page, select Microsoft as the Identity provider to sign in Microsoft
and Azure AD identities.
5. Accept the default settings and click Add .
6. The Authentication page opens. Copy the Client ID of the Azure AD application to a notepad. You need
this value later.
If you stop here, you have a self-contained app that's already secured by the App Service authentication and
authorization. The remaining sections show you how to secure a multi-app solution by "flowing" the
authenticated user from the front end to the back end.
Enable authentication and authorization for front-end app
Follow the same steps for the front-end app, but skip the last step. You don't need the client ID for the front-end
app. However, stay on the Authentication page for the front-end app because you'll use it in the next step.
If you like, navigate to http://<front-end-app-name>.azurewebsites.net . It should now direct you to a secured
sign-in page. After you sign in, you still can't access the data from the back-end app, because the back-end app
now requires Azure Active Directory sign-in from the front-end app. You need to do three things:
Grant the front end access to the back end
Configure App Service to return a usable token
Use the token in your code
TIP
If you run into errors and reconfigure your app's authentication/authorization settings, the tokens in the token store may
not be regenerated from the new settings. To make sure your tokens are regenerated, you need to sign out and sign back
in to your app. An easy way to do it is to use your browser in private mode, and close and reopen the browser in private
mode after changing the settings in your apps.
The commands effectively adds a loginParameters property with additional custom scopes. Here's an
explanation of the requested scopes:
, profile , and
openid email are requested by App Service by default already. For information, see OpenID
Connect Scopes.
api://<back-end-client-id>/user_impersonation is an exposed API in your back-end app registration. It's the
scope that gives you a JWT token that includes the back end app as a token audience.
offline_access is included here for convenience (in case you want to refresh tokens).
TIP
To view the api://<back-end-client-id>/user_impersonation scope in the Azure portal, go to the
Authentication page for the back-end app, click the link under Identity provider , then click Expose an API in the
left menu.
To configure the required scopes using a web interface instead, see the Microsoft steps at Refresh auth tokens.
Some scopes require admin or user consent. This requirement causes the consent request page to be displayed when
a user signs into the front-end app in the browser. To avoid this consent page, add the front end's app registration as
an authorized client application in the Expose an API page by clicking Add a client application and supplying the
client ID of the front end's app registration.
NOTE
For Linux apps, There's a temporary requirement to configure a versioning setting for the back-end app registration. In
the Cloud Shell, configure it with the following commands. Be sure to replace <back-end-client-id> with your back end's
client ID.
Your apps are now configured. The front end is now ready to access the back end with a proper access token.
For information on how to configure the access token for other providers, see Refresh identity provider tokens.
NOTE
These headers are injected for all supported languages. You access them using the standard pattern for each respective
language.
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"]);
}
This code adds the standard HTTP header Authorization: Bearer <access-token> to all remote API calls. In
the ASP.NET Core MVC request execution pipeline, OnActionExecuting executes just before the respective
action does, so each of your outgoing API call now presents the access token.
2. Save all your changes. In the local terminal window, deploy your changes to the front-end app with the
following Git commands:
git add .
git commit -m "add authorization header for server code"
git push frontend main
TIP
This section uses the standard HTTP methods to demonstrate the secure HTTP calls. However, you can use Microsoft
Authentication Library for JavaScript to help simplify the Angular.js application pattern.
Configure CORS
In the Cloud Shell, enable CORS to your client's URL by using the az webapp cors add command. Replace the
<back-end-app-name> and <front-end-app-name> placeholders.
This step is not related to authentication and authorization. However, you need it so that your browser allows the
cross-domain API calls from your Angular.js app. For more information, see Add CORS functionality.
Point Angular.js app to back-end API
1. In the local repository, open wwwroot/index.html.
2. In Line 51, set the variable to the HTTPS URL of your back-end app (
apiEndpoint
https://<back-end-app-name>.azurewebsites.net ). Replace <back-end-app-name> with your app name in
App Service.
3. In the local repository, open wwwroot/app/scripts/todoListSvc.js and see that apiEndpoint is prepended
to all the API calls. Your Angular.js app is now calling the back-end APIs.
Add access token to API calls
1. In wwwroot/app/scripts/todoListSvc.js, above the list of API calls (above the line getItems : function(){ ),
add the following function to the list:
setAuth: function (token) {
$http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
},
This function is called to set the default Authorization header with the access token. You call it in the next
step.
2. In the local repository, open wwwroot/app/scripts/app.js and find the following code:
$routeProvider.when("/Home", {
controller: "todoListCtrl",
templateUrl: "/App/Views/TodoList.html",
}).otherwise({ redirectTo: "/Home" });
$routeProvider.when("/Home", {
controller: "todoListCtrl",
templateUrl: "/App/Views/TodoList.html",
resolve: {
token: ['$http', 'todoListSvc', function ($http, todoListSvc) {
return $http.get('/.auth/me').then(function (response) {
todoListSvc.setAuth(response.data[0].access_token);
return response.data[0].access_token;
});
}]
},
}).otherwise({ redirectTo: "/Home" });
The new change adds the resolve mapping that calls /.auth/me and sets the access token. It makes sure
you have the access token before instantiating the todoListCtrl controller. That way all API calls by the
controller includes the token.
Deploy updates and test
1. Save all your changes. In the local terminal window, deploy your changes to the front-end app with the
following Git commands:
git add .
git commit -m "add authorization header for Angular"
git push frontend main
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
az group delete --name myAuthResourceGroup
Next steps
What you learned:
Enable built-in authentication and authorization
Secure apps against unauthenticated requests
Use Azure Active Directory as the identity provider
Access a remote app on behalf of the signed-in user
Secure service-to-service calls with token authentication
Use access tokens from server code
Use access tokens from client (browser) code
Advance to the next tutorial to learn how to map a custom DNS name to your app.
Map an existing custom DNS name to Azure App Service
Tutorial: Isolate back-end communication in Azure
App Service with Virtual Network integration
5/18/2022 • 7 minutes to read • Edit Online
In this article you will configure an App Service app with secure, network-isolated communication to backend
services. The example scenario used is in Tutorial: Secure Cognitive Service connection from App Service using
Key Vault. When you're finished, you have an App Service app that accesses both Key Vault and Cognitive
Services through an Azure virtual network, and no other traffic is allowed to access those back-end resources.
All traffic will be isolated within your virtual network using virtual network integration and private endpoints.
As a multi-tenanted service, outbound network traffic from your App Service app to other Azure services shares
the same environment with other apps or even other subscriptions. While the traffic itself can be encrypted,
certain scenarios may require an extra level of security by isolating back-end communication from other
network traffic. These scenarios are typically accessible to large enterprises with a high level of expertise, but
App Service puts it within reach with virtual network integration.
Prerequisites
The tutorial assumes that you have followed the Tutorial: Secure Cognitive Service connection from App Service
using Key Vault and created the language detector app.
The tutorial continues to use the following environment variables from the previous tutorial. Make sure you set
them properly.
groupName=myKVResourceGroup
region=westeurope
csResourceName=<cs-resource-name>
appName=<app-name>
vaultName=<vault-name>
az network vnet create --resource-group $groupName --location $region --name $vnetName --address-
prefixes 10.0.0.0/16
az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name vnet-
integration-subnet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Web/serverfarms
For App Service, the virtual network integration subnet is recommended to have a CIDR block of /26 at
a minimum (see Virtual network integration subnet requirements). /24 is more than sufficient.
--delegations Microsoft.Web/serverfarms specifies that the subnet is delegated for App Service virtual
network integration.
3. Create another subnet for the private endpoints.
az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name private-
endpoint-subnet --address-prefixes 10.0.1.0/24 --disable-private-endpoint-network-policies
For private endpoint subnets, you must disable private endpoint network policies.
For more information on these settings, see Azure Private Endpoint DNS configuration
2. Link the private DNS zones to the virtual network.
az network private-dns link vnet create --resource-group $groupName --name cognitiveservices-zonelink
--zone-name privatelink.cognitiveservices.azure.com --virtual-network $vnetName --registration-
enabled False
az network private-dns link vnet create --resource-group $groupName --name vaultcore-zonelink --zone-
name privatelink.vaultcore.azure.net --virtual-network $vnetName --registration-enabled False
2. Create a DNS zone group for the Cognitive Services private endpoint. DNS zone group is a link between
the private DNS zone and the private endpoint. This link helps you to auto update the private DNS Zone
when there is an update to the private endpoint.
NOTE
Make sure the provisioning state of your change is "Succeeded" . Then you can observe the behavior change in
the sample app. You can still load the app, but if you try click the Detect button, you get an HTTP 500 error. The
app has lost its connectivity to the Cognitive Services resource through the shared networking.
NOTE
Again, you can observe the behavior change in the sample app. You can no longer load the app because it can no
longer access the key vault references. The app has lost its connectivity to the key vault through the shared
networking.
The two private endpoints are only accessible to clients inside the virtual network you created. You can't even
access the secrets in the key vault through Secrets page in the Azure portal, because the portal accesses them
through the public internet (see Manage the locked down resources).
2. Unrelated to our scenario but also important, enforce HTTPS for inbound requests.
az webapp vnet-integration add --resource-group $groupName --name $appName --vnet $vnetName --subnet
vnet-integration-subnet
Virtual network integration allows outbound traffic to flow directly into the virtual network. By default,
only local IP traffic defined in RFC-1918 is routed to the virtual network, which is what you need for the
private endpoints. To route all your traffic to the virtual network, see Manage virtual network integration
routing. Routing all traffic can also be used if you want to route internet traffic through your virtual
network, such as through an Azure Virtual Network NAT or an Azure Firewall.
4. In the browser, navigate to <app-name>.azurewebsites.net again and wait for the integration to take effect.
If you get an HTTP 500 error, wait a few minutes and try again. If you can load the page and get detection
results, then you're connecting to the Cognitive Services endpoint with key vault references.
NOTE
If keep getting HTTP 500 errors after a long time, it may help to force a refetch of the key vault references again,
like so:
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
Integrate your app with an Azure virtual network
App Service networking features
Tutorial: Host a RESTful API with CORS in Azure
App Service
5/18/2022 • 9 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. In addition, App Service has
built-in support for Cross-Origin Resource Sharing (CORS) for RESTful APIs. This tutorial shows how to deploy
an ASP.NET Core API app to App Service with CORS support. You configure the app using command-line tools
and deploy the app using Git.
In this tutorial, you learn how to:
Create App Service resources using Azure CLI
Deploy a RESTful API to Azure using Git
Enable App Service CORS support
You can follow the steps in this tutorial on macOS, Linux, Windows.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial:
Install Git
Install the latest .NET Core 3.1 SDK
This repository contains an app that's created based on the following tutorial: ASP.NET Core Web API help
pages using Swagger. It uses a Swagger generator to serve the Swagger UI and the Swagger JSON
endpoint.
3. Make sure the default branch is main .
dotnet restore
dotnet run
O P T IO N EXA M P L E/ L IN K
The JSON output shows the password as null . If you get a 'Conflict'. Details: 409 error, change the
username. If you get a 'Bad Request'. Details: 400 error, use a stronger password.
Record your username and password to use to deploy your web apps.
Create a resource group
A resource group is a logical container into which Azure resources, such as web apps, databases, and storage
accounts, are deployed and managed. For example, you can choose to delete the entire resource group in one
simple step later.
In the Cloud Shell, create a resource group with the az group create command. The following example creates
a resource group named myResourceGroup in the West Europe location. To see all supported locations for App
Service in Free tier, run the az appservice list-locations --sku FREE command.
You generally create your resource group and the resources in a region near you.
When the command finishes, a JSON output shows you the resource group properties.
Create an App Service plan
In the Cloud Shell, create an App Service plan with the az appservice plan create command.
The following example creates an App Service plan named myAppServicePlan in the Free pricing tier:
When the App Service plan has been created, the Azure CLI shows information similar to the following example:
{
"adminSiteName": null,
"appServicePlanName": "myAppServicePlan",
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-
0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "app",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
When the web app has been created, the Azure CLI shows output similar to the following example:
Local git is configured with url of 'https://<username>@<app-name>.scm.azurewebsites.net/<app-
name>.git'
{
"availabilityState": "Normal",
"clientAffinityEnabled": true,
"clientCertEnabled": false,
"clientCertExclusionPaths": null,
"cloningInfo": null,
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"defaultHostName": "<app-name>.azurewebsites.net",
"deploymentLocalGitUrl": "https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git",
"enabled": true,
< JSON data removed for brevity. >
}
NOTE
The URL of the Git remote is shown in the property, with the format
deploymentLocalGitUrl
https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git . Save this URL as you need it later.
2. Back in the local terminal window, add an Azure remote to your local Git repository. Replace
<deploymentLocalGitUrl-from-create-step> with the URL of the Git remote that you saved from Create a
web app.
3. Push to the Azure remote to deploy your app with the following command. When Git Credential Manager
prompts you for credentials, make sure you enter the credentials you created in Configure a
deployment user , not the credentials you use to sign in to the Azure portal.
This command may take a few minutes to run. While running, it displays information similar to the
following example:
Enumerating objects: 83, done.
Counting objects: 100% (83/83), done.
Delta compression using up to 8 threads
Compressing objects: 100% (78/78), done.
Writing objects: 100% (83/83), 22.15 KiB | 3.69 MiB/s, done.
Total 83 (delta 26), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '509236e13d'.
remote: Generating deployment script.
remote: Project file path: .\TodoApi.csproj
remote: Generating deployment script for ASP.NET MSBuild16 App
remote: Generated deployment script files
remote: Running deployment command...
remote: Handling ASP.NET Core Web Application deployment with MSBuild16.
remote: .
remote: .
remote: .
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Triggering recycle (preview mode disabled).
remote: Deployment successful.
To https://<app_name>.scm.azurewebsites.net/<app_name>.git
* [new branch] master -> master
dotnet run
4. Navigate to the browser app at http://localhost:5000 . Open the developer tools window in your
browser ( Ctrl + Shift + i in Chrome for Windows) and inspect the Console tab. You should now see
the error message, No 'Access-Control-Allow-Origin' header is present on the requested resource .
Because of the domain mismatch between the browser app ( http://localhost:5000 ) and remote
resource ( http://<app_name>.azurewebsites.net ), and the fact that your API in App Service is not sending
the Access-Control-Allow-Origin header, your browser has prevented cross-domain content from loading
in your browser app.
In production, your browser app would have a public URL instead of the localhost URL, but the way to
enable CORS to a localhost URL is the same as a public URL.
Enable CORS
In the Cloud Shell, enable CORS to your client's URL by using the az webapp cors add command. Replace the
<app-name> placeholder.
You can set more than one client URL in properties.cors.allowedOrigins ( "['URL1','URL2',...]" ). You can also
enable all client URLs with "['*']" .
NOTE
If your app requires credentials such as cookies or authentication tokens to be sent, the browser may require the
ACCESS-CONTROL-ALLOW-CREDENTIALS header on the response. To enable this in App Service, set
properties.cors.supportCredentials to true in your CORS config. This cannot be enabled when allowedOrigins
includes '*' .
NOTE
Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request
forgery. The CORS service returns an invalid CORS response when an app is configured with both methods.
Test CORS again
Refresh the browser app at http://localhost:5000 . The error message in the Console window is now gone, and
you can see the data from the deployed API and interact with it. Your remote API now supports CORS to your
browser app running locally.
Congratulations, you're running an API in Azure App Service with CORS support.
NOTE
Don't try to use App Service CORS and your own CORS code together. When used together, App Service CORS takes
precedence and your own CORS code has no effect.
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
This tutorial shows how to add Azure Content Delivery Network (CDN) to a web app in Azure App Service. Web
apps is a service for hosting web applications, REST APIs, and mobile back ends.
Here's the home page of the sample static HTML site that you'll work with:
Prerequisites
To complete this tutorial:
Install Git
Install the Azure CLI
If you don't have an Azure subscription, create an Azure free account before you begin.
In the App Ser vice page, in the Settings section, select Networking > Configure Azure CDN for your
app .
In the Azure Content Deliver y Network page, provide the New endpoint settings as specified in the table.
Pricing tier Standard Akamai The pricing tier specifies the provider
and available features. This tutorial
uses Standard Akamai.
CDN endpoint name Any name that is unique in the You access your cached resources at
azureedge.net domain the domain
<endpointname>.azureedge.net.
http://<appname>.azurewebsites.net/css/bootstrap.css
http://<endpointname>.azureedge.net/css/bootstrap.css
http://<endpointname>.azureedge.net/index.html
You see the same page that you ran earlier in an Azure web app. Azure CDN has retrieved the origin web app's
assets and is serving them from the CDN endpoint
To ensure that this page is cached in the CDN, refresh the page. Two requests for the same asset are sometimes
required for the CDN to cache the requested content.
For more information about creating Azure CDN profiles and endpoints, see Getting started with Azure CDN.
Once deployment has completed, browse to the web app URL to see the change.
http://<appname>.azurewebsites.net/index.html
If you browse to the CDN endpoint URL for the home page, you won't see the change because the cached
version in the CDN hasn't expired yet.
http://<endpointname>.azureedge.net/index.html
Enter the content paths you want to purge. You can pass a complete file path to purge an individual file, or a
path segment to purge and refresh all content in a folder. Because you changed index.html, ensure that is in one
of the paths.
At the bottom of the page, select Purge .
Verify that the CDN is updated
Wait until the purge request finishes processing, which is typically a couple of minutes. To see the current status,
select the bell icon at the top of the page.
When you browse to the CDN endpoint URL for index.html, you'll see the V2 that you added to the title on the
home page, which indicates that the CDN cache has been refreshed.
http://<endpointname>.azureedge.net/index.html
http://<endpointname>.azureedge.net/index.html?q=1
Azure CDN returns the current web app content, which includes V2 in the heading.
To ensure that this page is cached in the CDN, refresh the page.
Open index.html, change V2 to V3, then deploy the change.
In a browser, go to the CDN endpoint URL with a new query string, such as q=2 . Azure CDN gets the current
index.html file and displays V3. However, if you navigate to the CDN endpoint with the q=1 query string, you
see V2.
http://<endpointname>.azureedge.net/index.html?q=2
http://<endpointname>.azureedge.net/index.html?q=1
Clean up resources
In the preceding steps, you created Azure resources in a resource group. If you don't expect to need these
resources in the future, delete the resource group by running the following command in the Cloud Shell:
Next steps
What you learned:
Create a CDN endpoint.
Refresh cached assets.
Use query strings to control cached versions.
Learn how to optimize CDN performance in the following articles:
Tutorial: Add a custom domain to your Azure CDN endpoint
Tutorial: Send email and invoke other business
processes from App Service
5/18/2022 • 7 minutes to read • Edit Online
In this tutorial, you learn how to integrate your App Service app with your business processes. This is common
to web app scenarios, such as:
Send confirmation email for a transaction
Add user to Facebook group
Connect to third-party systems like SAP, Salesforce, etc.
Exchange standard B2B messages
In this tutorial, you send emails with Gmail from your App Service app by using Azure Logic Apps. There are
other ways to send emails from a web app, such as SMTP configuration provided by your language framework.
However, Logic Apps brings a lot more power to your App Service app without adding complexity to your code.
Logic Apps provides a simple configuration interface for the most popular business integrations, and your app
can call them anytime with an HTTP request.
Prerequisite
Deploy an app with the language framework of your choice to App Service. To follow a tutorial to deploy a
sample app, see below:
ASP.NET
ASP.NET Core
Node.js
PHP
Python
Ruby
4. Copy the following sample JSON into the textbox and select Done .
{
"task": "<description>",
"due": "<date>",
"email": "<email-address>"
}
The schema is now generated for the request data you want. In practice, you can just capture the actual
request data your application code generates and let Azure generate the JSON schema for you.
5. At the top of the Logic Apps Designer, select Save .
You can now see the URL of your HTTP request trigger. Select the copy icon to copy it for later use.
This HTTP request definition is a trigger to anything you want to do in this logic app, be it Gmail or
anything else. Later you will invoke this URL in your App Service app. For more information on the
request trigger, see the HTTP request/response reference.
6. At the bottom of the designer, click New step , type Gmail in the actions search box. Find and select
Send email (V2) .
TIP
You can search for other types of integrations, such as SendGrid, MailChimp, Microsoft 365, and SalesForce. For
more information, see Logic Apps documentation.
7. In the Gmail dialog, select Sign in and sign in to the Gmail account you want to send the email from.
8. Once signed in, click in the To textbox, and the dynamic content dialog is automatically opened.
9. Next to the When an HTTP request is received action, select See more .
You should now see the three properties from your sample JSON data you used earlier. In this step, you
use these properties from the HTTP request to construct an email.
10. Since you're selecting the value for the To field, choose email . If you want, toggle off the dynamic content
dialog by clicking Add dynamic content .
11. In the Add new parameter dropdown, select Subject and Body .
12. Click in the Subject textbox, and in the same way, choose task . With the cursor still in the Subject box,
type created.
13. Click in the Body , and in the same way, choose due . Move the cursor to the left of due and type This
work item is due on.
TIP
If you want to edit HTML content directly in the email body, select Code view at the top of the Logic Apps
Designer window. Just make sure you preserve the dynamic content code (for example,
@{triggerBody()?['due']} )
14. Next, add an asynchronous HTTP response to the HTTP trigger. Between the HTTP trigger and the Gmail
action, click the + sign and select Add a parallel branch .
15. In the search box, search for response , then select the Response action.
By default, the response action sends an HTTP 200. That's good enough for this tutorial. For more
information, see the HTTP request/response reference.
16. At the top of the Logic Apps Designer, select Save again.
In your code, make a standard HTTP post to the URL using any HTTP client language that's available to your
language framework, with the following configuration:
The request body contains the same JSON format that you supplied to your logic app:
{
"task": "<description>",
"due": "<date>",
"email": "<email-address>"
}
ASP.NET
ASP.NET Core
Node.js
PHP
Python
Ruby
In ASP.NET, you can send the HTTP post with the System.Net.Http.HttpClient class. For example:
If you're testing this code on the sample app for Tutorial: Build an ASP.NET app in Azure with SQL Database, you
could use it to send an email confirmation in the Create action, after the Todo item is added. To use the
asynchronous code above, convert the Create action to asynchronous.
More resources
Tutorial: Host a RESTful API with CORS in Azure App Service
HTTP request/response reference for Logic Apps
Quickstart: Create your first workflow by using Azure Logic Apps - Azure portal
Environment variables and app settings reference
Tutorial: Troubleshoot an App Service app with
Azure Monitor
5/18/2022 • 7 minutes to read • Edit Online
This tutorial shows how to troubleshoot an App Service app using Azure Monitor. The sample app includes code
meant to exhaust memory and cause HTTP 500 errors, so you can diagnose and fix the problem using Azure
Monitor. When you're finished, you'll have a sample app running on App Service on Linux integrated with Azure
Monitor.
Azure Monitor maximizes the availability and performance of your applications and services by delivering a
comprehensive solution for collecting, analyzing, and acting on telemetry from your cloud and on-premises
environments.
In this tutorial, you learn how to:
Configure a web app with Azure Monitor
Send console logs to Log Analytics
Use Log queries to identify and troubleshoot web app errors
You can follow the steps in this tutorial on macOS, Linux, Windows.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial, you'll need:
Azure subscription
Git
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
NOTE
For Azure Monitor Log Analytics, you pay for data ingestion and data retention.
NOTE
The first two commands, resourceID and workspaceID , are variables to be used in the az monitor diagnostic-settings
create command. See Create diagnostic settings using Azure CLI for more information on this command.
resourceID=$(az webapp show -g myResourceGroup -n <app-name> --query id --output tsv)
Select the first two images and click convert . This will convert successfully.
Break the app
Now that you've verified the app by converting two images successfully, we'll try to convert the first five images.
This action fails and produces a HTTP 500 error that wasn't tested during development.
The AppServiceHTTPLogs query returns all requests in the past 24-hours. The column ScStatus contains the
HTTP status. To diagnose the HTTP 500 errors, limit the ScStatus to 500 and run the query, as shown below:
AppServiceHTTPLogs
| where ScStatus == 500
NOTE
A query has been prepared for you that does the following:
Filters HTTPLogs for 500 errors
Queries console logs
Joins the tables on TimeGenerated
In the ResultDescription column, you'll see the following error at the same time as web server errors:
The message states memory has been exhausted on line 20 of process.php . You've now confirmed that the
application produced an error during the HTTP 500 error. Let's take a look at the code to identify the problem.
imagepng($imgArray[$x], $filename);
The first argument, $imgArray[$x] , is a variable holding all JPGs (in-memory) needing conversion. However,
imagepng only needs the image being converted and not all images. Pre-loading images is not necessary and
may be causing the memory exhaustion, leading to HTTP 500s. Let's update the code to load images on-demand
to see if it resolves the issue. Next, you will improve the code to address the memory problem.
<?php
Commit your changes in Git, and then push the code changes to Azure.
Next steps
Query logs with Azure Monitor
Troubleshooting Azure App Service in Visual Studio
Analyze app Logs in HDInsight
Tutorial: Run a load test to identify performance bottlenecks in a web app
Tutorial: Use GitHub Actions to deploy to an App
Service custom container and connect to a
database
5/18/2022 • 4 minutes to read • Edit Online
This tutorial walks you through setting up a GitHub Actions workflow to deploy a containerized ASP.NET Core
application with an Azure SQL Database backend. When you're finished, you have an ASP.NET app running in
Azure and connected to SQL Database. You'll first create Azure resources with an ARM template GitHub Actions
workflow.
In this tutorial, you learn how to:
Use a GitHub Actions workflow to add resources to Azure with a Azure Resource Manager template (ARM
template)
Use a GitHub Actions workflow to build a container with the latest web app changes
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial, you'll need:
An Azure account with an active subscription. Create an account for free.
A GitHub account. If you don't have one, sign up for free.
A GitHub repository to store your Resource Manager templates and your workflow files. To create one,
see Creating a new repository.
https://github.com/Azure-Samples/dotnetcore-containerized-sqldb-ghactions/
In the example, replace the placeholders with your subscription ID, resource group name, and service principal
name. The output is a JSON object with the role assignment credentials that provide access to your App Service
app. Copy this JSON object for later. For help, go to configure deployment credentials.
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
IMPORTANT
It is always a good practice to grant minimum access. The scope in the previous example is limited to the specific App
Service app and not the entire resource group.
3. Update the ACR_LOGIN_SERVER value for your Azure Container Registry login server.
Next steps
Learn about Azure and GitHub integration
Tutorial: Use GitHub Actions to deploy to App
Service and connect to a database
5/18/2022 • 3 minutes to read • Edit Online
Learn how to set up a GitHub Actions workflow to deploy a ASP.NET Core application with an Azure SQL
Database backend. When you're finished, you have an ASP.NET app running in Azure and connected to SQL
Database. You'll first use an ARM template to create resources.
This tutorial does not use containers. If you want to deploy to a containerized ASP.NET Core application, see Use
GitHub Actions to deploy to App Service for Containers and connect to a database.
In this tutorial, you learn how to:
Use a GitHub Actions workflow to add resources to Azure with a Azure Resource Manager template (ARM
template)
Use a GitHub Actions workflow to build an ASP.NET Core application
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
To complete this tutorial, you'll need:
An Azure account with an active subscription. Create an account for free.
A GitHub account. If you don't have one, sign up for free.
A GitHub repository to store your Resource Manager templates and your workflow files. To create one,
see Creating a new repository.
https://github.com/Azure-Samples/dotnetcore-sqldb-ghactions
In the example, replace the placeholders with your subscription ID, resource group name, and service principal
name. The output is a JSON object with the role assignment credentials that provide access to your App Service
app. Copy this JSON object for later. For help, go to configure deployment credentials.
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
6. After you've created your resources, go to Actions , select Create Azure Resources, disable the workflow.
3. Verify that your app deployed by visiting the URL in the Swap to production slot output. You should see a
sample app, My TodoList App.
Clean up resources
If you no longer need your sample project, delete your resource group in the Azure portal and delete your
repository on GitHub.
Next steps
Learn about Azure and GitHub integration
CLI samples for Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
The following table includes links to bash scripts built using the Azure CLI.
Create app
Create an app and deploy files with FTP Creates an App Service app and deploys a file to it using FTP.
Create an app and deploy code from GitHub Creates an App Service app and deploys code from a public
GitHub repository.
Create an app with continuous deployment from GitHub Creates an App Service app with continuous publishing from
a GitHub repository you own.
Create an app and deploy code into a local Git repository Creates an App Service app and configures code push into a
local Git repository.
Create an app and deploy code to a staging environment Creates an App Service app with a deployment slot for
staging code changes.
Create an ASP.NET Core app in a Docker container Creates an App Service app on Linux and loads a Docker
image from Docker Hub.
Create an app with a Private Endpoint Creates an App Service app and a Private Endpoint
Configure app
Map a custom domain to an app Creates an App Service app and maps a custom domain
name to it.
Bind a custom TLS/SSL certificate to an app Creates an App Service app and binds the TLS/SSL certificate
of a custom domain name to it.
Scale app
Scale an app manually Creates an App Service app and scales it across 2 instances.
Scale an app worldwide with a high-availability architecture Creates two App Service apps in two different geographical
regions and makes them available through a single endpoint
using Azure Traffic Manager.
Protect app
Integrate with Azure Application Gateway Creates an App Service app and integrates it with
Application Gateway using service endpoint and access
restrictions.
Connect an app to a SQL Database Creates an App Service app and a database in Azure SQL
Database, then adds the database connection string to the
app settings.
Connect an app to a storage account Creates an App Service app and a storage account, then
adds the storage connection string to the app settings.
Connect an app to an Azure Cache for Redis Creates an App Service app and an Azure Cache for Redis,
then adds the redis connection details to the app settings.)
Connect an app to Cosmos DB Creates an App Service app and a Cosmos DB, then adds
the Cosmos DB connection details to the app settings.
Backup and restore app Creates an App Service app and creates a one-time backup
for it, creates a backup schedule for it, and then restores an
App Service app from a backup.
Monitor app
Monitor an app with web server logs Creates an App Service app, enables logging for it, and
downloads the logs to your local machine.
Create an App Service app and deploy files with
FTP using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources, and then deploys a static HTML page
using FTP. For FTP upload, the script uses cURL as an example. You can use whatever FTP tool to upload your
files.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
subscription="<subscriptionId>" # add subscription here
# Get FTP publishing profile and query for publish URL and credentials
creds=($(az webapp deployment list-publishing-profiles --name $webapp --resource-group $resourceGroup \
--query "[?contains(publishMethod, 'FTP')].[publishUrl,userName,userPWD]" --output tsv))
# Use cURL to perform FTP upload. You can use any FTP tool to do this instead.
curl -T index.html -u ${creds[1]}:${creds[2]} ${creds[0]}/
# Copy the result of the following command into a browser to see the static HTML site.
site="http://$webapp.azurewebsites.net"
echo $site
curl "$site"
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp deployment list-publishing-profiles Get the details for available app deployment profiles.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Create an App Service app with deployment from
GitHub using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources. It then deploys your app code from a
public GitHub repository (without continuous deployment). For GitHub deployment with continuous
deployment, see Create an app with continuous deployment from GitHub.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
subscription="<subscriptionId>" # add subscription here
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
C OMMAND N OT ES
az webapp deployment source config Associates an App Service app with a Git or Mercurial
repository.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Create an App Service app with continuous
deployment from GitHub using CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources, and then sets up continuous
deployment from a GitHub repository. For GitHub deployment without continuous deployment, see Create an
app and deploy code from GitHub. For this sample, you need:
A GitHub repository with application code, that you have administrative permissions for. To get automatic
builds, structure your repository according to the Prepare your repository table.
A Personal Access Token (PAT) for your GitHub account.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
gitrepo=<replace-with-URL-of-your-own-GitHub-repo>
token=<replace-with-a-GitHub-access-token>
TIP
The --git-token parameter is required only once per Azure account (Azure remembers token).
az webapp deployment source config --name $webapp --resource-group $resourceGroup --repo-url $gitrepo
--branch master --git-token $token
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp deployment source config Associates an App Service app with a Git or Mercurial
repository.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Create an App Service app and deploy code into a
local Git repository using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources, and then deploys your app code in a
local Git repository.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
3. Add the Azure remote to your local Git repository and push your code. When prompted for password,
use the value of $password that you specified.
cd $gitdirectory
git remote add azure $url
git push azure main
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp deployment user set Sets the account-level deployment credentials for App
Service.
az webapp deployment source config-local-git Creates a source control configuration for a local Git
repository.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Create an App Service app and deploy code to a
staging environment using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with an additional deployment slot called "staging", and then
deploys a sample app to the "staging" slot.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
# Create an App Service plan in STANDARD tier (minimum required by deployment slots).
echo "Creating $appServicePlan"
az appservice plan create --name $appServicePlan --resource-group $resourceGroup --location "$location" \
--sku S1
# Copy the result of the following command into a browser to see the staging slot.
site="http://$webapp-staging.azurewebsites.net"
echo $site
curl "$site"
# Copy the result of the following command into a browser to see the web app in the production slot.
site="http://$webapp.azurewebsites.net"
echo $site
curl "$site"
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp deployment source config Associates an App Service app with a Git or Mercurial
repository.
az webapp deployment slot swap Swap a specified deployment slot into production.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Create an ASP.NET Core app in a Docker container
from Docker Hub using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates a resource group, a Linux App Service plan, and an app. It then deploys an ASP.NET
Core application using a Docker Container.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
# Create a web app. To see list of available runtimes, run 'az webapp list-runtimes --linux'
echo "Creating $webapp"
az webapp create --name $webapp --resource-group $resourceGroup --plan $appServicePlan --runtime "NODE|14-
lts"
# Copy the result of the following command into a browser to see the static HTML site.
site="http://$webapp.azurewebsites.net"
echo $site
curl "$site"
Configure Web App with a Custom Docker Container from Docker Hub
1. Create the following variable containing your GitHub information.
2. Configure the web app with a custom docker container from Docker Hub.
3. Copy the result of the following command into a browser to see the web app.
site="http://$webapp.azurewebsites.net"
echo $site
curl "$site"
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp config container set Sets the Docker container for the App Service app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Create an App Service app and deploy Private
Endpoint using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources, and then deploys a Private Endpoint.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
This tutorial requires version 2.0.28 or later of the Azure CLI. If using Azure Cloud Shell, the latest version is
already installed.
az webapp create \
--name mySiteName \
--resource-group myResourceGroup \
--plan myAppServicePlan
Create a VNet
Create a Virtual Network with az network vnet create. This example creates a default Virtual Network named
myVNet with one subnet named mySubnet:
Clean up deployment
After the sample script has been run, the following command can be used to remove the resource group and all
resources associated with it.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Map a custom domain to an App Service app using
CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources, and then maps www.<yourdomain> to
it.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
# Create an App Service plan in SHARED tier (minimum required by custom domains).
echo "Creating $appServicePlan"
az appservice plan create --name $appServicePlan --resource-group $resourceGroup --sku SHARED
# Copy the result of the following command into a browser to see the static HTML site.
site="http://$webapp.azurewebsites.net"
echo $site
curl "$site"
2. Configure a CNAME record that maps your fully qualified domain name to your web app's default
domain name ($webappname.azurewebsites.net).
3. Map your domain name to the web app.
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp config hostname add Maps a custom domain to an App Service app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Bind a custom TLS/SSL certificate to an App Service
app using CLI
5/18/2022 • 4 minutes to read • Edit Online
This sample script creates an app in App Service with its related resources, then binds the TLS/SSL certificate of
a custom domain name to it. For this sample, you need:
Access to your domain registrar's DNS configuration page.
A valid .PFX file and its password for the TLS/SSL certificate you want to upload and bind.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
subscription="<subscriptionId>" # add subscription here
# Create an App Service plan in Basic tier (minimum required by custom domains).
echo "Creating $appServicePlan"
az appservice plan create --name $appServicePlan --resource-group $resourceGroup --sku B1
# Copy the result of the following command into a browser to see the static HTML site.
site="http://$webapp.azurewebsites.net"
echo $site
curl "$site"
2. Configure a CNAME record that maps your fully qualified domain name to your web app's default
domain name ($webappname.azurewebsites.net).
3. Map your domain name to the web app.
pfxPath=<replace-with-path-to-your-.PFX-file>
pfxPassword=<replace-with-your=.PFX-password>
az webapp config ssl bind --certificate-thumbprint $thumbprint --ssl-type SNI --name $webapp --
resource-group $resourceGroup
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp config hostname add Maps a custom domain to an App Service app.
az webapp config ssl upload Uploads a TLS/SSL certificate to an App Service app.
az webapp config ssl bind Binds an uploaded TLS/SSL certificate to an App Service app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Scale an App Service app manually using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates a resource group, an App Service plan, and an app. It then scales the App Service plan
from a single instance to multiple instances.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands to create a resource group, App Service app, and all related resources.
Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Scale an App Service app worldwide with a high-
availability architecture using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates a resource group, two App Service plans, two apps, a traffic manager profile, and two
traffic manager endpoints. Once the exercise is complete, you have a high-available architecture, which provides
global availability of your app based on the lowest network latency.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
subscription="<subscriptionId>" # add subscription here
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands to create a resource group, App Service app, traffic manager profile,
and all related resources. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az network traffic-manager endpoint create Adds an endpoint to an Azure Traffic Manager Profile.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Integrate App Service with Application Gateway
using CLI
5/18/2022 • 4 minutes to read • Edit Online
This sample script creates an Azure App Service web app, an Azure Virtual Network and an Application Gateway.
It then restricts the traffic for the web app to only originate from the Application Gateway subnet.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
appFqdn=$(az webapp show --name $webapp --resource-group $resourceGroup --query defaultHostName -o tsv)
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp config access-restriction add Adds an access restriction to the App Service web app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Connect an App Service app to SQL Database
using CLI
5/18/2022 • 4 minutes to read • Edit Online
This sample script creates a database in Azure SQL Database and an App Service app. It then links the database
to the app using app settings.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
Sample reference
This script uses the following commands to create a resource group, App Service app, SQL Database, and all
related resources. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp config appsettings set Creates or updates an app setting for an App Service app.
App settings are exposed as environment variables for your
app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Connect an App Service app to a storage account
using CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an Azure storage account and an App Service app. It then links the storage account to
the app using app settings.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands to create a resource group, App Service app, storage account, and all
related resources. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az storage account show-connection-string Get the connection string for a storage account.
az webapp config appsettings set Creates or updates an app setting for an App Service app.
App settings are exposed as environment variables for your
app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Connect an App Service app to an Azure Cache for
Redis using CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an Azure Cache for Redis and an App Service app. It then links the Azure Cache for
Redis to the app using app settings.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands to create a resource group, App Service app, Azure Cache for Redis,
and all related resources. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az redis list-keys Lists the access keys for the Azure Cache for Redis instance.
az webapp config appsettings set Creates or updates an app setting for an App Service app.
App settings are exposed as environment variables for your
app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Connect an App Service app to Cosmos DB using
CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates an Azure Cosmos DB account using the Azure Cosmos DB's API for MongoDB and an
App Service app. It then links a MongoDB connection string to the web app using app settings.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands to create a resource group, App Service app, Cosmos DB, and all
related resources. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp config appsettings set Creates or updates an app setting for an App Service app.
App settings are exposed as environment variables for your
app (see Environment variables and app settings reference).
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Backup and restore a web app from a backup using
CLI
5/18/2022 • 4 minutes to read • Edit Online
This sample script creates a web app in App Service with its related resources. It then creates a one-time backup
for it, and also a scheduled backup for it. Finally, it restores the web app from backup.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
# Generate a SAS token for the storage container, valid for one month.
# NOTE: You can use the same SAS token to make backups in App Service until --expiry
sastoken=$(az storage container generate-sas --account-name $storage --name $container --account-key $key \
--expiry $expirydate --permissions rwdl --output tsv)
# Create an App Service plan in Standard tier. Standard tier allows one backup per day.
echo "Creating $appServicePlan"
az appservice plan create --name $appServicePlan --resource-group $resourceGroup --location "$location" \
--sku S1
# fails - https://github.com/Azure/azure-cli/issues/19492
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands. Each command in the table links to command specific documentation.
C OMMAND N OT ES
az webapp config backup list Gets a list of backups for a web app.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
Monitor an App Service app with web server logs
using Azure CLI
5/18/2022 • 3 minutes to read • Edit Online
This sample script creates a resource group, App Service plan, and app, and configures the app to enable web
server logs. It then downloads the log files for review.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Azure Cloud Shell Quickstart -
Bash.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you are running on Windows
or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the
Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish
the authentication process, follow the steps displayed in your terminal. For additional sign-in
options, see Sign in with the Azure CLI.
When you're prompted, install Azure CLI extensions on first use. For more information about
extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the
latest version, run az upgrade.
Sample script
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common
Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Tr y it from the upper right corner of a code block. You can also launch Cloud
Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure
CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter
to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to
sign in using a different subscription, replacing <Subscription ID> with your Azure Subscription ID. If you don't
have an Azure subscription, create an Azure free account before you begin.
Clean up resources
Use the following command to remove the resource group and all resources associated with it using the az
group delete command - unless you have an ongoing need for these resources. Some of these resources may
take a while to create, as well as to delete.
Sample reference
This script uses the following commands to create a resource group, App Service app, and all related resources.
Each command in the table links to command specific documentation.
C OMMAND N OT ES
az group create Creates a resource group in which all resources are stored.
az webapp log config Configures which logs an App Service app persists.
az webapp log download Downloads the logs of an App Service app to your local
machine.
Next steps
For more information on the Azure CLI, see Azure CLI documentation.
Additional App Service CLI script samples can be found in the Azure App Service documentation.
PowerShell samples for Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
The following table includes links to PowerShell scripts built using the Azure PowerShell.
Create app
Create an app with deployment from GitHub Creates an App Service app that pulls code from GitHub.
Create an app with continuous deployment from GitHub Creates an App Service app that continuously deploys code
from GitHub.
Create an app and deploy code with FTP Creates an App Service app and upload files from a local
directory using FTP.
Create an app and deploy code from a local Git repository Creates an App Service app and configures code push from
a local Git repository.
Create an app and deploy code to a staging environment Creates an App Service app with a deployment slot for
staging code changes.
Create an app and expose your app with a Private Endpoint Creates an App Service app with a Private Endpoint.
Configure app
Map a custom domain to an app Creates an App Service app and maps a custom domain
name to it.
Bind a custom TLS/SSL certificate to an app Creates an App Service app and binds the TLS/SSL certificate
of a custom domain name to it.
Scale app
Scale an app manually Creates an App Service app and scales it across 2 instances.
Scale an app worldwide with a high-availability architecture Creates two App Service apps in two different geographical
regions and makes them available through a single endpoint
using Azure Traffic Manager.
Connect an app to a SQL Database Creates an App Service app and a database in Azure SQL
Database, then adds the database connection string to the
app settings.
Connect an app to a storage account Creates an App Service app and a storage account, then
adds the storage connection string to the app settings.
Back up an app Creates an App Service app and creates a one-time backup
for it.
Create a scheduled backup for an app Creates an App Service app and creates a scheduled backup
for it.
Restore an app from backup Restores an app from a previously completed backup.
Restore a backup across subscriptions Restores a web app from a backup in another subscription.
Monitor app
Monitor an app with web server logs Creates an App Service app, enables logging for it, and
downloads the logs to your local machine.
Azure Resource Manager templates for App Service
5/18/2022 • 2 minutes to read • Edit Online
The following table includes links to Azure Resource Manager templates for Azure App Service. For
recommendations about avoiding common errors when you're creating app templates, see Guidance on
deploying apps with Azure Resource Manager templates.
To learn about the JSON syntax and properties for App Services resources, see Microsoft.Web resource types.
App Service plan and basic Linux app Deploys an App Service app that is configured for Linux.
App Service plan and basic Windows app Deploys an App Service app that is configured for Windows.
App linked to a GitHub repository Deploys an App Service app that pulls code from GitHub.
App with custom deployment slots Deploys an App Service app with custom deployment
slots/environments.
App with Private Endpoint Deploys an App Service app with a Private Endpoint.
App certificate from Key Vault Deploys an App Service app certificate from an Azure Key
Vault secret and uses it for TLS/SSL binding.
App with a custom domain and SSL Deploys an App Service app with a custom host name, and
gets an app certificate from Key Vault for TLS/SSL binding.
App with Java 8 and Tomcat 8 Deploys an App Service app with Java 8 and Tomcat 8
enabled. You can then run Java applications in Azure.
App with regional VNet integration Deploys an App Service app with regional VNet integration
enabled.
App integrated with Azure Application Gateway Deploys an App Service app and an Application Gateway,
and isolates the traffic using service endpoint and access
restrictions.
App on Linux with MySQL Deploys an App Service app on Linux with Azure Database
for MySQL.
App on Linux with PostgreSQL Deploys an App Service app on Linux with Azure Database
for PostgreSQL.
App with MySQL Deploys an App Service app on Windows with Azure
Database for MySQL.
App with PostgreSQL Deploys an App Service app on Windows with Azure
Database for PostgreSQL.
App with a database in Azure SQL Database Deploys an App Service app and a database in Azure SQL
Database at the Basic service level.
App with a Blob storage connection Deploys an App Service app with an Azure Blob storage
connection string. You can then use Blob storage from the
app.
App with an Azure Cache for Redis Deploys an App Service app with an Azure Cache for Redis.
App connected to a backend webapp Deploys two web apps (frontend and backend) securely
connected together with VNet injection and Private
Endpoint.
Create an App Service environment v2 Creates an App Service environment v2 in your virtual
network.
Create an App Service environment v2 with an ILB address Creates an App Service environment v2 in your virtual
network with a private internal load balancer address.
Configure the default SSL certificate for an ILB App Service Configures the default TLS/SSL certificate for an ILB App
environment or an ILB App Service environment v2 Service environment or an ILB App Service environment v2.
Terraform samples for Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
Create app
Create two apps and connect securely with Private Endpoint Creates two App Service apps and connect apps together
and VNet integration with Private Endpoint and VNet integration.
Provision App Service and use slot swap to deploy Provision App Service infrastructure with Azure deployment
slots.
Bicep files for App Service
5/18/2022 • 2 minutes to read • Edit Online
The following table includes links to Bicep files for Azure App Service. For quickstarts and further information
about Bicep, see Bicep documentation.
To learn about the Bicep syntax and properties for App Services resources, see Microsoft.Web resource types.
App Service plan and basic Linux app Deploys an App Service app that is configured for Linux.
App Service plan and basic Windows app Deploys an App Service app that is configured for Windows.
Website with container Deploys a website from a docker image configured for Linux.
App with conditional logging Deploys an App Service app with a conditional for logging
enablement.
App with log analytics module Deploys an App Service app with log analytics.
App with regional VNet integration Deploys an App Service app with regional VNet integration
enabled.
App with CosmosDB Deploys an App Service app on Linux with CosmosDB.
App with MySQL Deploys an App Service app on Windows with Azure
Database for MySQL.
App with a database in Azure SQL Database Deploys an App Service app and a database in Azure SQL
Database at the Basic service level.
App connected to a backend webapp Deploys two web apps (frontend and backend) securely
connected together with VNet injection and Private
Endpoint.
App with a database, managed identity, and monitoring Deploys an App Service App with a database, managed
identity, and monitoring.
Create an App Service environment v2 Creates an App Service environment v2 in your virtual
network.
Azure App Service plan overview
5/18/2022 • 7 minutes to read • Edit Online
In App Service (Web Apps, API Apps, or Mobile Apps), an app always runs in an App Service plan. In addition,
Azure Functions also has the option of running in an App Service plan. An App Service plan defines a set of
compute resources for a web app to run. These compute resources are analogous to the server farm in
conventional web hosting. One or more apps can be configured to run on the same computing resources (or in
the same App Service plan).
When you create an App Service plan in a certain region (for example, West Europe), a set of compute resources
is created for that plan in that region. Whatever apps you put into this App Service plan run on these compute
resources as defined by your App Service plan. Each App Service plan defines:
Operating System (Windows, Linux)
Region (West US, East US, etc.)
Number of VM instances
Size of VM instances (Small, Medium, Large)
Pricing tier (Free, Shared, Basic, Standard, Premium, PremiumV2, PremiumV3, Isolated, IsolatedV2)
The pricing tier of an App Service plan determines what App Service features you get and how much you pay
for the plan. The pricing tiers available to your App Service plan depend on the operating system selected at
creation time. There are a few categories of pricing tiers:
Shared compute : Free and Shared , the two base tiers, runs an app on the same Azure VM as other App
Service apps, including apps of other customers. These tiers allocate CPU quotas to each app that runs on the
shared resources, and the resources cannot scale out.
Dedicated compute : The Basic , Standard , Premium , PremiumV2 , and PremiumV3 tiers run apps on
dedicated Azure VMs. Only apps in the same App Service plan share the same compute resources. The
higher the tier, the more VM instances are available to you for scale-out.
Isolated : This Isolated and IsolatedV2 tiers run dedicated Azure VMs on dedicated Azure Virtual
Networks. It provides network isolation on top of compute isolation to your apps. It provides the maximum
scale-out capabilities.
NOTE
App Service Free and Shared (preview) service plans are base tiers that run on the same Azure virtual machines as other
App Service apps. Some apps might belong to other customers. These tiers are intended to be used only for development
and testing purposes.
Each tier also provides a specific subset of App Service features. These features include custom domains and
TLS/SSL certificates, autoscaling, deployment slots, backups, Traffic Manager integration, and more. The higher
the tier, the more features are available. To find out which features are supported in each pricing tier, see App
Service plan details.
NOTE
The new PremiumV3 pricing tier guarantees machines with faster processors (minimum 195 ACU per virtual CPU), SSD
storage, and quadruple memory-to-core ratio compared to Standard tier. PremiumV3 also supports higher scale via
increased instance count while still providing all the advanced capabilities found in Standard tier. All features available in
the existing PremiumV2 tier are included in PremiumV3 .
Similar to other dedicated tiers, three VM sizes are available for this tier:
Small (2 CPU core, 8 GiB of memory)
Medium (4 CPU cores, 16 GiB of memory)
Large (8 CPU cores, 32 GiB of memory)
For PremiumV3 pricing information, see App Service Pricing.
To get started with the new PremiumV3 pricing tier, see Configure PremiumV3 tier for App Service.
NOTE
If you integrate App Service with another Azure service, you may need to consider charges from these other services. For
example, if you use Azure Traffic Manager to scale your app geographically, Azure Traffic Manager also charges you based
on your usage. To estimate your cross-services cost in Azure, see Pricing calculator.
This article describes how you plan for and manage costs for Azure App Service. First, you use the Azure pricing
calculator to help plan for App Service costs before you add any resources for the service to estimate costs.
Next, as you add Azure resources, review the estimated costs. After you've started using App Service resources,
use Cost Management features to set budgets and monitor costs. You can also review forecasted costs and
identify spending trends to identify areas where you might want to act. Costs for Azure App Service are only a
portion of the monthly costs in your Azure bill. Although this article explains how to plan for and manage costs
for App Service, you're billed for all Azure services and resources used in your Azure subscription, including the
third-party services.
Estimate costs
An easy way to estimate and optimize your App Service cost beforehand is by using the Azure pricing calculator.
To use the pricing calculator, click App Ser vice in the Products tab. Then, scroll down to work with the
calculator. The following screenshot is an example and doesn't reflect current pricing.
If your Azure subscription has a spending limit, Azure prevents you from spending over your credit amount. As
you create and use Azure resources, your credits are used. When you reach your credit limit, the resources that
you deployed are disabled for the rest of that billing period. You can't change your credit limit, but you can
remove it. For more information about spending limits, see Azure spending limit.
Optimize costs
At a basic level, App Service apps are charged by the App Service plan that hosts them. The costs associated
with your App Service deployment depend on a few main factors:
Pricing tier Otherwise known as the SKU of the App Service plan. Higher tiers provide more CPU cores,
memory, storage, or features, or combinations of them.
Instance count dedicated tiers (Basic and above) can be scaled out, and each scaled out instance accrues
costs.
Stamp fee In the Isolated tier, a flat fee is accrued on your App Service environment, regardless of how
many apps or worker instances are hosted.
An App Service plan can host more than one app. Depending on your deployment, you could save costs hosting
more apps on one App Service plans (i.e. hosting your apps on fewer App Service plans).
For details, see App Service plan overview
Non-production workloads
To test App Service or your solution while accruing low or minimal cost, you can begin by using the two entry-
level pricing tiers, Free and Shared , which are hosted on shared instances. To test your app on dedicated
instances with better performance, you can upgrade to Basic tier, which supports both Windows and Linux
apps.
NOTE
Azure Dev/Test Pricing To test pre-production workloads that require higher tiers (all tiers except for Isolated ), Visual
Studio subscribers can also take advantage of the Azure Dev/Test Pricing, which offers significant discounts.
Both the Free and Shared tier, as well as the Azure Dev/Test Pricing discounts, don't carry a financially backed SLA.
Production workloads
Production workloads come with the recommendation of the dedicated Standard pricing tier or above. While
the price goes up for higher tiers, it also gives you more memory and storage and higher-performing hardware,
giving you higher app density per compute instance. That translates to lower instance count for the same
number of apps, and therefore lower cost. In fact, Premium V3 (the highest non-Isolated tier) is the most cost
effective way to serve your app at scale. To add to the savings, you can get deep discounts on Premium V3
reservations.
NOTE
Premium V3 supports both Windows containers and Linux containers.
Once you choose the pricing tier you want, you should minimize the idle instances. In a scale-out deployment,
you can waste money on underutilized compute instances. You should configure autoscaling, available in
Standard tier and above. By creating scale-out schedules, as well as metric-based scale-out rules, you only pay
for the instances you really need at any given time.
Azure Reservations
If you plan to utilize a known minimum number of compute instances for one year or more, you should take
advantage of Premium V3 tier and drive down the instance cost drastically by reserving those instances in 1-
year or 3-year increments. The monthly cost savings can be as much as 55% per instance. Two types of
reservations are possible:
Windows (or platform agnostic) Can apply to Windows or Linux instances in your subscription.
Linux specific Applies only to Linux instances in your subscription.
The reserved instance pricing applies to the applicable instances in your subscription, up to the number of
instances that you reserve. The reserved instances are a billing matter and are not tied to specific compute
instances. If you run fewer instances than you reserve at any point during the reservation period, you still pay
for the reserved instances. If you run more instances than you reserve at any point during the reservation
period, you pay the normal accrued cost for the additional instances.
The Isolated tier (App Service environment) also supports 1-year and 3-year reservations at reduced pricing.
For more information, see How reservation discounts apply to Azure App Service.
Monitor costs
As you use Azure resources with App Service, you incur costs. Azure resource usage unit costs vary by time
intervals (seconds, minutes, hours, and days). As soon as App Service use starts, costs are incurred and you can
see the costs in cost analysis.
When you use cost analysis, you view App Service costs in graphs and tables for different time intervals. Some
examples are by day, current and prior month, and year. You also view costs against budgets and forecasted
costs. Switching to longer views over time can help you identify spending trends. And you see where
overspending might have occurred. If you've created budgets, you can also easily see where they're exceeded.
To view App Service costs in cost analysis:
1. Sign in to the Azure portal.
2. Open the scope in the Azure portal and select Cost analysis in the menu. For example, go to
Subscriptions , select a subscription from the list, and then select Cost analysis in the menu. Select Scope
to switch to a different scope in cost analysis.
3. By default, cost for services are shown in the first donut chart. Select the area in the chart labeled App
Service.
Actual monthly costs are shown when you initially open cost analysis. Here's an example showing all monthly
usage costs.
To narrow costs for a single service, like App Service, select Add filter and then select Ser vice name . Then,
select App Ser vice .
Here's an example showing costs for just App Service.
In the preceding example, you see the current cost for the service. Costs by Azure regions (locations) and App
Service costs by resource group are also shown. From here, you can explore costs on your own.
Create budgets
You can create budgets to manage costs and create alerts that automatically notify stakeholders of spending
anomalies and overspending risks. Alerts are based on spending compared to budget and cost thresholds.
Budgets and alerts are created for Azure subscriptions and resource groups, so they're useful as part of an
overall cost monitoring strategy.
Budgets can be created with filters for specific resources or services in Azure if you want more granularity
present in your monitoring. Filters help ensure that you don't accidentally create new resources that cost you
extra money. For more information about the filter options available when you create a budget, see Group and
filter options.
Next steps
Learn more on how pricing works with Azure Storage. See App Service pricing.
Learn how to optimize your cloud investment with Azure Cost Management.
Learn more about managing costs with cost analysis.
Learn about how to prevent unexpected costs.
Take the Cost Management guided learning course.
Operating system functionality on Azure App
Service
5/18/2022 • 10 minutes to read • Edit Online
This article describes the common baseline operating system functionality that is available to all Windows apps
running on Azure App Service. This functionality includes file, network, and registry access, and diagnostics logs
and events.
NOTE
Linux apps in App Service run in their own containers. You have root access to the container but no access to the host
operating system is allowed. Likewise, for apps running in Windows containers, you have administrative access to the
container but no access to the host operating system.
NOTE
App Service Free and Shared (preview) service plans are base tiers that run on the same Azure virtual machines as other
App Service apps. Some apps might belong to other customers. These tiers are intended to be used only for development
and testing purposes.
Because App Service supports a seamless scaling experience between different tiers, the security configuration
enforced for App Service apps remains the same. This ensures that apps don't suddenly behave differently,
failing in unexpected ways, when an App Service plan switches from one tier to another.
Development frameworks
App Service pricing tiers control the amount of compute resources (CPU, disk storage, memory, and network
egress) available to apps. However, the breadth of framework functionality available to apps remains the same
regardless of the scaling tiers.
App Service supports a variety of development frameworks, including ASP.NET, classic ASP, Node.js, PHP, and
Python. In order to simplify and normalize security configuration, App Service apps typically run the various
development frameworks with their default settings. The frameworks and runtime components provided by the
platform are updated regularly to satisfy security and compliance requirements, for this reason we do not
guarantee specific minor/patch versions and recommend customers target major version as needed.
The following sections summarize the general kinds of operating system functionality available to App Service
apps.
File access
Various drives exist within App Service, including local drives and network drives.
Local drives
At its core, App Service is a service running on top of the Azure PaaS (platform as a service) infrastructure. As a
result, the local drives that are "attached" to a virtual machine are the same drive types available to any worker
role running in Azure. This includes:
An operating system drive ( %SystemDrive% ), whose size varies depending on the size of the VM.
A resource drive ( %ResourceDrive% ) used by App Service internally.
It is important to monitor your disk utilization as your application grows. If the disk quota is reached, it can have
adverse effects to your application. For example:
The app may throw an error indicating not enough space on the disk.
You may see disk errors when browsing to the Kudu console.
Deployment from Azure DevOps or Visual Studio may fail with
ERROR_NOT_ENOUGH_DISK_SPACE: Web deployment task failed. (Web Deploy detected insufficient space on disk) .
Your app may suffer slow performance.
Two examples of how App Service uses temporary local storage are the directory for temporary ASP.NET files
and the directory for IIS compressed files. The ASP.NET compilation system uses the
%SystemDrive%\local\Temporary ASP.NET Files directory as a temporary compilation cache location. IIS uses the
%SystemDrive%\local\IIS Temporary Compressed Files directory to store compressed response output. Both of
these types of file usage (as well as others) are remapped in App Service to per-app temporary local storage.
This remapping ensures that functionality continues as expected.
Each app in App Service runs as a random unique low-privileged worker process identity called the "application
pool identity", described further in the IIS Application Pool Identities documentation. Application code uses this
identity for basic read-only access to the operating system drive. This means application code can list common
directory structures and read common files on operating system drive. Although this might appear to be a
somewhat broad level of access, the same directories and files are accessible when you provision a worker role
in an Azure hosted service and read the drive contents.
Network access
Application code can use TCP/IP and UDP-based protocols to make outbound network connections to Internet
accessible endpoints that expose external services. Apps can use these same protocols to connect to services
within Azure, for example, by establishing HTTPS connections to SQL Database.
There is also a limited capability for apps to establish one local loopback connection, and have an app listen on
that local loopback socket. This feature exists primarily to enable apps that listen on local loopback sockets as
part of their functionality. Each app sees a "private" loopback connection. App "A" cannot listen to a local
loopback socket established by app "B".
Named pipes are also supported as an inter-process communication (IPC) mechanism between different
processes that collectively run an app. For example, the IIS FastCGI module relies on named pipes to coordinate
the individual processes that run PHP pages.
Registry access
Apps have read-only access to much (though not all) of the registry of the virtual machine they are running on.
In practice, this means registry keys that allow read-only access to the local Users group are accessible by apps.
One area of the registry that is currently not supported for either read or write access is the
HKEY_CURRENT_USER hive.
Write-access to the registry is blocked, including access to any per-user registry keys. From the app's
perspective, write access to the registry should never be relied upon in the Azure environment since apps can
(and do) get migrated across different virtual machines. The only persistent writeable storage that can be
depended on by an app is the per-app content directory structure stored on the App Service UNC shares.
More information
Azure App Service sandbox - The most up-to-date information about the execution environment of App Service.
This page is maintained directly by the App Service development team.
Deployment Best Practices
5/18/2022 • 7 minutes to read • Edit Online
Every development team has unique requirements that can make implementing an efficient deployment
pipeline difficult on any cloud service. This article introduces the three main components of deploying to App
Service: deployment sources, build pipelines, and deployment mechanisms. This article also covers some best
practices and tips for specific language stacks.
Deployment Components
Deployment Source
A deployment source is the location of your application code. For production apps, the deployment source is
usually a repository hosted by version control software such as GitHub, BitBucket, or Azure Repos. For
development and test scenarios, the deployment source may be a project on your local machine. App Service
also supports OneDrive and Dropbox folders as deployment sources. While cloud folders can make it easy to
get started with App Service, it is not typically recommended to use this source for enterprise-level production
applications.
Build Pipeline
Once you decide on a deployment source, your next step is to choose a build pipeline. A build pipeline reads
your source code from the deployment source and executes a series of steps (such as compiling code, minifying
HTML and JavaScript, running tests, and packaging components) to get the application in a runnable state. The
specific commands executed by the build pipeline depend on your language stack. These operations can be
executed on a build server such as Azure Pipelines, or executed locally.
Deployment Mechanism
The deployment mechanism is the action used to put your built application into the /home/site/wwwroot
directory of your web app. The /wwwroot directory is a mounted storage location shared by all instances of
your web app. When the deployment mechanism puts your application in this directory, your instances receive a
notification to sync the new files. App Service supports the following deployment mechanisms:
Kudu endpoints: Kudu is the open-source developer productivity tool that runs as a separate process in
Windows App Service, and as a second container in Linux App Service. Kudu handles continuous
deployments and provides HTTP endpoints for deployment, such as zipdeploy.
FTP and WebDeploy: Using your site or user credentials, you can upload files via FTP or WebDeploy. These
mechanisms do not go through Kudu.
Deployment tools such as Azure Pipelines, Jenkins, and editor plugins use one of these deployment
mechanisms.
on:
push:
branches:
- <your-branch-name>
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- uses: azure/container-actions/docker-login@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push the image tagged with the git commit hash
run: |
docker build . -t contoso/demo:${{ github.sha }}
docker push contoso/demo:${{ github.sha }}
In your script, log in using , providing the principal’s information. You can then use
az login --service-principal
az webapp config container set to set the container name, tag, registry URL, and registry password. Below are
some helpful links for you to construct your container CI process.
How to log into the Azure CLI on Circle CI
Language-Specific Considerations
Java
Use the Kudu zipdeploy/ API for deploying JAR applications, and wardeploy/ for WAR apps. If you are using
Jenkins, you can use those APIs directly in your deployment phase. For more information, see this article.
Node
By default, Kudu executes the build steps for your Node application ( npm install ). If you are using a build
service such as Azure DevOps, then the Kudu build is unnecessary. To disable the Kudu build, create an app
setting, SCM_DO_BUILD_DURING_DEPLOYMENT , with a value of false .
.NET
By default, Kudu executes the build steps for your .NET application ( dotnet build ). If you are using a build
service such as Azure DevOps, then the Kudu build is unnecessary. To disable the Kudu build, create an app
setting, SCM_DO_BUILD_DURING_DEPLOYMENT , with a value of false .
More resources
Environment variables and app settings reference
App Service, Functions, and Logic Apps on Azure
Arc (Preview)
5/18/2022 • 10 minutes to read • Edit Online
You can run App Service, Functions, and Logic Apps on an Azure Arc-enabled Kubernetes cluster. The Kubernetes
cluster can be on-premises or hosted in a third-party cloud. This approach lets app developers take advantage
of the features of App Service. At the same time, it lets their IT administrators maintain corporate compliance by
hosting the App Service apps on internal infrastructure. It also lets other IT operators safeguard their prior
investments in other cloud providers by running App Service on existing Kubernetes clusters.
NOTE
To learn how to set up your Kubernetes cluster for App Service, Functions, and Logic Apps, see Create an App Service
Kubernetes environment (Preview).
In most cases, app developers need to know nothing more than how to deploy to the correct Azure region that
represents the deployed Kubernetes environment. For operators who provide the environment and maintain the
underlying Kubernetes infrastructure, you must be aware of the following Azure resources:
The connected cluster, which is an Azure projection of your Kubernetes infrastructure. For more information,
see What is Azure Arc-enabled Kubernetes?.
A cluster extension, which is a subresource of the connected cluster resource. The App Service extension
installs the required pods into your connected cluster. For more information about cluster extensions, see
Cluster extensions on Azure Arc-enabled Kubernetes.
A custom location, which bundles together a group of extensions and maps them to a namespace for created
resources. For more information, see Custom locations on top of Azure Arc-enabled Kubernetes.
An App Service Kubernetes environment, which enables configuration common across apps but not related
to cluster operations. Conceptually, it's deployed into the custom location resource, and app developers
create apps into this environment. This resource is described in greater detail in App Service Kubernetes
environment.
L IM ITAT IO N DETA IL S
Cluster storage requirement Must have cluster attached storage class available for use by
the extension to support deployment and build of code-
based apps where applicable
Feature: Pull images from ACR with managed identity Not available (depends on managed identities)
Feature: In-portal editing for Functions and Logic Apps Not available
Feature: Portal listing of Functions or keys Not available if cluster is not publicly reachable
<extensionName>-k8se-app-controller The core operator pod that creates resources on the cluster
and maintains the state of components.
<extensionName>-k8se-img-cacher Pulls placeholder and app images into a local cache on the
node.
<extensionName>-k8se-log-processor Gathers logs from apps and other components and sends
them to Log Analytics.
FAQ for App Service, Functions, and Logic Apps on Azure Arc
(Preview)
How much does it cost?
Are both Windows and Linux apps supported?
Which built-in application stacks are supported?
Are all app deployment types supported?
Which App Service features are supported?
Are all networking features supported?
Are managed identities supported?
Are there any scaling limits?
What logs are collected?
What do I do if I see a provider registration error?
Can I deploy the Application services extension on an ARM64 based cluster?
How much does it cost?
App Service on Azure Arc is free during the public preview.
Are both Windows and Linux apps supported?
Only Linux-based apps are supported, both code and custom containers. Windows apps are not supported.
Which built-in application stacks are supported?
All built-in Linux stacks are supported.
Are all app deployment types supported?
FTP deployment is not supported. Currently az webapp up is also not supported. Other deployment methods
are supported, including Git, ZIP, CI/CD, Visual Studio, and Visual Studio Code.
Which App Service features are supported?
During the preview period, certain App Service features are being validated. When they're supported, their left
navigation options in the Azure portal will be activated. Features that are not yet supported remain grayed out.
Are all networking features supported?
No. Networking features such as hybrid connections or Virtual Network integration, are not supported. Access
restriction support was added in April 2022. Networking should be handled directly in the networking rules in
the Kubernetes cluster itself.
Are managed identities supported?
No. Apps cannot be assigned managed identities when running in Azure Arc. If your app needs an identity for
working with another Azure resource, consider using an application service principal instead.
Are there any scaling limits?
All applications deployed with Azure App Service on Kubernetes with Azure Arc are able to scale within the
limits of the underlying Kubernetes cluster. If the underlying Kubernetes Cluster runs out of available compute
resources (CPU and memory primarily), then applications will only be able to scale to the number of instances
of the application that Kubernetes can schedule with available resource.
What logs are collected?
Logs for both system components and your applications are written to standard output. Both log types can be
collected for analysis using standard Kubernetes tools. You can also configure the App Service cluster extension
with a Log Analytics workspace, and it sends all logs to that workspace.
By default, logs from system components are sent to the Azure team. Application logs are not sent. You can
prevent these logs from being transferred by setting logProcessor.enabled=false as an extension configuration
setting. This configuration setting will also disable forwarding of application to your Log Analytics workspace.
Disabling the log processor might impact time needed for any support cases, and you will be asked to collect
logs from standard output through some other means.
What do I do if I see a provider registration error?
When creating a Kubernetes environment resource, some subscriptions might see a "No registered resource
provider found" error. The error details might include a set of locations and api versions that are considered
valid. If this error message is returned, the subscription must be re-registered with the Microsoft.Web provider,
an operation that has no impact on existing applications or APIs. To re-register, use the Azure CLI to run
az provider register --namespace Microsoft.Web --wait . Then reattempt the Kubernetes environment command.
Next steps
Create an App Service Kubernetes environment (Preview)
Azure App Service monitoring overview
5/18/2022 • 2 minutes to read • Edit Online
Azure App Service provides several monitoring options for monitoring resources for availability, performance,
and operation. Options such as Diagnostic Settings, Application Insights, Log stream, Metrics, Quotas and alerts,
and Activity logs. This article aims to bring clarity on monitoring options on App Service and provide scenarios
when each should be used.
Metrics
Build visualizations of metrics on Azure resources (web apps and App Service Plans). Metrics can be viewed by
aggregates on data (ie. average, max, min, etc), instances, time range, and other filters. Metrics can monitor
performance, memory, CPU, and other attributes.
Activity logs
View a historical log of events changing your resource. Resource events help you understand any changes that
were made to your underlying web app resources and take action as necessary. Event examples include scaling
of instances, updates to application settings, restarting of the web app, and many more.
Monitoring scenarios
The table below lists monitoring methods to use for different scenarios.
I want to monitor platform metrics and logs (Azure Monitor) Diagnostic Settings
I want to monitor application performance and usage (Azure Monitor) Application Insights
I want to monitor built-in logs for testing and development Log stream
I want to monitor resource limits and configure alerts Quotas and alerts
Next steps
Query logs with Azure Monitor
How to Monitor Azure App Service
Troubleshooting Azure App Service with Azure Monitor
Monitor App Service with Azure Monitor
Security recommendations for App Service
5/18/2022 • 4 minutes to read • Edit Online
This article contains security recommendations for Azure App Service. Implementing these recommendations
will help you fulfill your security obligations as described in our shared responsibility model and will improve
the overall security for your Web App solutions. For more information on what Microsoft does to fulfill service
provider responsibilities, read Azure infrastructure security.
General
REC O M M EN DAT IO N C O M M EN T S
Disable anonymous access Unless you need to support anonymous requests, disable
anonymous access. For more information on Azure App
Service authentication options, see Authentication and
authorization in Azure App Service.
Protect back-end resources with authenticated access You can either use the user's identity or use an application
identity to authenticate to a back-end resource. When you
choose to use an application identity use a managed
identity.
Require client certificate authentication Client certificate authentication improves security by only
allowing connections from clients that can authenticate
using certificates that you provide.
Data protection
REC O M M EN DAT IO N C O M M EN T S
Redirect HTTP to HTTPs By default, clients can connect to web apps by using both
HTTP or HTTPS. We recommend redirecting HTTP to HTTPs
because HTTPS uses the SSL/TLS protocol to provide a
secure connection, which is both encrypted and
authenticated.
REC O M M EN DAT IO N C O M M EN T S
Encrypt communication to Azure resources When your app connects to Azure resources, such as SQL
Database or Azure Storage, the connection stays in Azure.
Since the connection goes through the shared networking in
Azure, you should always encrypt all communication.
Require the latest TLS version possible Since 2018 new Azure App Service apps use TLS 1.2. Newer
versions of TLS include security improvements over older
protocol versions.
Use FTPS App Service supports both FTP and FTPS for deploying your
files. Use FTPS instead of FTP when possible. When one or
both of these protocols are not in use, you should disable
them.
Secure application data Don't store application secrets, such as database credentials,
API tokens, or private keys in your code or configuration
files. The commonly accepted approach is to access them as
environment variables using the standard pattern in your
language of choice. In Azure App Service, you can define
environment variables through app settings and connection
strings. App settings and connection strings are stored
encrypted in Azure. The app settings are decrypted only
before being injected into your app's process memory when
the app starts. The encryption keys are rotated regularly.
Alternatively, you can integrate your Azure App Service app
with Azure Key Vault for advanced secrets management. By
accessing the Key Vault with a managed identity, your App
Service app can securely access the secrets you need.
Secure application code Follow the steps to ensure the application code is secured.
Hidden Folders Ensure hidden folders like .git, bin, obj, objd, etc., doesn’t get
accidentally included as part of deployment artifact. Take
adequate steps to ensure deployment scripts only deploy
required files and nothing more.
Networking
REC O M M EN DAT IO N C O M M EN T S
Use static IP restrictions Azure App Service on Windows lets you define a list of IP
addresses that are allowed to access your app. The allowed
list can include individual IP addresses or a range of IP
addresses defined by a subnet mask. For more information,
see Azure App Service Static IP Restrictions.
Use the isolated pricing tier Except for the isolated pricing tier, all tiers run your apps on
the shared network infrastructure in Azure App Service. The
isolated tier gives you complete network isolation by
running your apps inside a dedicated App Service
environment. An App Service environment runs in your own
instance of Azure Virtual Network.
Use secure connections when accessing on-premises You can use Hybrid connections, Virtual Network integration,
resources or App Service environment's to connect to on-premises
resources.
Limit exposure to inbound network traffic Network security groups allow you to restrict network access
and control the number of exposed endpoints. For more
information, see How To Control Inbound Traffic to an App
Service Environment.
Monitoring
REC O M M EN DAT IO N C O M M EN T S
Use Microsoft Defender for Cloud's Microsoft Defender for Microsoft Defender for App Service is natively integrated
App Service with Azure App Service. Defender for Cloud assesses the
resources covered by your App Service plan and generates
security recommendations based on its findings. Use the
detailed instructions in these recommendations to harden
your App Service resources. Microsoft Defender for Cloud
also provides threat protection and can detect a multitude of
threats covering almost the complete list of MITRE ATT&CK
tactics from pre-attack to command and control. For a full
list of the Azure App Service alerts, see Microsoft Defender
for App Service alerts.
Next steps
Check with your application provider to see if there are additional security requirements. For more information
on developing secure applications, see Secure Development Documentation.
Authentication and authorization in Azure App
Service and Azure Functions
5/18/2022 • 8 minutes to read • Edit Online
Azure App Service provides built-in authentication and authorization capabilities (sometimes referred to as
"Easy Auth"), so you can sign in users and access data by writing minimal or no code in your web app, RESTful
API, and mobile back end, and also Azure Functions. This article describes how App Service helps simplify
authentication and authorization for your app.
Identity providers
App Service uses federated identity, in which a third-party identity provider manages the user identities and
authentication flow for you. The following identity providers are available by default:
Any OpenID Connect provider /.auth/login/<providerName> App Service OpenID Connect login
When you enable authentication and authorization with one of these providers, its sign-in endpoint is available
for user authentication and for validation of authentication tokens from the provider. You can provide your users
with any number of these sign-in options.
Considerations for using built-in authentication
Enabling this feature will causeall requests to your application to be automatically redirected to HTTPS,
regardless of the App Service configuration setting to enforce HTTPS. You can disable this with the
requireHttps setting in the V2 configuration. However, we do recommend sticking with HTTPS, and you should
ensure no security tokens ever get transmitted over non-secure HTTP connections.
App Service can be used for authentication with or without restricting access to your site content and APIs. To
restrict app access only to authenticated users, set Action to take when request is not authenticated to log
in with one of the configured identity providers. To authenticate but not restrict access, set Action to take
when request is not authenticated to "Allow anonymous requests (no action)."
NOTE
You should give each app registration its own permission and consent. Avoid permission sharing between environments
by using separate app registrations for separate deployment slots. When testing new code, this practice can help prevent
issues from affecting the production app.
How it works
Feature architecture
Authentication flow
Authorization behavior
Token store
Logging and tracing
Feature architecture
The authentication and authorization middleware component is a feature of the platform that runs on the same
VM as your application. When it's enabled, every incoming HTTP request passes through it before being handled
by your application.
1. Sign user in Redirects client to Client code signs user in directly with
/.auth/login/<provider> . provider's SDK and receives an
authentication token. For information,
see the provider's documentation.
2. Post-authentication Provider redirects client to Client code posts token from provider
/.auth/login/<provider>/callback . to /.auth/login/<provider> for
validation.
3. Establish authenticated session App Service adds authenticated cookie App Service returns its own
to response. authentication token to client code.
ST EP W IT H O UT P RO VIDER SDK W IT H P RO VIDER SDK
4. Serve authenticated content Client includes authentication cookie in Client code presents authentication
subsequent requests (automatically token in X-ZUMO-AUTH header
handled by browser). (automatically handled by Mobile Apps
client SDKs).
For client browsers, App Service can automatically direct all unauthenticated users to /.auth/login/<provider> .
You can also present users with one or more /.auth/login/<provider> links to sign in to your app using their
provider of choice.
Authorization behavior
In the Azure portal, you can configure App Service with a number of behaviors when incoming request is not
authenticated. The following headings describe the options.
Allow unauthenticated requests
This option defers authorization of unauthenticated traffic to your application code. For authenticated requests,
App Service also passes along authentication information in the HTTP headers.
This option provides more flexibility in handling anonymous requests. For example, it lets you present multiple
sign-in providers to your users. However, you must write code.
Require authentication
This option will reject any unauthenticated traffic to your application. This rejection can be a redirect action to
one of the configured identity providers. In these cases, a browser client is redirected to
/.auth/login/<provider> for the provider you choose. If the anonymous request comes from a native mobile
app, the returned response is an HTTP 401 Unauthorized . You can also configure the rejection to be an
HTTP 401 Unauthorized or HTTP 403 Forbidden for all requests.
With this option, you don't need to write any authentication code in your app. Finer authorization, such as role-
specific authorization, can be handled by inspecting the user's claims (see Access user claims).
Cau t i on
Restricting access in this way applies to all calls to your app, which may not be desirable for apps wanting a
publicly available home page, as in many single-page applications.
NOTE
By default, any user in your Azure AD tenant can request a token for your application from Azure AD. You can configure
the application in Azure AD if you want to restrict access to your app to a defined set of users.
Token store
App Service provides a built-in token store, which is a repository of tokens that are associated with the users of
your web apps, APIs, or native mobile apps. When you enable authentication with any provider, this token store
is immediately available to your app. If your application code needs to access data from these providers on the
user's behalf, such as:
post to the authenticated user's Facebook timeline
read the user's corporate data using the Microsoft Graph API
You typically must write code to collect, store, and refresh these tokens in your application. With the token store,
you just retrieve the tokens when you need them and tell App Service to refresh them when they become
invalid.
The ID tokens, access tokens, and refresh tokens are cached for the authenticated session, and they're accessible
only by the associated user.
If you don't need to work with tokens in your app, you can disable the token store in your app's Authentication
/ Authorization page.
Logging and tracing
If you enable application logging, you will see authentication and authorization traces directly in your log files. If
you see an authentication error that you didn't expect, you can conveniently find all the details by looking in
your existing application logs. If you enable failed request tracing, you can see exactly what role the
authentication and authorization module may have played in a failed request. In the trace logs, look for
references to a module named EasyAuthModule_32/64 .
More resources
How-To: Configure your App Service or Azure Functions app to use Azure AD login
Customize sign-ins and sign-outs
Work with OAuth tokens and sessions
Access user and application claims
File-based configuration
Samples:
Tutorial: Add authentication to your web app running on Azure App Service
Tutorial: Authenticate and authorize users end-to-end in Azure App Service (Windows or Linux)
.NET Core integration of Azure AppService EasyAuth (3rd party)
Getting Azure App Service authentication working with .NET Core (3rd party)
OS and runtime patching in Azure App Service
5/18/2022 • 4 minutes to read • Edit Online
This article shows you how to get certain version information regarding the OS or software in App Service.
App Service is a Platform-as-a-Service, which means that the OS and application stack are managed for you by
Azure; you only manage your application and its data. More control over the OS and application stack is
available you in Azure Virtual Machines. With that in mind, it is nevertheless helpful for you as an App Service
user to know more information, such as:
How and when are OS updates applied?
How is App Service patched against significant vulnerabilities (such as zero-day)?
Which OS and runtime versions are running your apps?
For security reasons, certain specifics of security information are not published. However, the article aims to
alleviate concerns by maximizing transparency on the process, and how you can stay up-to-date on security-
related announcements or runtime updates.
NOTE
Information here applies to language runtimes that are built into an App Service app. A custom runtime you upload to
App Service, for example, remains unchanged unless you manually upgrade it.
NOTE
This example uses the recommended "tilde syntax" to target the latest available version of Node.js 16 runtime on
Windows App Service.
IN F O RM AT IO N W H ERE TO F IN D IT
.NET version At
https://<appname>.scm.azurewebsites.net/DebugConsole
, run the following command in the command prompt:
reg query
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET
Framework Setup\NDP\v4\Full"
PHP version At
https://<appname>.scm.azurewebsites.net/DebugConsole
, run the following command in the command prompt:
php --version
IN F O RM AT IO N W H ERE TO F IN D IT
Default Node.js version In the Cloud Shell, run the following command:
az webapp config appsettings list --resource-group
<groupname> --name <appname> --query "[?
name=='WEBSITE_NODE_DEFAULT_VERSION']"
Python version At
https://<appname>.scm.azurewebsites.net/DebugConsole
, run the following command in the command prompt:
python --version
Java version At
https://<appname>.scm.azurewebsites.net/DebugConsole
, run the following command in the command prompt:
java -version
NOTE
Access to registry location
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages , where
information on "KB" patches is stored, is locked down.
More resources
Trust Center: Security
64 bit ASP.NET Core on Azure App Service
Azure Policy Regulatory Compliance controls for
Azure App Service
5/18/2022 • 78 minutes to read • Edit Online
Regulatory Compliance in Azure Policy provides Microsoft created and managed initiative definitions, known as
built-ins, for the compliance domains and security controls related to different compliance standards. This
page lists the compliance domains and security controls for Azure App Service. You can assign the built-ins
for a security control individually to help make your Azure resources compliant with the specific standard.
The title of each built-in policy definition links to the policy definition in the Azure portal. Use the link in the
Policy Version column to view the source on the Azure Policy GitHub repo.
IMPORTANT
Each control below is associated with one or more Azure Policy definitions. These policies may help you assess compliance
with the control; however, there often is not a one-to-one or complete match between a control and one or more policies.
As such, Compliant in Azure Policy refers only to the policies themselves; this doesn't ensure you're fully compliant with
all requirements of a control. In addition, the compliance standard includes controls that aren't addressed by any Azure
Policy definitions at this time. Therefore, compliance in Azure Policy is only a partial view of your overall compliance status.
The associations between controls and Azure Policy Regulatory Compliance definitions for these compliance standards
may change over time.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
SWIFT Environment SWIFT CSCF v2021 SWIFT Environment App Service should 1.0.0
Protection 1.1 Protection use a virtual network
service endpoint
SWIFT Environment SWIFT CSCF v2021 SWIFT Environment Remote debugging 1.0.0
Protection 1.1 Protection should be turned off
for API Apps
SWIFT Environment SWIFT CSCF v2021 SWIFT Environment Remote debugging 1.0.0
Protection 1.1 Protection should be turned off
for Function Apps
SWIFT Environment SWIFT CSCF v2021 SWIFT Environment Remote debugging 1.0.0
Protection 1.1 Protection should be turned off
for Web Applications
SWIFT Environment SWIFT CSCF v2021 Operating System Remote debugging 1.0.0
Protection 1.2 Privileged Account should be turned off
Control for API Apps
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
SWIFT Environment SWIFT CSCF v2021 Operating System Remote debugging 1.0.0
Protection 1.2 Privileged Account should be turned off
Control for Function Apps
SWIFT Environment SWIFT CSCF v2021 Operating System Remote debugging 1.0.0
Protection 1.2 Privileged Account should be turned off
Control for Web Applications
Reduce Attack SWIFT CSCF v2021 Internal Data Flow API App should only 1.0.0
Surface and 2.1 Security be accessible over
Vulnerabilities HTTPS
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Ensure WEB app has 1.0.0
Surface and 2.1 Security 'Client Certificates
Vulnerabilities (Incoming client
certificates)' set to
'On'
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Function App should 1.0.0
Surface and 2.1 Security only be accessible
Vulnerabilities over HTTPS
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Latest TLS version 1.0.0
Surface and 2.1 Security should be used in
Vulnerabilities your API App
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Latest TLS version 1.0.0
Surface and 2.1 Security should be used in
Vulnerabilities your Function App
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Latest TLS version 1.0.0
Surface and 2.1 Security should be used in
Vulnerabilities your Web App
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Managed identity 2.0.0
Surface and 2.1 Security should be used in
Vulnerabilities your API App
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Managed identity 2.0.0
Surface and 2.1 Security should be used in
Vulnerabilities your Function App
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Managed identity 2.0.0
Surface and 2.1 Security should be used in
Vulnerabilities your Web App
Reduce Attack SWIFT CSCF v2021 Internal Data Flow Web Application 1.0.0
Surface and 2.1 Security should only be
Vulnerabilities accessible over
HTTPS
Reduce Attack SWIFT CSCF v2021 Back-office Data Flow API App should only 1.0.0
Surface and 2.4A Security be accessible over
Vulnerabilities HTTPS
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Reduce Attack SWIFT CSCF v2021 Back-office Data Flow Ensure WEB app has 1.0.0
Surface and 2.4A Security 'Client Certificates
Vulnerabilities (Incoming client
certificates)' set to
'On'
Reduce Attack SWIFT CSCF v2021 Back-office Data Flow Function App should 1.0.0
Surface and 2.4A Security only be accessible
Vulnerabilities over HTTPS
Reduce Attack SWIFT CSCF v2021 Back-office Data Flow Web Application 1.0.0
Surface and 2.4A Security should only be
Vulnerabilities accessible over
HTTPS
Reduce Attack SWIFT CSCF v2021 External Transmission API App should only 1.0.0
Surface and 2.5A Data Protection be accessible over
Vulnerabilities HTTPS
Reduce Attack SWIFT CSCF v2021 External Transmission Function App should 1.0.0
Surface and 2.5A Data Protection only be accessible
Vulnerabilities over HTTPS
Reduce Attack SWIFT CSCF v2021 External Transmission Web Application 1.0.0
Surface and 2.5A Data Protection should only be
Vulnerabilities accessible over
HTTPS
Reduce Attack SWIFT CSCF v2021 Operator Session Latest TLS version 1.0.0
Surface and 2.6 Confidentiality and should be used in
Vulnerabilities Integrity your API App
Reduce Attack SWIFT CSCF v2021 Operator Session Latest TLS version 1.0.0
Surface and 2.6 Confidentiality and should be used in
Vulnerabilities Integrity your Function App
Reduce Attack SWIFT CSCF v2021 Operator Session Latest TLS version 1.0.0
Surface and 2.6 Confidentiality and should be used in
Vulnerabilities Integrity your Web App
Manage Identities SWIFT CSCF v2021 Token Management Managed identity 2.0.0
and Segregate 5.2 should be used in
Privileges your API App
Manage Identities SWIFT CSCF v2021 Token Management Managed identity 2.0.0
and Segregate 5.2 should be used in
Privileges your Function App
Manage Identities SWIFT CSCF v2021 Token Management Managed identity 2.0.0
and Segregate 5.2 should be used in
Privileges your Web App
Manage Identities SWIFT CSCF v2021 Physical and Logical Managed identity 2.0.0
and Segregate 5.4 Password Storage should be used in
Privileges your API App
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Manage Identities SWIFT CSCF v2021 Physical and Logical Managed identity 2.0.0
and Segregate 5.4 Password Storage should be used in
Privileges your Function App
Manage Identities SWIFT CSCF v2021 Physical and Logical Managed identity 2.0.0
and Segregate 5.4 Password Storage should be used in
Privileges your Web App
Detect Anomalous SWIFT CSCF v2021 Software Integrity Remote debugging 1.0.0
Activity to Systems 6.2 should be turned off
or Transaction for API Apps
Records
Detect Anomalous SWIFT CSCF v2021 Software Integrity Remote debugging 1.0.0
Activity to Systems 6.2 should be turned off
or Transaction for Function Apps
Records
Detect Anomalous SWIFT CSCF v2021 Software Integrity Remote debugging 1.0.0
Activity to Systems 6.2 should be turned off
or Transaction for Web Applications
Records
Detect Anomalous SWIFT CSCF v2021 Intrusion Detection CORS should not 1.0.0
Activity to Systems 6.5A allow every resource
or Transaction to access your API
Records App
Detect Anomalous SWIFT CSCF v2021 Intrusion Detection CORS should not 1.0.0
Activity to Systems 6.5A allow every resource
or Transaction to access your
Records Function Apps
Detect Anomalous SWIFT CSCF v2021 Intrusion Detection CORS should not 1.0.0
Activity to Systems 6.5A allow every resource
or Transaction to access your Web
Records Applications
Detect Anomalous SWIFT CSCF v2021 Intrusion Detection Remote debugging 1.0.0
Activity to Systems 6.5A should be turned off
or Transaction for API Apps
Records
Detect Anomalous SWIFT CSCF v2021 Intrusion Detection Remote debugging 1.0.0
Activity to Systems 6.5A should be turned off
or Transaction for Function Apps
Records
Detect Anomalous SWIFT CSCF v2021 Intrusion Detection Remote debugging 1.0.0
Activity to Systems 6.5A should be turned off
or Transaction for Web Applications
Records
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Guidelines for 1552 Web application API App should only 1.0.0
Software interactions - 1552 be accessible over
Development - Web HTTPS
application
development
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Network Security NS-8 Detect and disable Latest TLS version 1.0.0
insecure services and should be used in
protocols your API App
Network Security NS-8 Detect and disable Latest TLS version 1.0.0
insecure services and should be used in
protocols your Function App
Network Security NS-8 Detect and disable Latest TLS version 1.0.0
insecure services and should be used in
protocols your Web App
Data Protection DP-3 Encrypt sensitive API App should only 1.0.0
data in transit be accessible over
HTTPS
Logging and Threat LT-3 Enable logging for Resource logs in App 2.0.0
Detection security investigation Services should be
enabled
Posture and PV-2 Audit and enforce CORS should not 1.0.0
Vulnerability secure configurations allow every resource
Management to access your API
App
Posture and PV-2 Audit and enforce CORS should not 1.0.0
Vulnerability secure configurations allow every resource
Management to access your
Function Apps
Posture and PV-2 Audit and enforce CORS should not 1.0.0
Vulnerability secure configurations allow every resource
Management to access your Web
Applications
Posture and PV-2 Audit and enforce Ensure API app has 1.0.0
Vulnerability secure configurations 'Client Certificates
Management (Incoming client
certificates)' set to
'On'
Posture and PV-2 Audit and enforce Ensure WEB app has 1.0.0
Vulnerability secure configurations 'Client Certificates
Management (Incoming client
certificates)' set to
'On'
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Posture and PV-2 Audit and enforce Function apps should 1.0.1
Vulnerability secure configurations have 'Client
Management Certificates
(Incoming client
certificates)' enabled
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Network Security 1.3 Protect critical web CORS should not 1.0.0
applications allow every resource
to access your API
App
Network Security 1.3 Protect critical web CORS should not 1.0.0
applications allow every resource
to access your
Function Apps
Network Security 1.3 Protect critical web CORS should not 1.0.0
applications allow every resource
to access your Web
Applications
Network Security 1.3 Protect critical web Ensure WEB app has 1.0.0
applications 'Client Certificates
(Incoming client
certificates)' set to
'On'
Logging and 2.3 Enable audit logging Resource logs in App 2.0.0
Monitoring for Azure resources Services should be
enabled
Data Protection 4.4 Encrypt all sensitive API App should only 1.0.0
information in transit be accessible over
HTTPS
Data Protection 4.4 Encrypt all sensitive FTPS only should be 2.0.0
information in transit required in your API
App
Data Protection 4.4 Encrypt all sensitive FTPS only should be 2.0.0
information in transit required in your
Function App
Data Protection 4.4 Encrypt all sensitive Function App should 1.0.0
information in transit only be accessible
over HTTPS
Data Protection 4.4 Encrypt all sensitive Latest TLS version 1.0.0
information in transit should be used in
your API App
Data Protection 4.4 Encrypt all sensitive Latest TLS version 1.0.0
information in transit should be used in
your Function App
Data Protection 4.4 Encrypt all sensitive Latest TLS version 1.0.0
information in transit should be used in
your Web App
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
AppService CIS Microsoft Azure Ensure that 'HTTP Ensure that 'HTTP 2.0.0
Foundations Version' is the latest, Version' is the latest,
Benchmark if used to run the if used to run the API
recommendation web app app
9.10
AppService CIS Microsoft Azure Ensure that 'HTTP Ensure that 'HTTP 2.0.0
Foundations Version' is the latest, Version' is the latest,
Benchmark if used to run the if used to run the
recommendation web app Function app
9.10
AppService CIS Microsoft Azure Ensure that 'HTTP Ensure that 'HTTP 2.0.0
Foundations Version' is the latest, Version' is the latest,
Benchmark if used to run the if used to run the
recommendation web app Web app
9.10
AppService CIS Microsoft Azure Ensure web app Web Application 1.0.0
Foundations redirects all HTTP should only be
Benchmark traffic to HTTPS in accessible over
recommendation 9.2 Azure App Service HTTPS
AppService CIS Microsoft Azure Ensure web app is Latest TLS version 1.0.0
Foundations using the latest should be used in
Benchmark version of TLS your API App
recommendation 9.3 encryption
AppService CIS Microsoft Azure Ensure web app is Latest TLS version 1.0.0
Foundations using the latest should be used in
Benchmark version of TLS your Function App
recommendation 9.3 encryption
AppService CIS Microsoft Azure Ensure web app is Latest TLS version 1.0.0
Foundations using the latest should be used in
Benchmark version of TLS your Web App
recommendation 9.3 encryption
AppService CIS Microsoft Azure Ensure the web app Ensure API app has 1.0.0
Foundations has 'Client 'Client Certificates
Benchmark Certificates (Incoming client
recommendation 9.4 (Incoming client certificates)' set to
certificates)' set to 'On'
'On'
AppService CIS Microsoft Azure Ensure the web app Ensure WEB app has 1.0.0
Foundations has 'Client 'Client Certificates
Benchmark Certificates (Incoming client
recommendation 9.4 (Incoming client certificates)' set to
certificates)' set to 'On'
'On'
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
AppService CIS Microsoft Azure Ensure the web app Function apps should 1.0.1
Foundations has 'Client have 'Client
Benchmark Certificates Certificates
recommendation 9.4 (Incoming client (Incoming client
certificates)' set to certificates)' enabled
'On'
AppService CIS Microsoft Azure Ensure that Register Managed identity 2.0.0
Foundations with Azure Active should be used in
Benchmark Directory is enabled your API App
recommendation 9.5 on App Service
AppService CIS Microsoft Azure Ensure that Register Managed identity 2.0.0
Foundations with Azure Active should be used in
Benchmark Directory is enabled your Function App
recommendation 9.5 on App Service
AppService CIS Microsoft Azure Ensure that Register Managed identity 2.0.0
Foundations with Azure Active should be used in
Benchmark Directory is enabled your Web App
recommendation 9.5 on App Service
AppService CIS Microsoft Azure Ensure that 'PHP Ensure that 'PHP 2.1.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.7 web app the API app
AppService CIS Microsoft Azure Ensure that 'PHP Ensure that 'PHP 2.2.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.7 web app the WEB app
AppService CIS Microsoft Azure Ensure that 'Python Ensure that 'Python 3.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.8 web app the API app
AppService CIS Microsoft Azure Ensure that 'Python Ensure that 'Python 3.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.8 web app the Function app
AppService CIS Microsoft Azure Ensure that 'Python Ensure that 'Python 3.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.8 web app the Web app
AppService CIS Microsoft Azure Ensure that 'Java Ensure that 'Java 2.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.9 web app the API app
AppService CIS Microsoft Azure Ensure that 'Java Ensure that 'Java 2.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.9 web app the Function app
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
AppService CIS Microsoft Azure Ensure that 'Java Ensure that 'Java 2.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.9 web app the Web app
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Logging and CIS Microsoft Azure Ensure that Resource logs in App 2.0.0
Monitoring Foundations Diagnostic Logs are Services should be
Benchmark enabled for all enabled
recommendation 5.3 services which
support it.
App Service CIS Microsoft Azure Ensure App Service Authentication 1.0.0
Foundations Authentication is set should be enabled on
Benchmark on Azure App Service your API app
recommendation 9.1
App Service CIS Microsoft Azure Ensure App Service Authentication 2.0.0
Foundations Authentication is set should be enabled on
Benchmark on Azure App Service your Function app
recommendation 9.1
App Service CIS Microsoft Azure Ensure App Service Authentication 2.0.0
Foundations Authentication is set should be enabled on
Benchmark on Azure App Service your web app
recommendation 9.1
App Service CIS Microsoft Azure Ensure FTP FTPS only should be 2.0.0
Foundations deployments are required in your API
Benchmark disabled App
recommendation
9.10
App Service CIS Microsoft Azure Ensure FTP FTPS only should be 2.0.0
Foundations deployments are required in your
Benchmark disabled Function App
recommendation
9.10
App Service CIS Microsoft Azure Ensure FTP FTPS should be 2.0.0
Foundations deployments are required in your Web
Benchmark disabled App
recommendation
9.10
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
App Service CIS Microsoft Azure Ensure web app Web Application 1.0.0
Foundations redirects all HTTP should only be
Benchmark traffic to HTTPS in accessible over
recommendation 9.2 Azure App Service HTTPS
App Service CIS Microsoft Azure Ensure web app is Latest TLS version 1.0.0
Foundations using the latest should be used in
Benchmark version of TLS your API App
recommendation 9.3 encryption
App Service CIS Microsoft Azure Ensure web app is Latest TLS version 1.0.0
Foundations using the latest should be used in
Benchmark version of TLS your Function App
recommendation 9.3 encryption
App Service CIS Microsoft Azure Ensure web app is Latest TLS version 1.0.0
Foundations using the latest should be used in
Benchmark version of TLS your Web App
recommendation 9.3 encryption
App Service CIS Microsoft Azure Ensure the web app Ensure API app has 1.0.0
Foundations has 'Client 'Client Certificates
Benchmark Certificates (Incoming client
recommendation 9.4 (Incoming client certificates)' set to
certificates)' set to 'On'
'On'
App Service CIS Microsoft Azure Ensure the web app Ensure WEB app has 1.0.0
Foundations has 'Client 'Client Certificates
Benchmark Certificates (Incoming client
recommendation 9.4 (Incoming client certificates)' set to
certificates)' set to 'On'
'On'
App Service CIS Microsoft Azure Ensure the web app Function apps should 1.0.1
Foundations has 'Client have 'Client
Benchmark Certificates Certificates
recommendation 9.4 (Incoming client (Incoming client
certificates)' set to certificates)' enabled
'On'
App Service CIS Microsoft Azure Ensure that Register Managed identity 2.0.0
Foundations with Azure Active should be used in
Benchmark Directory is enabled your API App
recommendation 9.5 on App Service
App Service CIS Microsoft Azure Ensure that Register Managed identity 2.0.0
Foundations with Azure Active should be used in
Benchmark Directory is enabled your Function App
recommendation 9.5 on App Service
App Service CIS Microsoft Azure Ensure that Register Managed identity 2.0.0
Foundations with Azure Active should be used in
Benchmark Directory is enabled your Web App
recommendation 9.5 on App Service
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
App Service CIS Microsoft Azure Ensure that 'PHP Ensure that 'PHP 2.1.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.6 web app the API app
App Service CIS Microsoft Azure Ensure that 'PHP Ensure that 'PHP 2.2.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.6 web app the WEB app
App Service CIS Microsoft Azure Ensure that 'Python Ensure that 'Python 3.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.7 web app the API app
App Service CIS Microsoft Azure Ensure that 'Python Ensure that 'Python 3.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.7 web app the Function app
App Service CIS Microsoft Azure Ensure that 'Python Ensure that 'Python 3.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.7 web app the Web app
App Service CIS Microsoft Azure Ensure that 'Java Ensure that 'Java 2.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.8 web app the API app
App Service CIS Microsoft Azure Ensure that 'Java Ensure that 'Java 2.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.8 web app the Function app
App Service CIS Microsoft Azure Ensure that 'Java Ensure that 'Java 2.0.0
Foundations version' is the latest, version' is the latest,
Benchmark if used to run the if used as a part of
recommendation 9.8 web app the Web app
App Service CIS Microsoft Azure Ensure that 'HTTP Ensure that 'HTTP 2.0.0
Foundations Version' is the latest, Version' is the latest,
Benchmark if used to run the if used to run the API
recommendation 9.9 web app app
App Service CIS Microsoft Azure Ensure that 'HTTP Ensure that 'HTTP 2.0.0
Foundations Version' is the latest, Version' is the latest,
Benchmark if used to run the if used to run the
recommendation 9.9 web app Function app
App Service CIS Microsoft Azure Ensure that 'HTTP Ensure that 'HTTP 2.0.0
Foundations Version' is the latest, Version' is the latest,
Benchmark if used to run the if used to run the
recommendation 9.9 web app Web app
CMMC Level 3
To review how the available Azure Policy built-ins for all Azure services map to this compliance standard, see
Azure Policy Regulatory Compliance - CMMC Level 3. For more information about this compliance standard, see
Cybersecurity Maturity Model Certification (CMMC).
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Access Control AC.1.002 Limit information API App should only 1.0.0
system access to the be accessible over
types of transactions HTTPS
and functions that
authorized users are
permitted to execute.
Access Control AC.2.016 Control the flow of CORS should not 1.0.0
CUI in accordance allow every resource
with approved to access your API
authorizations. App
Access Control AC.2.016 Control the flow of CORS should not 1.0.0
CUI in accordance allow every resource
with approved to access your
authorizations. Function Apps
Identification and IA.3.084 Employ replay- API App should only 1.0.0
Authentication resistant be accessible over
authentication HTTPS
mechanisms for
network access to
privileged and
nonprivileged
accounts.
System and SC.1.175 Monitor, control, and API App should only 1.0.0
Communications protect be accessible over
Protection communications (i.e., HTTPS
information
transmitted or
received by
organizational
systems) at the
external boundaries
and key internal
boundaries of
organizational
systems.
System and SC.1.175 Monitor, control, and Function App should 1.0.0
Communications protect only be accessible
Protection communications (i.e., over HTTPS
information
transmitted or
received by
organizational
systems) at the
external boundaries
and key internal
boundaries of
organizational
systems.
System and SC.1.175 Monitor, control, and Latest TLS version 1.0.0
Communications protect should be used in
Protection communications (i.e., your API App
information
transmitted or
received by
organizational
systems) at the
external boundaries
and key internal
boundaries of
organizational
systems.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
System and SC.1.175 Monitor, control, and Latest TLS version 1.0.0
Communications protect should be used in
Protection communications (i.e., your Function App
information
transmitted or
received by
organizational
systems) at the
external boundaries
and key internal
boundaries of
organizational
systems.
System and SC.1.175 Monitor, control, and Latest TLS version 1.0.0
Communications protect should be used in
Protection communications (i.e., your Web App
information
transmitted or
received by
organizational
systems) at the
external boundaries
and key internal
boundaries of
organizational
systems.
System and SC.3.190 Protect the API App should only 1.0.0
Communications authenticity of be accessible over
Protection communications HTTPS
sessions.
System and SI.1.210 Identify, report, and Ensure that 'HTTP 2.0.0
Information Integrity correct information Version' is the latest,
and information if used to run the API
system flaws in a app
timely manner.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
System and SI.1.210 Identify, report, and Ensure that 'HTTP 2.0.0
Information Integrity correct information Version' is the latest,
and information if used to run the
system flaws in a Function app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'HTTP 2.0.0
Information Integrity correct information Version' is the latest,
and information if used to run the
system flaws in a Web app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'Java 2.0.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the API app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'Java 2.0.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the Function app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'Java 2.0.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the Web app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'PHP 2.1.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the API app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'PHP 2.2.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the WEB app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'Python 3.0.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the API app
timely manner.
System and SI.1.210 Identify, report, and Ensure that 'Python 3.0.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the Function app
timely manner.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
System and SI.1.210 Identify, report, and Ensure that 'Python 3.0.0
Information Integrity correct information version' is the latest,
and information if used as a part of
system flaws in a the Web app
timely manner.
System and SI.1.210 Identify, report, and Latest TLS version 1.0.0
Information Integrity correct information should be used in
and information your API App
system flaws in a
timely manner.
System and SI.1.210 Identify, report, and Latest TLS version 1.0.0
Information Integrity correct information should be used in
and information your Function App
system flaws in a
timely manner.
System and SI.1.210 Identify, report, and Latest TLS version 1.0.0
Information Integrity correct information should be used in
and information your Web App
system flaws in a
timely manner.
FedRAMP High
To review how the available Azure Policy built-ins for all Azure services map to this compliance standard, see
Azure Policy Regulatory Compliance - FedRAMP High. For more information about this compliance standard,
see FedRAMP High.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Audit and AU-6 (4) Central Review and Resource logs in App 2.0.0
Accountability Analysis Services should be
enabled
Audit and AU-12 (1) System-wide / Time- Resource logs in App 2.0.0
Accountability correlated Audit Trail Services should be
enabled
System and SC-8 (1) Cryptographic or API App should only 1.0.0
Communications Alternate Physical be accessible over
Protection Protection HTTPS
FedRAMP Moderate
To review how the available Azure Policy built-ins for all Azure services map to this compliance standard, see
Azure Policy Regulatory Compliance - FedRAMP Moderate. For more information about this compliance
standard, see FedRAMP Moderate.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
System and SC-8 (1) Cryptographic or API App should only 1.0.0
Communications Alternate Physical be accessible over
Protection Protection HTTPS
Network Connection 0809.01n2Organizati Network traffic is API App should only 1.0.0
Control onal.1234 - 01.n controlled in be accessible over
accordance with the HTTPS
organizations access
control policy
through firewall and
other network-
related restrictions
for each network
access point or
external
telecommunication
service's managed
interface.
Network Connection 0811.01n2Organizati Exceptions to the API App should only 1.0.0
Control onal.6 - 01.n traffic flow policy are be accessible over
documented with a HTTPS
supporting
mission/business
need, duration of the
exception, and
reviewed at least
annually; traffic flow
policy exceptions are
removed when no
longer supported by
an explicit
mission/business
need.
Network Connection 0812.01n2Organizati Remote devices API App should only 1.0.0
Control onal.8 - 01.n establishing a non- be accessible over
remote connection HTTPS
are not allowed to
communicate with
external (remote)
resources.
Network Connection 0814.01n1Organizati The ability of users to API App should only 1.0.0
Control onal.12 - 01.n connect to the be accessible over
internal network is HTTPS
restricted using a
deny-by-default and
allow-by-exception
policy at managed
interfaces according
to the access control
policy and the
requirements of
clinical and business
applications.
Network Connection 0814.01n1Organizati The ability of users to Function App should 1.0.0
Control onal.12 - 01.n connect to the only be accessible
internal network is over HTTPS
restricted using a
deny-by-default and
allow-by-exception
policy at managed
interfaces according
to the access control
policy and the
requirements of
clinical and business
applications.
Network Connection 0814.01n1Organizati The ability of users to Latest TLS version 1.0.0
Control onal.12 - 01.n connect to the should be used in
internal network is your API App
restricted using a
deny-by-default and
allow-by-exception
policy at managed
interfaces according
to the access control
policy and the
requirements of
clinical and business
applications.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Network Connection 0814.01n1Organizati The ability of users to Latest TLS version 1.0.0
Control onal.12 - 01.n connect to the should be used in
internal network is your Function App
restricted using a
deny-by-default and
allow-by-exception
policy at managed
interfaces according
to the access control
policy and the
requirements of
clinical and business
applications.
Network Connection 0814.01n1Organizati The ability of users to Latest TLS version 1.0.0
Control onal.12 - 01.n connect to the should be used in
internal network is your Web App
restricted using a
deny-by-default and
allow-by-exception
policy at managed
interfaces according
to the access control
policy and the
requirements of
clinical and business
applications.
Identification of Risks 1404.05i2Organizati Due diligence of the API App should only 1.0.0
Related to External onal.1 - 05.i external party be accessible over
Parties includes interviews, HTTPS
document review,
checklists,
certification reviews
(e.g. HITRUST) or
other remote means.
On-line Transactions 0949.09y2Organizati The protocols used API App should only 1.0.0
onal.5 - 09.y for communications be accessible over
are enhanced to HTTPS
address any new
vulnerability, and the
updated versions of
the protocols are
adopted as soon as
possible.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
On-line Transactions 0949.09y2Organizati The protocols used Function App should 1.0.0
onal.5 - 09.y for communications only be accessible
are enhanced to over HTTPS
address any new
vulnerability, and the
updated versions of
the protocols are
adopted as soon as
possible.
On-line Transactions 0949.09y2Organizati The protocols used Latest TLS version 1.0.0
onal.5 - 09.y for communications should be used in
are enhanced to your API App
address any new
vulnerability, and the
updated versions of
the protocols are
adopted as soon as
possible.
On-line Transactions 0949.09y2Organizati The protocols used Latest TLS version 1.0.0
onal.5 - 09.y for communications should be used in
are enhanced to your Function App
address any new
vulnerability, and the
updated versions of
the protocols are
adopted as soon as
possible.
On-line Transactions 0949.09y2Organizati The protocols used Latest TLS version 1.0.0
onal.5 - 09.y for communications should be used in
are enhanced to your Web App
address any new
vulnerability, and the
updated versions of
the protocols are
adopted as soon as
possible.
ISO 27001:2013
To review how the available Azure Policy built-ins for all Azure services map to this compliance standard, see
Azure Policy Regulatory Compliance - ISO 27001:2013. For more information about this compliance standard,
see ISO 27001:2013.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Cryptography 10.1.1 Policy on the use of API App should only 1.0.0
cryptographic be accessible over
controls HTTPS
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Software security SS-9 14.5.8 Web API App should only 1.0.0
applications be accessible over
HTTPS
Access Control and AC-2 16.1.32 System User Managed identity 2.0.0
Passwords Identitfication should be used in
your API App
Access Control and AC-2 16.1.32 System User Managed identity 2.0.0
Passwords Identitfication should be used in
your Function App
Access Control and AC-2 16.1.32 System User Managed identity 2.0.0
Passwords Identitfication should be used in
your Web App
Access Control and AC-17 16.6.9 Events to be Resource logs in App 2.0.0
Passwords logged Services should be
enabled
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Audit and AU-6 (4) Central Review and Resource logs in App 2.0.0
Accountability Analysis Services should be
enabled
Audit and AU-6 (5) Integrated Analysis Resource logs in App 2.0.0
Accountability of Audit Records Services should be
enabled
Audit and AU-12 (1) System-wide and Resource logs in App 2.0.0
Accountability Time-correlated Services should be
Audit Trail enabled
System and SC-8 (1) Cryptographic API App should only 1.0.0
Communications Protection be accessible over
Protection HTTPS
System and SI-2 (6) Removal of Previous Ensure that 'HTTP 2.0.0
Information Integrity Versions of Software Version' is the latest,
and Firmware if used to run the API
app
System and SI-2 (6) Removal of Previous Ensure that 'HTTP 2.0.0
Information Integrity Versions of Software Version' is the latest,
and Firmware if used to run the
Function app
System and SI-2 (6) Removal of Previous Ensure that 'HTTP 2.0.0
Information Integrity Versions of Software Version' is the latest,
and Firmware if used to run the
Web app
System and SI-2 (6) Removal of Previous Ensure that 'Java 2.0.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the API app
System and SI-2 (6) Removal of Previous Ensure that 'Java 2.0.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the Function app
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
System and SI-2 (6) Removal of Previous Ensure that 'Java 2.0.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the Web app
System and SI-2 (6) Removal of Previous Ensure that 'PHP 2.1.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the API app
System and SI-2 (6) Removal of Previous Ensure that 'PHP 2.2.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the WEB app
System and SI-2 (6) Removal of Previous Ensure that 'Python 3.0.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the API app
System and SI-2 (6) Removal of Previous Ensure that 'Python 3.0.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the Function app
System and SI-2 (6) Removal of Previous Ensure that 'Python 3.0.0
Information Integrity Versions of Software version' is the latest,
and Firmware if used as a part of
the Web app
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Requirement 3 PCI DSS v3.2.1 3.4 PCI DSS requirement API App should only 1.0.0
3.4 be accessible over
HTTPS
Requirement 3 PCI DSS v3.2.1 3.4 PCI DSS requirement Function App should 1.0.0
3.4 only be accessible
over HTTPS
Requirement 3 PCI DSS v3.2.1 3.4 PCI DSS requirement Web Application 1.0.0
3.4 should only be
accessible over
HTTPS
Requirement 4 PCI DSS v3.2.1 4.1 PCI DSS requirement API App should only 1.0.0
4.1 be accessible over
HTTPS
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Requirement 4 PCI DSS v3.2.1 4.1 PCI DSS requirement Function App should 1.0.0
4.1 only be accessible
over HTTPS
Requirement 4 PCI DSS v3.2.1 4.1 PCI DSS requirement Web Application 1.0.0
4.1 should only be
accessible over
HTTPS
Requirement 6 PCI DSS v3.2.1 6.5.3 PCI DSS requirement API App should only 1.0.0
6.5.3 be accessible over
HTTPS
Requirement 6 PCI DSS v3.2.1 6.5.3 PCI DSS requirement Function App should 1.0.0
6.5.3 only be accessible
over HTTPS
Requirement 6 PCI DSS v3.2.1 6.5.3 PCI DSS requirement Web Application 1.0.0
6.5.3 should only be
accessible over
HTTPS
RMIT Malaysia
To review how the available Azure Policy built-ins for all Azure services map to this compliance standard, see
Azure Policy Regulatory Compliance - RMIT Malaysia. For more information about this compliance standard, see
RMIT Malaysia.
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Security of Digital RMiT 10.66 Security of Digital Resource logs in App 2.0.0
Services Services - 10.66 Services should be
enabled
Security of Digital RMiT 10.68 Security of Digital Latest TLS version 1.0.0
Services Services - 10.68 should be used in
your API App
Security of Digital RMiT 10.68 Security of Digital Latest TLS version 1.0.0
Services Services - 10.68 should be used in
your Function App
Security of Digital RMiT 10.68 Security of Digital Latest TLS version 1.0.0
Services Services - 10.68 should be used in
your Web App
Control Measures on RMiT Appendix 5.3 Control Measures on API App should only 1.0.0
Cybersecurity Cybersecurity - be accessible over
Appendix 5.3 HTTPS
Control Measures on RMiT Appendix 5.3 Control Measures on CORS should not 1.0.0
Cybersecurity Cybersecurity - allow every resource
Appendix 5.3 to access your Web
Applications
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'HTTP 2.0.0
Cybersecurity Cybersecurity - Version' is the latest,
Appendix 5.3 if used to run the API
app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'HTTP 2.0.0
Cybersecurity Cybersecurity - Version' is the latest,
Appendix 5.3 if used to run the
Function app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'HTTP 2.0.0
Cybersecurity Cybersecurity - Version' is the latest,
Appendix 5.3 if used to run the
Web app
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'Java 2.0.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the API app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'Java 2.0.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the Function app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'Java 2.0.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the Web app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'PHP 2.1.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the API app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'PHP 2.2.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the WEB app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'Python 3.0.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the API app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'Python 3.0.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the Function app
Control Measures on RMiT Appendix 5.3 Control Measures on Ensure that 'Python 3.0.0
Cybersecurity Cybersecurity - version' is the latest,
Appendix 5.3 if used as a part of
the Web app
Control Measures on RMiT Appendix 5.3 Control Measures on FTPS only should be 2.0.0
Cybersecurity Cybersecurity - required in your API
Appendix 5.3 App
Control Measures on RMiT Appendix 5.3 Control Measures on FTPS only should be 2.0.0
Cybersecurity Cybersecurity - required in your
Appendix 5.3 Function App
Control Measures on RMiT Appendix 5.3 Control Measures on FTPS should be 2.0.0
Cybersecurity Cybersecurity - required in your Web
Appendix 5.3 App
Control Measures on RMiT Appendix 5.3 Control Measures on Function App should 1.0.0
Cybersecurity Cybersecurity - only be accessible
Appendix 5.3 over HTTPS
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E
Control Measures on RMiT Appendix 5.3 Control Measures on Web Application 1.0.0
Cybersecurity Cybersecurity - should only be
Appendix 5.3 accessible over
HTTPS
Control Measures on RMiT Appendix 5.7 Control Measures on CORS should not 1.0.0
Cybersecurity Cybersecurity - allow every resource
Appendix 5.7 to access your API
App
Control Measures on RMiT Appendix 5.7 Control Measures on CORS should not 1.0.0
Cybersecurity Cybersecurity - allow every resource
Appendix 5.7 to access your
Function Apps
Control Measures on RMiT Appendix 5.7 Control Measures on Remote debugging 1.0.0
Cybersecurity Cybersecurity - should be turned off
Appendix 5.7 for API Apps
Control Measures on RMiT Appendix 5.7 Control Measures on Remote debugging 1.0.0
Cybersecurity Cybersecurity - should be turned off
Appendix 5.7 for Function Apps
Control Measures on RMiT Appendix 5.7 Control Measures on Remote debugging 1.0.0
Cybersecurity Cybersecurity - should be turned off
Appendix 5.7 for Web Applications
P O L IC Y P O L IC Y VERSIO N
DO M A IN C O N T RO L ID C O N T RO L T IT L E ( A ZURE PO RTA L) ( GIT HUB)
Next steps
Learn more about Azure Policy Regulatory Compliance.
See the built-ins on the Azure Policy GitHub repo.
Security in Azure App Service
5/18/2022 • 7 minutes to read • Edit Online
This article shows you how Azure App Service helps secure your web app, mobile app back end, API app, and
function app. It also shows how you can further secure your app with the built-in App Service features.
The platform components of App Service, including Azure VMs, storage, network connections, web frameworks,
management and integration features, are actively secured and hardened. App Service goes through vigorous
compliance checks on a continuous basis to make sure that:
Your app resources are secured from the other customers' Azure resources.
VM instances and runtime software are regularly updated to address newly discovered vulnerabilities.
Communication of secrets (such as connection strings) between your app and other Azure resources (such as
SQL Database) stays within Azure and doesn't cross any network boundaries. Secrets are always encrypted
when stored.
All communication over the App Service connectivity features, such as hybrid connection, is encrypted.
Connections with remote management tools like Azure PowerShell, Azure CLI, Azure SDKs, REST APIs, are all
encrypted.
24-hour threat management protects the infrastructure and platform against malware, distributed denial-of-
service (DDoS), man-in-the-middle (MITM), and other threats.
For more information on infrastructure and platform security in Azure, see Azure Trust Center.
The following sections show you how to further protect your App Service app from threats.
Service-to-service authentication
When authenticating against a back-end service, App Service provides two different mechanisms depending on
your need:
Ser vice identity - Sign in to the remote resource using the identity of the app itself. App Service lets you
easily create a managed identity, which you can use to authenticate with other services, such as Azure SQL
Database or Azure Key Vault. For an end-to-end tutorial of this approach, see Secure Azure SQL Database
connection from App Service using a managed identity.
On-behalf-of (OBO) - Make delegated access to remote resources on behalf of the user. With Azure Active
Directory as the authentication provider, your App Service app can perform delegated sign-in to a remote
service, such as Microsoft Graph API or a remote API app in App Service. For an end-to-end tutorial of this
approach, see Authenticate and authorize users end-to-end in Azure App Service.
Application secrets
Don't store application secrets, such as database credentials, API tokens, and private keys in your code or
configuration files. The commonly accepted approach is to access them as environment variables using the
standard pattern in your language of choice. In App Service, the way to define environment variables is through
app settings (and, especially for .NET applications, connection strings). App settings and connection strings are
stored encrypted in Azure, and they're decrypted only before being injected into your app's process memory
when the app starts. The encryption keys are rotated regularly.
Alternatively, you can integrate your App Service app with Azure Key Vault for advanced secrets management.
By accessing the Key Vault with a managed identity, your App Service app can securely access the secrets you
need.
Network isolation
Except for the Isolated pricing tier, all tiers run your apps on the shared network infrastructure in App Service.
For example, the public IP addresses and front-end load balancers are shared with other tenants. The Isolated
tier gives you complete network isolation by running your apps inside a dedicated App Service environment. An
App Service environment runs in your own instance of Azure Virtual Network. It lets you:
Serve your apps through a dedicated public endpoint, with dedicated front ends.
Serve internal application using an internal load balancer (ILB), which allows access only from inside your
Azure Virtual Network. The ILB has an IP address from your private subnet, which provides total isolation of
your apps from the internet.
Use an ILB behind a web application firewall (WAF). The WAF offers enterprise-level protection to your
public-facing applications, such as DDoS protection, URI filtering, and SQL injection prevention.
For more information, see Introduction to Azure App Service Environments.
App Service networking features
5/18/2022 • 19 minutes to read • Edit Online
You can deploy applications in Azure App Service in multiple ways. By default, apps hosted in App Service are
accessible directly through the internet and can reach only internet-hosted endpoints. But for many applications,
you need to control the inbound and outbound network traffic. There are several features in App Service to help
you meet those needs. The challenge is knowing which feature to use to solve a given problem. This article will
help you determine which feature to use, based on some example use cases.
There are two main deployment types for Azure App Service:
The multi-tenant public service hosts App Service plans in the Free, Shared, Basic, Standard, Premium,
PremiumV2, and PremiumV3 pricing SKUs.
The single-tenant App Service Environment (ASE) hosts Isolated SKU App Service plans directly in your Azure
virtual network.
The features you use will depend on whether you're in the multi-tenant service or in an ASE.
NOTE
Networking features are not available for apps deployed in Azure Arc.
Private endpoints
Other than noted exceptions, you can use all of these features together. You can mix the features to solve your
problems.
Support unshared dedicated inbound address for your app App-assigned address
Protect your app with a web application firewall (WAF) Application Gateway and ILB ASE
Application Gateway with private endpoints
Application Gateway with service endpoints
Azure Front Door with access restrictions
Load balance traffic to your apps in different regions Azure Front Door with access restrictions
Load balance traffic in the same region Application Gateway with service endpoints
The following outbound use cases suggest how to use App Service networking features to solve outbound
access needs for your app:
Access resources in an Azure virtual network in the same Virtual network integration
region ASE
Access resources in an Azure virtual network in a different virtual network integration and virtual network peering
region Gateway-required virtual network integration
ASE and virtual network peering
Secure outbound traffic from your web app virtual network integration and network security groups
ASE
Route outbound traffic from your web app virtual network integration and route tables
ASE
Default networking behavior
Azure App Service scale units support many customers in each deployment. The Free and Shared SKU plans
host customer workloads on multi-tenant workers. The Basic and higher plans host customer workloads that are
dedicated to only one App Service plan. If you have a Standard App Service plan, all the apps in that plan will
run on the same worker. If you scale out the worker, all the apps in that App Service plan will be replicated on a
new worker for each instance in your App Service plan.
Outbound addresses
The worker VMs are broken down in large part by the App Service plans. The Free, Shared, Basic, Standard, and
Premium plans all use the same worker VM type. The PremiumV2 plan uses another VM type. PremiumV3 uses
yet another VM type. When you change the VM family, you get a different set of outbound addresses. If you
scale from Standard to PremiumV2, your outbound addresses will change. If you scale from PremiumV2 to
PremiumV3, your outbound addresses will change. In some older scale units, both the inbound and outbound
addresses will change when you scale from Standard to PremiumV2.
There are a number of addresses that are used for outbound calls. The outbound addresses used by your app
for making outbound calls are listed in the properties for your app. These addresses are shared by all the apps
running on the same worker VM family in the App Service deployment. If you want to see all the addresses that
your app might use in a scale unit, there's property called possibleOutboundAddresses that will list them.
App Service has a number of endpoints that are used to manage the service. Those addresses are published in a
separate document and are also in the AppServiceManagement IP service tag. The AppServiceManagement tag is
used only in App Service Environments where you need to allow such traffic. The App Service inbound
addresses are tracked in the AppService IP service tag. There's no IP service tag that contains the outbound
addresses used by App Service.
App-assigned address
The app-assigned address feature is an offshoot of the IP-based SSL capability. You access it by setting up SSL
with your app. You can use this feature for IP-based SSL calls. You can also use it to give your app an address
that only it has.
When you use an app-assigned address, your traffic still goes through the same front-end roles that handle all
the incoming traffic into the App Service scale unit. But the address that's assigned to your app is used only by
your app. Use cases for this feature:
Support IP-based SSL needs for your app.
Set a dedicated address for your app that's not shared.
To learn how to set an address on your app, see Add a TLS/SSL certificate in Azure App Service.
Access restrictions
Access restrictions let you filter inbound requests. The filtering action takes place on the front-end roles that are
upstream from the worker roles where your apps are running. Because the front-end roles are upstream from
the workers, you can think of access restrictions as network-level protection for your apps.
This feature allows you to build a list of allow and deny rules that are evaluated in priority order. It's similar to
the network security group (NSG) feature in Azure networking. You can use this feature in an ASE or in the
multi-tenant service. When you use it with an ILB ASE, you can restrict access from private address blocks.
NOTE
Up to 512 access restriction rules can be configured per app.
IP-based access restriction rules
The IP-based access restrictions feature helps when you want to restrict the IP addresses that can be used to
reach your app. Both IPv4 and IPv6 are supported. Some use cases for this feature:
Restrict access to your app from a set of well-defined addresses.
Restrict access to traffic coming through an external load-balancing service or other network appliances with
known egress IP addresses.
To learn how to enable this feature, see Configuring access restrictions.
NOTE
IP-based access restriction rules only handle virtual network address ranges when your app is in an App Service
Environment. If your app is in the multi-tenant service, you need to use service endpoints to restrict traffic to select
subnets in your virtual network.
NOTE
Access restriction rules based on service endpoints are not supported on apps that use IP-based SSL (App-assigned
address).
App Service Hybrid Connections is built on the Azure Relay Hybrid Connections capability. App Service uses a
specialized form of the feature that only supports making outbound calls from your app to a TCP host and port.
This host and port only need to resolve on the host where Hybrid Connection Manager is installed.
When the app, in App Service, does a DNS lookup on the host and port defined in your hybrid connection, the
traffic automatically redirects to go through the hybrid connection and out of Hybrid Connection Manager. To
learn more, see App Service Hybrid Connections.
This feature is commonly used to:
Access resources in private networks that aren't connected to Azure with a VPN or ExpressRoute.
Support the migration of on-premises apps to App Service without the need to move supporting databases.
Provide access with improved security to a single host and port per hybrid connection. Most networking
features open access to a network. With Hybrid Connections, you can only reach the single host and port.
Cover scenarios not covered by other outbound connectivity methods.
Perform development in App Service in a way that allows the apps to easily use on-premises resources.
Because this feature enables access to on-premises resources without an inbound firewall hole, it's popular with
developers. The other outbound App Service networking features are related to Azure Virtual Network. Hybrid
Connections doesn't depend on going through a virtual network. It can be used for a wider variety of
networking needs.
Note that App Service Hybrid Connections is unaware of what you're doing on top of it. So you can use it to
access a database, a web service, or an arbitrary TCP socket on a mainframe. The feature essentially tunnels TCP
packets.
Hybrid Connections is popular for development, but it's also used in production applications. It's great for
accessing a web service or database, but it's not appropriate for situations that involve creating many
connections.
Gateway-required virtual network integration
Gateway-required App Service virtual network integration enables your app to make outbound requests into an
Azure virtual network. The feature works by connecting the host your app is running on to a Virtual Network
gateway on your virtual network by using a point-to-site VPN. When you configure the feature, your app gets
one of the point-to-site addresses assigned to each instance. This feature enables you to access resources in
either classic or Azure Resource Manager virtual networks in any region.
This feature solves the problem of accessing resources in other virtual networks. It can even be used to connect
through a virtual network to either other virtual networks or on-premises. It doesn't work with ExpressRoute-
connected virtual networks, but it does work with site-to-site VPN-connected networks. It's usually
inappropriate to use this feature from an app in an App Service Environment (ASE) because the ASE is already in
your virtual network. Use cases for this feature:
Access resources in cross region virtual networks that aren't peered to a virtual network in the region.
When this feature is enabled, your app will use the DNS server that the destination virtual network is configured
with. For more information on this feature, see App Service virtual network integration.
Regional virtual network integration
Gateway-required virtual network integration is useful, but it doesn't solve the problem of accessing resources
across ExpressRoute. On top of needing to reach across ExpressRoute connections, there's a need for apps to be
able to make calls to services secured by service endpoint. Another virtual network integration capability can
meet these needs.
The regional virtual network integration feature enables you to place the back end of your app in a subnet in a
Resource Manager virtual network in the same region as your app. This feature isn't available from an App
Service Environment, which is already in a virtual network. Use cases for this feature:
Access resources in Resource Manager virtual networks in the same region.
Access resources in peered virtual networks, including cross region connections.
Access resources that are secured with service endpoints.
Access resources that are accessible across ExpressRoute or VPN connections.
Access resources in private networks without the need and cost of a Virtual Network gateway.
Help to secure all outbound traffic.
Force tunnel all outbound traffic.
The ASE provides the best story around isolated and dedicated app hosting, but it does involve some
management challenges. Some things to consider before you use an operational ASE:
An ASE runs inside your virtual network, but it does have dependencies outside the virtual network. Those
dependencies must be allowed. For more information, see Networking considerations for an App Service
Environment.
An ASE doesn't scale immediately like the multi-tenant service. You need to anticipate scaling needs rather
than reactively scaling.
An ASE does have a higher up-front cost. To get the most out of your ASE, you should plan to put many
workloads into one ASE rather than using it for small efforts.
The apps in an ASE can't selectively restrict access to some apps in the ASE and not others.
An ASE is in a subnet, and any networking rules apply to all the traffic to and from that ASE. If you want to
assign inbound traffic rules for just one app, use access restrictions.
Combining features
The features noted for the multi-tenant service can be used together to solve more elaborate use cases. Two of
the more common use cases are described here, but they're just examples. By understanding what the various
features do, you can meet nearly all your system architecture needs.
Place an app into a virtual network
You might wonder how to put an app into a virtual network. If you put your app into a virtual network, the
inbound and outbound endpoints for the app are within the virtual network. An ASE is the best way to solve this
problem. But you can meet most of your needs within the multi-tenant service by combining features. For
example, you can host intranet-only applications with private inbound and outbound addresses by:
Creating an application gateway with private inbound and outbound addresses.
Securing inbound traffic to your app with service endpoints.
Using the virtual network integration feature so the back end of your app is in your virtual network.
This deployment style won't give you a dedicated address for outbound traffic to the internet or the ability to
lock down all outbound traffic from your app. It will give you a much of what you would only otherwise get with
an ASE.
Create multi-tier applications
A multi-tier application is an application in which the API back-end apps can be accessed only from the front-end
tier. There are two ways to create a multi-tier application. Both start by using virtual network integration to
connect your front-end web app to a subnet in a virtual network. Doing so will enable your web app to make
calls into your virtual network. After your front-end app is connected to the virtual network, you need to decide
how to lock down access to your API application. You can:
Host both the front end and the API app in the same ILB ASE, and expose the front-end app to the internet by
using an application gateway.
Host the front end in the multi-tenant service and the back end in an ILB ASE.
Host both the front end and the API app in the multi-tenant service.
If you're hosting both the front end and API app for a multi-tier application, you can:
Expose your API application by using private endpoints in your virtual network:
Use service endpoints to ensure inbound traffic to your API app comes only from the subnet used by
your front-end web app:
Here are some considerations to help you decide which method to use:
When you use service endpoints, you only need to secure traffic to your API app to the integration subnet.
Service endpoints helps to secure the API app, but you could still have data exfiltration from your front-end
app to other apps in the app service.
When you use private endpoints, you have two subnets at play, which adds complexity. Also, the private
endpoint is a top-level resource and adds management overhead. The benefit of using private endpoints is
that you don't have the possibility of data exfiltration.
Either method will work with multiple front ends. On a small scale, service endpoints are easier to use because
you simply enable service endpoints for the API app on the front-end integration subnet. As you add more front-
end apps, you need to adjust every API app to include service endpoints with the integration subnet. When you
use private endpoints, there's more complexity, but you don't have to change anything on your API apps after
you set a private endpoint.
Line -of-business applications
Line-of-business (LOB) applications are internal applications that aren't normally exposed for access from the
internet. These applications are called from inside corporate networks where access can be strictly controlled. If
you use an ILB ASE, it's easy to host your line-of-business applications. If you use the multi-tenant service, you
can either use private endpoints or use service endpoints combined with an application gateway. There are two
reasons to use an application gateway with service endpoints instead of using private endpoints:
You need WAF protection on your LOB apps.
You want to load balance to multiple instances of your LOB apps.
If neither of these needs apply, you're better off using private endpoints. With private endpoints available in App
Service, you can expose your apps on private addresses in your virtual network. The private endpoint you place
in your virtual network can be reached across ExpressRoute and VPN connections.
Configuring private endpoints will expose your apps on a private address, but you'll need to configure DNS to
reach that address from on-premises. To make this configuration work, you'll need to forward the Azure DNS
private zone that contains your private endpoints to your on-premises DNS servers. Azure DNS private zones
don't support zone forwarding, but you can support zone forwarding by using a DNS server for that purpose.
The DNS Forwarder template makes it easier to forward your Azure DNS private zone to your on-premises DNS
servers.
USE P O RT O R P O RT S
Azure App Service is a multi-tenant service, except for App Service Environments. Apps that are not in an App
Service environment (not in the Isolated tier) share network infrastructure with other apps. As a result, the
inbound and outbound IP addresses of an app can be different, and can even change in certain situations.
App Service Environments use dedicated network infrastructures, so apps running in an App Service
environment get static, dedicated IP addresses both for inbound and outbound connections.
nslookup <app-name>.azurewebsites.net
az webapp show --resource-group <group_name> --name <app_name> --query outboundIpAddresses --output tsv
To find all possible outbound IP addresses for your app, regardless of pricing tiers, click Proper ties in your
app's left-hand navigation. They are listed in the Additional Outbound IP Addresses field.
You can find the same information by running the following command in the Cloud Shell.
Next steps
Learn how to restrict inbound traffic by source IP addresses.
Static IP restrictions
Using Private Endpoints for Azure Web App
5/18/2022 • 7 minutes to read • Edit Online
IMPORTANT
Private Endpoint is available for Windows and Linux Web App, containerized or not, hosted on these App Service Plans :
Basic, Standard , PremiumV2 , PremiumV3 , IsolatedV2 , Functions Premium (sometimes referred to as the Elastic
Premium plan).
You can use Private Endpoint for your Azure Web App to allow clients located in your private network to
securely access the app over Private Link. The Private Endpoint uses an IP address from your Azure VNet
address space. Network traffic between a client on your private network and the Web App traverses over the
VNet and a Private Link on the Microsoft backbone network, eliminating exposure from the public Internet.
Using Private Endpoint for your Web App enables you to:
Secure your Web App by configuring the Private Endpoint, eliminating public exposure.
Securely connect to Web App from on-premises networks that connect to the VNet using a VPN or
ExpressRoute private peering.
Avoid any data exfiltration from your VNet.
If you just need a secure connection between your VNet and your Web App, a Service Endpoint is the simplest
solution. If you also need to reach the web app from on-premises through an Azure Gateway, a regionally
peered VNet, or a globally peered VNet, Private Endpoint is the solution.
For more information, see Service Endpoints.
Conceptual overview
A Private Endpoint is a special network interface (NIC) for your Azure Web App in a Subnet in your Virtual
Network (VNet). When you create a Private Endpoint for your Web App, it provides secure connectivity between
clients on your private network and your Web App. The Private Endpoint is assigned an IP Address from the IP
address range of your VNet. The connection between the Private Endpoint and the Web App uses a secure
Private Link. Private Endpoint is only used for incoming flows to your Web App. Outgoing flows won't use this
Private Endpoint. You can inject outgoing flows to your network in a different subnet through the VNet
integration feature.
Each slot of an app is configured separately. You can plug up to 100 Private Endpoints per slot. You can't share a
Private Endpoint between slots.
The Subnet where you plug the Private Endpoint can have other resources in it, you don't need a dedicated
empty Subnet. You can also deploy the Private Endpoint in a different region than the Web App.
NOTE
The VNet integration feature cannot use the same subnet as Private Endpoint, this is a limitation of the VNet integration
feature.
DNS
When you use Private Endpoint for Web App, the requested URL must match the name of your Web App. By
default mywebappname.azurewebsites.net.
By default, without Private Endpoint, the public name of your web app is a canonical name to the cluster. For
example, the name resolution will be:
NAME TYPE VA L UE
cloudservicename.cloudapp.net A 40.122.110.154
When you deploy a Private Endpoint, we update the DNS entry to point to the canonical name
mywebapp.privatelink.azurewebsites.net. For example, the name resolution will be:
You must setup a private DNS server or an Azure DNS private zone, for tests you can modify the host entry of
your test machine. The DNS zone that you need to create is: privatelink .azurewebsites.net . Register the
record for your Web App with a A record and the Private Endpoint IP. For example, the name resolution will be:
After this DNS configuration you can reach your Web App privately with the default name
mywebappname.azurewebsites.net. You must use this name, because the default certificate is issued for
*.azurewebsites.net.
If you need to use a custom DNS name, you must add the custom name in your Web App. The custom name
must be validated like any custom name, using public DNS resolution. For more information, see custom DNS
validation.
For the Kudu console, or Kudu REST API (deployment with Azure DevOps self-hosted agents for example), you
must create two records pointing to the Private Endpoint IP in your Azure DNS private zone or your custom
DNS server. The first is for your Web App, the second is for the SCM of your Web App.
NAME TYPE VA L UE
mywebapp.privatelink.azurewebsites.n A PrivateEndpointIP
et
mywebapp.scm.privatelink.azurewebsit A PrivateEndpointIP
es.net
Specific requirements
If the Virtual Network is in a different subscription than the app, you must ensure that the subscription with the
Virtual Network is registered for the Microsoft.Web resource provider. You can explicitly register the provider by
following this documentation, but it will also automatically be registered when creating the first web app in a
subscription.
Pricing
For pricing details, see Azure Private Link pricing.
Limitations
When you use Azure Function in Elastic Premium Plan with Private Endpoint, to run or execute the function in
Azure Web portal, you must have direct network access or you'll receive an HTTP 403 error. In other words,
your browser must be able to reach the Private Endpoint to execute the function from the Azure Web portal.
You can connect up to 100 Private Endpoints to a particular Web App.
Remote Debugging functionality is not available when Private Endpoint is enabled for the Web App. The
recommendation is to deploy the code to a slot and remote debug it there.
FTP access is provided through the inbound public IP address. Private Endpoint doesn't support FTP access to
the Web App.
IP-Based SSL isn't supported with Private Endpoints.
We're improving Private Link feature and Private Endpoint regularly, check this article for up-to-date
information about limitations.
Next steps
To deploy Private Endpoint for your Web App through the portal, see How to connect privately to a Web App
with the Portal
To deploy Private Endpoint for your Web App using Azure CLI, see How to connect privately to a Web App
with Azure CLI
To deploy Private Endpoint for your Web App using PowerShell, see How to connect privately to a Web App
with PowerShell
To deploy Private Endpoint for your Web App using Azure template, see How to connect privately to a Web
App with Azure template
End-to-end example, how to connect a frontend web app to a secured backend web app with VNet injection
and private endpoint with ARM template, see this quickstart
End-to-end example, how to connect a frontend web app to a secured backend web app with VNet injection
and private endpoint with terraform, see this sample
Azure App Service Hybrid Connections
5/18/2022 • 12 minutes to read • Edit Online
Hybrid Connections is both a service in Azure and a feature in Azure App Service. As a service, it has uses and
capabilities beyond those that are used in App Service. To learn more about Hybrid Connections and their usage
outside App Service, see Azure Relay Hybrid Connections.
Within App Service, Hybrid Connections can be used to access application resources in any network that can
make outbound calls to Azure over port 443. Hybrid Connections provides access from your app to a TCP
endpoint and doesn't enable a new way to access your app. As used in App Service, each Hybrid Connection
correlates to a single TCP host and port combination. This enables your apps to access resources on any OS,
provided it's a TCP endpoint. The Hybrid Connections feature doesn't know or care what the application protocol
is, or what you are accessing. It simply provides network access.
How it works
Hybrid Connections requires a relay agent to be deployed where it can reach both the desired endpoint as well
as to Azure. The relay agent, Hybrid Connection Manager (HCM), calls out to Azure Relay over port 443. From
the web app site, the App Service infrastructure also connects to Azure Relay on your application's behalf.
Through the joined connections, your app is able to access the desired endpoint. The connection uses TLS 1.2 for
security and shared access signature (SAS) keys for authentication and authorization.
When your app makes a DNS request that matches a configured Hybrid Connection endpoint, the outbound TCP
traffic will be redirected through the Hybrid Connection.
NOTE
This means that you should try to always use a DNS name for your Hybrid Connection. Some client software does not do
a DNS lookup if the endpoint uses an IP address instead.
To add a new Hybrid Connection, select [+] Add hybrid connection . You'll see a list of the Hybrid Connections
that you already created. To add one or more of them to your app, select the ones you want, and then select Add
selected Hybrid Connection .
If you want to create a new Hybrid Connection, select Create new hybrid connection . Specify the:
Hybrid Connection name.
Endpoint hostname.
Endpoint port.
Service Bus namespace you want to use.
Every Hybrid Connection is tied to a Service Bus namespace, and each Service Bus namespace is in an Azure
region. It's important to try to use a Service Bus namespace in the same region as your app, to avoid network
induced latency.
If you want to remove your Hybrid Connection from your app, right-click it and select Disconnect .
When a Hybrid Connection is added to your app, you can see details on it simply by selecting it.
Create a Hybrid Connection in the Azure Relay portal
In addition to the portal experience from within your app, you can create Hybrid Connections from within the
Azure Relay portal. For a Hybrid Connection to be used by App Service, it must:
Require client authorization.
Have a metadata item, named endpoint, that contains a host:port combination as the value.
The App Service plan UI shows you how many Hybrid Connections are being used and by what apps.
Select the Hybrid Connection to see details. You can see all the information that you saw at the app view. You can
also see how many other apps in the same plan are using that Hybrid Connection.
There's a limit on the number of Hybrid Connection endpoints that can be used in an App Service plan. Each
Hybrid Connection used, however, can be used across any number of apps in that plan. For example, a single
Hybrid Connection that is used in five separate apps in an App Service plan counts as one Hybrid Connection.
Pricing
In addition to there being an App Service plan SKU requirement, there's an additional cost to using Hybrid
Connections. There's a charge for each listener used by a Hybrid Connection. The listener is the Hybrid
Connection Manager. If you had five Hybrid Connections supported by two Hybrid Connection Managers, that
would be 10 listeners. For more information, see Service Bus pricing.
3. Sign in with your Azure account to get your Hybrid Connections available with your subscriptions. The
HCM doesn't continue to use your Azure account beyond that.
4. Choose a subscription.
5. Select the Hybrid Connections that you want the HCM to relay.
6. Select Save .
You can now see the Hybrid Connections you added. You can also select the configured Hybrid Connection to
see details.
Redundancy
Each HCM can support multiple Hybrid Connections. Also, any given Hybrid Connection can be supported by
multiple HCMs. The default behavior is to route traffic across the configured HCMs for any given endpoint. If
you want high availability on your Hybrid Connections from your network, run multiple HCMs on separate
machines. The load distribution algorithm used by the Relay service to distribute traffic to the HCMs is random
assignment.
Manually add a Hybrid Connection
To enable someone outside your subscription to host an HCM instance for a given Hybrid Connection, share the
gateway connection string for the Hybrid Connection with them. You can see the gateway connection string in
the Hybrid Connection properties in the Azure portal. To use that string, select Enter Manually in the HCM, and
paste in the gateway connection string.
Upgrade
There are periodic updates to the Hybrid Connection Manager to fix issues or provide improvements. When
upgrades are released, a popup will show up in the HCM UI. Applying the upgrade will apply the changes and
restart the HCM.
az webapp hybrid-connection
Group
az webapp hybrid-connection : Methods that list, add and remove hybrid-connections from webapps.
This command group is in preview. It may be changed/removed in a future release.
Commands:
add : Add a hybrid-connection to a webapp.
list : List the hybrid-connections on a webapp.
remove : Remove a hybrid-connection from a webapp.
The App Service plan commands enable you to set which key a given hybrid-connection will use. There are two
keys set on each Hybrid Connection, a primary and a secondary. You can choose to use the primary or
secondary key with the below commands. This enables you to switch keys for when you want to periodically
regenerate your keys.
az appservice hybrid-connection --help
Group
az appservice hybrid-connection : A method that sets the key a hybrid-connection uses.
This command group is in preview. It may be changed/removed in a future release.
Commands:
set-key : Set the key that all apps in an appservice plan use to connect to the hybrid-
connections in that appservice plan.
Troubleshooting
The status of "Connected" means that at least one HCM is configured with that Hybrid Connection, and is able to
reach Azure. If the status for your Hybrid Connection doesn't say Connected , your Hybrid Connection isn't
configured on any HCM that has access to Azure. When your HCM shows Not Connected there are a few
things to check:
Does your host have outbound access to Azure on port 443? You can test from your HCM host using the
PowerShell command Test-NetConnection Destination -P Port
Is your HCM potentially in a bad state? Try restarting the ‘Azure Hybrid Connection Manager Service"
local service.
Do you have conflicting software installed? Hybrid Connection Manager cannot coexist with Biztalk
Hybrid Connection Manager or Service Bus for Windows Server. Hence when installing HCM, any
versions of these packages should be removed first.
If your status says Connected but your app cannot reach your endpoint then:
make sure you're using a DNS name in your Hybrid Connection. If you use an IP address then the required
client DNS lookup may not happen. If the client running in your web app doesn't do a DNS lookup, then the
Hybrid Connection will not work
check that the DNS name used in your Hybrid Connection can resolve from the HCM host. Check the
resolution using nslookup EndpointDNSname where EndpointDNSname is an exact match to what is used in
your Hybrid Connection definition.
test access from your HCM host to your endpoint using the PowerShell command Test-NetConnection
EndpointDNSname -P Port If you cannot reach the endpoint from your HCM host then check firewalls
between the two hosts including any host-based firewalls on the destination host.
if you're using App Service on Linux, make sure you're not using "localhost" as your endpoint host. Instead,
use your machine name if you're trying to create a connection with a resource on your local machine.
In App Service, the tcpping command-line tool can be invoked from the Advanced Tools (Kudu) console. This
tool can tell you if you have access to a TCP endpoint, but it doesn't tell you if you have access to a Hybrid
Connection endpoint. When you use the tool in the console against a Hybrid Connection endpoint, you're only
confirming that it uses a host:port combination.
If you have a command-line client for your endpoint, you can test connectivity from the app console. For
example, you can test access to web server endpoints by using curl.
Integrate your app with an Azure virtual network
5/18/2022 • 27 minutes to read • Edit Online
This article describes the Azure App Service virtual network integration feature and how to set it up with apps in
App Service. With Azure virtual networks, you can place many of your Azure resources in a non-internet-
routable network. The App Service virtual network integration feature enables your apps to access resources in
or through a virtual network. Virtual network integration doesn't enable your apps to be accessed privately.
App Service has two variations:
The dedicated compute pricing tiers, which include the Basic, Standard, Premium, Premium v2, and Premium
v3.
The App Service Environment, which deploys directly into your virtual network with dedicated supporting
infrastructure and is using the Isolated and Isolated v2 pricing tiers.
The virtual network integration feature is used in Azure App Service dedicated compute pricing tiers. If your app
is in an App Service Environment, it's already in a virtual network and doesn't require use of the VNet
integration feature to reach resources in the same virtual network. For more information on all the networking
features, see App Service networking features.
Virtual network integration gives your app access to resources in your virtual network, but it doesn't grant
inbound private access to your app from the virtual network. Private site access refers to making an app
accessible only from a private network, such as from within an Azure virtual network. Virtual network
integration is used only to make outbound calls from your app into your virtual network. The virtual network
integration feature behaves differently when it's used with virtual networks in the same region and with virtual
networks in other regions. The virtual network integration feature has two variations:
Regional vir tual network integration : When you connect to virtual networks in the same region, you
must have a dedicated subnet in the virtual network you're integrating with.
Gateway-required vir tual network integration : When you connect directly to virtual networks in other
regions or to a classic virtual network in the same region, you need an Azure Virtual Network gateway
created in the target virtual network.
The virtual network integration feature:
Requires a supported Basic or Standard, Premium, Premium v2, Premium v3, or Elastic Premium App Service
pricing tier.
Supports TCP and UDP.
Works with App Service apps and function apps.
There are some things that virtual network integration doesn't support, like:
Mounting a drive.
Windows Server Active Directory integration.
NetBIOS.
Gateway-required virtual network integration provides access to resources only in the target virtual network or
in networks connected to the target virtual network with peering or VPNs. Gateway-required virtual network
integration doesn't enable access to resources available across Azure ExpressRoute connections or work with
service endpoints.
No matter which version is used, virtual network integration gives your app access to resources in your virtual
network, but it doesn't grant inbound private access to your app from the virtual network. Private site access
refers to making your app accessible only from a private network, such as from within an Azure virtual network.
Virtual network integration is only for making outbound calls from your app into your virtual network.
Learn how to enable virtual network integration.
When regional virtual network integration is enabled, your app makes outbound calls through your virtual
network. The outbound addresses that are listed in the app properties portal are the addresses still used by your
app. However, if your outbound call is to a virtual machine or private endpoint in the integration virtual network
or peered virtual network, the outbound address will be an address from the integration subnet. The private IP
assigned to an instance is exposed via the environment variable, WEBSITE_PRIVATE_IP.
When all traffic routing is enabled, all outbound traffic is sent into your virtual network. If all traffic routing isn't
enabled, only private traffic (RFC1918) and service endpoints configured on the integration subnet will be sent
into the virtual network and outbound traffic to the internet will go through the same channels as normal.
The feature supports only one virtual interface per worker. One virtual interface per worker means one regional
virtual network integration per App Service plan. All the apps in the same App Service plan can only use the
same virtual network integration to a specific subnet. If you need an app to connect to another virtual network
or another subnet in the same virtual network, you need to create another App Service plan. The virtual
interface used isn't a resource that customers have direct access to.
Because of the nature of how this technology operates, the traffic that's used with virtual network integration
doesn't show up in Azure Network Watcher or NSG flow logs.
Subnet requirements
Virtual network integration depends on a dedicated subnet. When you create a subnet, the Azure subnet loses
five IPs from the start. One address is used from the integration subnet for each plan instance. If you scale your
app to four instances, then four addresses are used.
When you scale up or down in size, the required address space is doubled for a short period of time. This
change affects the real, available supported instances for a given subnet size. The following table shows both the
maximum available addresses per CIDR block and the effect this has on horizontal scale.
M A XIM UM H O RIZ O N TA L SC A L E
C IDR B LO C K SIZ E M A XIM UM AVA IL A B L E A DDRESSES ( IN STA N C ES) *
/28 11 5
/27 27 13
/26 59 29
*Assumes that you'll need to scale up or down in either size or SKU at some point.
Because subnet size can't be changed after assignment, use a subnet that's large enough to accommodate
whatever scale your app might reach. To avoid any issues with subnet capacity, use a /26 with 64 addresses.
When you're creating subnets in Azure portal as part of integrating with the virtual network, a minimum size of
/27 is required.
When you want your apps in your plan to reach a virtual network that's already connected to by apps in another
plan, select a different subnet than the one being used by the pre-existing virtual network integration.
Permissions
You must have at least the following Role-based access control permissions on the subnet or at a higher level to
configure regional virtual network integration through Azure portal, CLI or when setting the
virtualNetworkSubnetId site property directly:
A C T IO N DESC RIP T IO N
If the virtual network is in a different subscription than the app, you must ensure that the subscription with the
virtual network is registered for the Microsoft.Web resource provider. You can explicitly register the provider by
following this documentation, but it will also automatically be registered when creating the first web app in a
subscription.
Routes
You can control what traffic goes through the virtual network integration. There are three types of routing to
consider when you configure regional virtual network integration. Application routing defines what traffic is
routed from your app and into the virtual network. Configuration routing affects operations that happen before
or during startup of your app. Examples are container image pull and app settings with Key Vault reference.
Network routing is the ability to handle how both app and configuration traffic are routed from your virtual
network and out.
By default, only private traffic (also known as RFC1918 traffic) sent from your app is routed through the virtual
network integration. Unless you configure application routing or configuration routing options, all other traffic
will not be sent through the virtual network integration. Traffic is only subject to network routing if it is sent
through the virtual network integration.
Application routing
Application routing applies to traffic that is sent from your app after it has been started. See configuration
routing for traffic during start up. When you configure application routing, you can either route all traffic or only
private traffic into your virtual network. You configure this behavior through the Route All setting. If Route All
is disabled, your app only routes private traffic into your virtual network. If you want to route all your outbound
app traffic into your virtual network, make sure that Route All is enabled.
NOTE
Only traffic configured in application or configuration routing is subject to the NSGs and UDRs that are applied to your
integration subnet.
When Route All is enabled, outbound traffic from your app is still sent from the addresses that are listed in your app
properties, unless you provide routes that direct the traffic elsewhere.
Regional virtual network integration can't use port 25.
NOTE
Windows containers don't support routing App Service Key Vault references or pulling custom container images over
virtual network integration.
Backup/restore to private storage accounts is currently not supported.
Configure SSL/TLS certificates from private Key Vaults is currently not supported.
Diagnostics logs to private storage accounts is currently not supported.
C o n t e n t st o r a g e
Bringing your own storage for content in often used in Functions where content storage is configured as part of
the Functions app.
To route content storage traffic through the virtual network integration, you need to add an app setting named
WEBSITE_CONTENTOVERVNET with the value 1 . In addition to adding the app setting, you must also ensure that any
firewall or Network Security Group configured on traffic from the subnet allow traffic to port 443 and 445.
Co n t ai n er i m age pu l l
When using custom containers for Linux, you can pull the container over the virtual network integration. To
route the container pull traffic through the virtual network integration, you must add an app setting named
WEBSITE_PULL_IMAGE_OVER_VNET with the value true .
A p p se t t i n g s u si n g K e y Va u l t r e fe r e n c e s
App settings using Key Vault references will attempt to get secrets over the public route. If the Key Vault is
blocking public traffic and the app is using virtual network integration, an attempt will then be made to get the
secrets through the virtual network integration.
Network routing
You can use route tables to route outbound traffic from your app to wherever you want. Route tables affect your
destination traffic. Route tables only apply to traffic routed through the virtual network integration. See
application routing and configuration routing for details. Common destinations can include firewall devices or
gateways. Routes that are set on your integration subnet won't affect replies to inbound app requests.
When you want to route outbound traffic on-premises, you can use a route table to send outbound traffic to
your Azure ExpressRoute gateway. If you do route traffic to a gateway, set routes in the external network to send
any replies back.
Border Gateway Protocol (BGP) routes also affect your app traffic. If you have BGP routes from something like
an ExpressRoute gateway, your app outbound traffic is affected. Similar to user-defined routes, BGP routes affect
traffic according to your routing scope setting.
Network security groups
An app that uses virtual network integration can use a network security group to block outbound traffic to
resources in your virtual network or the internet. To block traffic to public addresses, enable Route All. When
Route All isn't enabled, NSGs are only applied to RFC1918 traffic from your app.
An NSG that's applied to your integration subnet is in effect regardless of any route tables applied to your
integration subnet.
The inbound rules in an NSG don't apply to your app because virtual network integration affects only outbound
traffic from your app. To control inbound traffic to your app, use the Access Restrictions feature.
Service endpoints
Regional virtual network integration enables you to reach Azure services that are secured with service
endpoints. To access a service endpoint-secured service, follow these steps:
1. Configure regional virtual network integration with your web app to connect to a specific subnet for
integration.
2. Go to the destination service and configure service endpoints against the integration subnet.
Private endpoints
If you want to make calls to private endpoints, make sure that your DNS lookups resolve to the private endpoint.
You can enforce this behavior in one of the following ways:
Integrate with Azure DNS private zones. When your virtual network doesn't have a custom DNS server, the
integration is done automatically when the zones are linked to the virtual network.
Manage the private endpoint in the DNS server used by your app. To manage the configuration, you must
know the private endpoint IP address. Then point the endpoint you're trying to reach to that address by using
an A record.
Configure your own DNS server to forward to Azure DNS private zones.
Azure DNS private zones
After your app integrates with your virtual network, it uses the same DNS server that your virtual network is
configured with. If no custom DNS is specified, it uses Azure default DNS and any private zones linked to the
virtual network.
Limitations
There are some limitations with using regional virtual network integration:
The feature is available from all App Service deployments in Premium v2 and Premium v3. It's also available
in Basic and Standard tier but only from newer App Service deployments. If you're on an older deployment,
you can only use the feature from a Premium v2 App Service plan. If you want to make sure you can use the
feature in a Basic or Standard App Service plan, create your app in a Premium v3 App Service plan. Those
plans are only supported on our newest deployments. You can scale down if you want after the plan is
created.
The feature can't be used by Isolated plan apps that are in an App Service Environment.
You can't reach resources across peering connections with classic virtual networks.
The feature requires an unused subnet that's an IPv4 /28 block or larger in an Azure Resource Manager
virtual network.
The app and the virtual network must be in the same region.
The integration virtual network can't have IPv6 address spaces defined.
The integration subnet can't have service endpoint policies enabled.
The integration subnet can be used by only one App Service plan.
You can't delete a virtual network with an integrated app. Remove the integration before you delete the
virtual network.
You can have only one regional virtual network integration per App Service plan. Multiple apps in the same
App Service plan can use the same virtual network.
You can't change the subscription of an app or a plan while there's an app that's using regional virtual
network integration.
NOTE
The gateway-required virtual network integration feature doesn't integrate an app with a virtual network that has an
ExpressRoute gateway. Even if the ExpressRoute gateway is configured in coexistence mode, the virtual network
integration doesn't work. If you need to access resources through an ExpressRoute connection, use the regional virtual
network integration feature or an App Service Environment, which runs in your virtual network.
Peering
If you use peering with regional virtual network integration, you don't need to do any more configuration.
If you use gateway-required virtual network integration with peering, you need to configure a few more items.
To configure peering to work with your app:
1. Add a peering connection on the virtual network your app connects to. When you add the peering
connection, enable Allow vir tual network access and select Allow for warded traffic and Allow
gateway transit .
2. Add a peering connection on the virtual network that's being peered to the virtual network you're connected
to. When you add the peering connection on the destination virtual network, enable Allow vir tual network
access and select Allow for warded traffic and Allow remote gateways .
3. Go to App Ser vice plan > Networking > VNet integration in the portal. Select the virtual network your
app connects to. Under the routing section, add the address range of the virtual network that's peered with
the virtual network your app is connected to.
NOTE
The value of WEBSITE_PRIVATE_IP is bound to change. However, it will be an IP within the address range of the integration
subnet or the point-to-site address range, so you'll need to allow access from the entire address range.
Pricing details
The regional virtual network integration feature has no extra charge for use beyond the App Service plan pricing
tier charges.
Three charges are related to the use of the gateway-required virtual network integration feature:
App Ser vice plan pricing tier charges : Your apps need to be in a Basic, Standard, Premium, Premium v2,
or Premium v3 App Service plan. For more information on those costs, see App Service pricing.
Data transfer costs : There's a charge for data egress, even if the virtual network is in the same datacenter.
Those charges are described in Data transfer pricing details.
VPN gateway costs : There's a cost to the virtual network gateway that's required for the point-to-site VPN.
For more information, see VPN gateway pricing.
Troubleshooting
NOTE
Virtual network integration isn't supported for Docker Compose scenarios in App Service. Access restrictions are ignored
if a private endpoint is present.
The feature is easy to set up, but that doesn't mean your experience will be problem free. If you encounter
problems accessing your desired endpoint, there are some utilities you can use to test connectivity from the app
console. There are two consoles that you can use. One is the Kudu console, and the other is the console in the
Azure portal. To reach the Kudu console from your app, go to Tools > Kudu . You can also reach the Kudo
console at [sitename].scm.azurewebsites.net. After the website loads, go to the Debug console tab. To get to
the Azure portal-hosted console from your app, go to Tools > Console .
Tools
In native Windows apps, the tools ping , nslookup , and tracer t won't work through the console because of
security constraints (they work in custom Windows containers). To fill the void, two separate tools are added. To
test DNS functionality, we added a tool named nameresolver.exe . The syntax is:
You can use nameresolver to check the hostnames that your app depends on. This way you can test if you have
anything misconfigured with your DNS or perhaps don't have access to your DNS server. You can see the DNS
server that your app uses in the console by looking at the environmental variables WEBSITE_DNS_SERVER and
WEBSITE_DNS_ALT_SERVER.
NOTE
The nameresolver.exe tool currently doesn't work in custom Windows containers.
You can use the next tool to test for TCP connectivity to a host and port combination. This tool is called tcpping
and the syntax is:
tcpping.exe hostname [optional: port]
The tcpping utility tells you if you can reach a specific host and port. It can show success only if there's an
application listening at the host and port combination, and there's network access from your app to the specified
host and port.
Debug access to virtual network-hosted resources
A number of things can prevent your app from reaching a specific host and port. Most of the time it's one of
these things:
A firewall is in the way. If you have a firewall in the way, you hit the TCP timeout. The TCP timeout is 21
seconds in this case. Use the tcpping tool to test connectivity. TCP timeouts can be caused by many things
beyond firewalls, but start there.
DNS isn't accessible. The DNS timeout is 3 seconds per DNS server. If you have two DNS servers, the
timeout is 6 seconds. Use nameresolver to see if DNS is working. You can't use nslookup, because that
doesn't use the DNS your virtual network is configured with. If inaccessible, you could have a firewall or NSG
blocking access to DNS or it could be down.
If those items don't answer your problems, look first for things like:
Regional vir tual network integration
Is your destination a non-RFC1918 address and you don't have Route All enabled?
Is there an NSG blocking egress from your integration subnet?
If you're going across Azure ExpressRoute or a VPN, is your on-premises gateway configured to route traffic
back up to Azure? If you can reach endpoints in your virtual network but not on-premises, check your routes.
Do you have enough permissions to set delegation on the integration subnet? During regional virtual
network integration configuration, your integration subnet is delegated to Microsoft.Web/serverFarms. The
VNet integration UI delegates the subnet to Microsoft.Web/serverFarms automatically. If your account
doesn't have sufficient networking permissions to set delegation, you'll need someone who can set attributes
on your integration subnet to delegate the subnet. To manually delegate the integration subnet, go to the
Azure Virtual Network subnet UI and set the delegation for Microsoft.Web/serverFarms.
Gateway-required vir tual network integration
Is the point-to-site address range in the RFC 1918 ranges (10.0.0.0-10.255.255.255 / 172.16.0.0-
172.31.255.255 / 192.168.0.0-192.168.255.255)?
Does the gateway show as being up in the portal? If your gateway is down, then bring it back up.
Do certificates show as being in sync, or do you suspect that the network configuration was changed? If your
certificates are out of sync or you suspect that a change was made to your virtual network configuration that
wasn't synced with your ASPs, select Sync Network .
If you're going across a VPN, is the on-premises gateway configured to route traffic back up to Azure? If you
can reach endpoints in your virtual network but not on-premises, check your routes.
Are you trying to use a coexistence gateway that supports both point to site and ExpressRoute? Coexistence
gateways aren't supported with virtual network integration.
Debugging networking issues is a challenge because you can't see what's blocking access to a specific host:port
combination. Some causes include:
You have a firewall up on your host that prevents access to the application port from your point-to-site IP
range. Crossing subnets often requires public access.
Your target host is down.
Your application is down.
You had the wrong IP or hostname.
Your application is listening on a different port than what you expected. You can match your process ID with
the listening port by using "netstat -aon" on the endpoint host.
Your network security groups are configured in such a manner that they prevent access to your application
host and port from your point-to-site IP range.
You don't know what address your app actually uses. It could be any address in the integration subnet or point-
to-site address range, so you need to allow access from the entire address range.
More debug steps include:
Connect to a VM in your virtual network and attempt to reach your resource host:port from there. To test
for TCP access, use the PowerShell command test-netconnection . The syntax is:
Bring up an application on a VM and test access to that host and port from the console from your app by
using tcpping .
On-premises resources
If your app can't reach a resource on-premises, check if you can reach the resource from your virtual network.
Use the test-netconnection PowerShell command to check for TCP access. If your VM can't reach your on-
premises resource, your VPN or ExpressRoute connection might not be configured properly.
If your virtual network-hosted VM can reach your on-premises system but your app can't, the cause is likely one
of the following reasons:
Your routes aren't configured with your subnet or point-to-site address ranges in your on-premises gateway.
Your network security groups are blocking access for your point-to-site IP range.
Your on-premises firewalls are blocking traffic from your point-to-site IP range.
You're trying to reach a non-RFC 1918 address by using the regional virtual network integration feature.
Deleting the App Service plan or web app before disconnecting the VNet integration
If you deleted the web app or the App Service plan without disconnecting the VNet integration first, you will not
be able to do any update/delete operations on the virtual network or subnet that was used for the integration
with the deleted resource. A subnet delegation 'Microsoft.Web/serverFarms' will remain assigned to your
subnet and will prevent the update/delete operations.
In order to do update/delete the subnet or virtual network again you need to re-create the VNet integration and
then disconnect it:
1. Re-create the App Service plan and web app (it is mandatory to use the exact same web app name as before).
2. Navigate to the 'Networking' blade on the web app and configure the VNet integration.
3. After the VNet integration is configured, select the 'Disconnect' button.
4. Delete the App Service plan or web app.
5. Update/Delete the subnet or virtual network.
If you still encounter issues with the VNet integration after following the steps above, please contact Microsoft
Support.
Application Gateway integration
5/18/2022 • 4 minutes to read • Edit Online
There are three variations of App Service that require slightly different configuration of the integration with
Azure Application Gateway. The variations include regular App Service - also known as multi-tenant, Internal
Load Balancer (ILB) App Service Environment (ASE) and External ASE. This article will walk through how to
configure it with App Service (multi-tenant) using service endpoint to secure traffic. The article will also discuss
considerations around using private endpoint and integrating with ILB, and External ASE. Finally the article has
considerations on scm/kudu site.
There are two parts to this configuration besides creating the App Service and the Application Gateway. The first
part is enabling service endpoints in the subnet of the Virtual Network where the Application Gateway is
deployed. Service endpoints will ensure all network traffic leaving the subnet towards the App Service will be
tagged with the specific subnet ID. The second part is to set an access restriction of the specific web app to
ensure that only traffic tagged with this specific subnet ID is allowed. You can configure it using different tools
depending on preference.
az webapp config access-restriction add --resource-group myRG --name myWebApp --rule-name AppGwSubnet --
priority 200 --subnet mySubNetName --vnet-name myVnetName
In the default configuration, the command will ensure both setup of the service endpoint configuration in the
subnet and the access restriction in the App Service.
If you want to set individual access restrictions for the scm site, you can add access restrictions using the --scm-
site flag like shown below.
az webapp config access-restriction add --resource-group myRG --name myWebApp --scm-site --rule-name
KudoAccess --priority 200 --ip-address 208.130.0.0/16
Next steps
For more information on the App Service Environment, see App Service Environment documentation.
To further secure your web app, information about Web Application Firewall on Application Gateway can be
found in the Azure Web Application Firewall documentation.
Virtual Network NAT gateway integration
5/18/2022 • 3 minutes to read • Edit Online
NAT gateway is a fully managed, highly resilient service, which can be associated with one or more subnets and
ensures that all outbound Internet-facing traffic will be routed through the gateway. With App Service, there are
two important scenarios that you can use NAT gateway for.
The NAT gateway gives you a static predictable public IP for outbound Internet-facing traffic. It also significantly
increases the available SNAT ports in scenarios where you have a high number of concurrent connections to the
same public address/port combination.
For more information and pricing. Go to the NAT gateway overview.
NOTE
Using NAT gateway with App Service is dependent on virtual network integration, and therefore a supported App
Service plan pricing tier is required.
When using NAT gateway together with App Service, all traffic to Azure Storage must be using private endpoint or
service endpoint.
NAT gateway cannot be used together with App Service Environment v1 or v2.
7. Fill in tags if needed and Create the NAT gateway. After the NAT gateway is provisioned, click on the Go to
resource group and select the new NAT gateway. You can see the public IP that your app will use for
outbound Internet-facing traffic in the Outbound IP blade.
If you prefer using CLI to configure your environment, these are the important commands. As a prerequisite,
you should create an app with virtual network integration configured.
Ensure Route All is configured for your virtual network integration:
az network public-ip create --resource-group [myResourceGroup] --name myPublicIP --sku standard --allocation
static
Associate the NAT gateway with the virtual network integration subnet:
Next steps
For more information on the NAT gateway, see NAT gateway documentation.
For more information on virtual network integration, see Virtual network integration documentation.
Controlling Azure App Service traffic with Azure
Traffic Manager
5/18/2022 • 2 minutes to read • Edit Online
NOTE
This article provides summary information for Microsoft Azure Traffic Manager as it relates to Azure App Service. More
information about Azure Traffic Manager itself can be found by visiting the links at the end of this article.
Introduction
You can use Azure Traffic Manager to control how requests from web clients are distributed to apps in Azure
App Service. When App Service endpoints are added to an Azure Traffic Manager profile, Azure Traffic Manager
keeps track of the status of your App Service apps (running, stopped, or deleted) so that it can decide which of
those endpoints should receive traffic.
Routing methods
Azure Traffic Manager uses four different routing methods. These methods are described in the following list as
they pertain to Azure App Service.
Priority : use a primary app for all traffic, and provide backups in case the primary or the backup apps are
unavailable.
Weighted : distribute traffic across a set of apps, either evenly or according to weights, which you define.
Performance : when you have apps in different geographic locations, use the "closest" app in terms of the
lowest network latency.
Geographic : direct users to specific apps based on which geographic location their DNS query originates
from.
For more information, see Traffic Manager routing methods.
Next Steps
For a conceptual and technical overview of Azure Traffic Manager, see Traffic Manager Overview.
Azure App Service Local Cache overview
5/18/2022 • 7 minutes to read • Edit Online
NOTE
Local cache is not supported in function apps or containerized App Service apps, such as in Windows Containers or in
App Service on Linux. A version of local cache that is available for these app types is App Cache.
Azure App Service content is stored on Azure Storage and is surfaced in a durable manner as a content share.
This design is intended to work with a variety of apps and has the following attributes:
The content is shared across multiple virtual machine (VM) instances of the app.
The content is durable and can be modified by running apps.
Log files and diagnostic data files are available under the same shared content folder.
Publishing new content directly updates the content folder. You can immediately view the same content
through the SCM website and the running app (typically some technologies such as ASP.NET do initiate an
app restart on some file changes to get the latest content).
While many apps use one or all of these features, some apps just need a high-performance, read-only content
store that they can run from with high availability. These apps can benefit from a VM instance of a specific local
cache.
The Azure App Service Local Cache feature provides a web role view of your content. This content is a write-but-
discard cache of your storage content that is created asynchronously on-site startup. When the cache is ready,
the site is switched to run against the cached content. Apps that run on Local Cache have the following benefits:
They are immune to latencies that occur when they access content on Azure Storage.
They are immune to the planned upgrades or unplanned downtimes and any other disruptions with Azure
Storage that occur on servers that serve the content share.
They have fewer app restarts due to storage share changes.
You configure Local Cache by using a combination of reserved app settings. You can configure these app
settings by using the following methods:
Azure portal
Azure Resource Manager
Configure Local Cache by using the Azure portal
You enable Local Cache on a per-web-app basis by using this app setting: WEBSITE_LOCAL_CACHE_OPTION = Always
{
"apiVersion": "2015-08-01",
"type": "config",
"name": "appsettings",
"dependsOn": [
"[resourceId('Microsoft.Web/sites/', variables('siteName'))]"
],
"properties": {
"WEBSITE_LOCAL_CACHE_OPTION": "Always",
"WEBSITE_LOCAL_CACHE_SIZEINMB": "1000"
}
}
...
NOTE
The run from package deployment option is not compatible with local cache.
More resources
Environment variables and app settings reference
Azure App Service diagnostics overview
5/18/2022 • 5 minutes to read • Edit Online
When you’re running a web application, you want to be prepared for any issues that may arise, from 500 errors
to your users telling you that your site is down. App Service diagnostics is an intelligent and interactive
experience to help you troubleshoot your app with no configuration required. When you do run into issues with
your app, App Service diagnostics points out what’s wrong to guide you to the right information to more easily
and quickly troubleshoot and resolve the issue.
Although this experience is most helpful when you’re having issues with your app within the last 24 hours, all
the diagnostic graphs are always available for you to analyze.
App Service diagnostics works for not only your app on Windows, but also apps on Linux/containers, App
Service Environment, and Azure Functions.
Interactive interface
Once you select a homepage category that best aligns with your app's problem, App Service diagnostics'
interactive interface, Genie, can guide you through diagnosing and solving problem with your app. You can use
the tile shortcuts provided by Genie to view the full diagnostic report of the problem category that you are
interested. The tile shortcuts provide you a direct way of accessing your diagnostic metrics.
After clicking on these tiles, you can see a list of topics related to the issue described in the tile. These topics
provide snippets of notable information from the full report. You can click on any of these topics to investigate
the issues further. Also, you can click on View Full Repor t to explore all the topics on a single page.
Diagnostic report
After you choose to investigate the issue further by clicking on a topic, you can view more details about the
topic often supplemented with graphs and markdowns. Diagnostic report can be a powerful tool for pinpointing
the problem with your app.
Health checkup
If you don't know what’s wrong with your app or don’t know where to start troubleshooting your issues, the
health checkup is a good place to start. The health checkup analyzes your applications to give you a quick,
interactive overview that points out what’s healthy and what’s wrong, telling you where to look to investigate
the issue. Its intelligent and interactive interface provides you with guidance through the troubleshooting
process. Health checkup is integrated with the Genie experience for Windows apps and web app down
diagnostic report for Linux apps.
Health checkup graphs
There are four different graphs in the health checkup.
requests and errors: A graph that shows the number of requests made over the last 24 hours along with
HTTP server errors.
app performance: A graph that shows response time over the last 24 hours for various percentile groups.
CPU usage: A graph that shows the overall percent CPU usage per instance over the last 24 hours.
memor y usage: A graph that shows the overall percent physical memory usage per instance over the last
24 hours.
Investigate application code issues (only for Windows app)
Because many app issues are related to issues in your application code, App Service diagnostics integrates with
Application Insights to highlight exceptions and dependency issues to correlate with the selected downtime.
Application Insights has to be enabled separately.
To view Application Insights exceptions and dependencies, select the web app down or web app slow tile
shortcuts.
Troubleshooting steps (only for Windows app)
If an issue is detected with a specific problem category within the last 24 hours, you can view the full diagnostic
report, and App Service diagnostics may prompt you to view more troubleshooting advice and next steps for a
more guided experience.
Diagnostic tools
Diagnostics Tools include more advanced diagnostic tools that help you investigate application code issues,
slowness, connection strings, and more. and proactive tools that help you mitigate issues with CPU usage,
requests, and memory.
Proactive CPU monitoring (only for Windows app)
Proactive CPU monitoring provides you an easy, proactive way to take an action when your app or child process
for your app is consuming high CPU resources. You can set your own CPU threshold rules to temporarily
mitigate a high CPU issue until the real cause for the unexpected issue is found. For more information, see
Mitigate your CPU problems before they happen.
Auto -healing
Auto-healing is a mitigation action you can take when your app is having unexpected behavior. You can set your
own rules based on request count, slow request, memory limit, and HTTP status code to trigger mitigation
actions. Use the tool to temporarily mitigate an unexpected behavior until you find the root cause. The tool is
currently available for Windows Web Apps, Linux Web Apps, and Linux Custom Containers. Supported
conditions and mitigation vary depending on the type of the web app. For more information, see Announcing
the new auto healing experience in app service diagnostics and Announcing Auto Heal for Linux.
Proactive auto -healing (only for Windows app)
Like proactive CPU monitoring, proactive auto-healing is a turn-key solution to mitigating unexpected behavior
of your app. Proactive auto-healing restarts your app when App Service determines that your app is in an
unrecoverable state. For more information, see Introducing Proactive Auto Heal.
More resources
Tutorial: Run a load test to identify performance bottlenecks in a web app
Configure an App Service app
5/18/2022 • 14 minutes to read • Edit Online
This article explains how to configure common settings for web apps, mobile back end, or API app.
NOTE
App settings can also be resolved from Key Vault using Key Vault references.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
2. In the app's left menu, select Configuration > Application settings .
By default, values for app settings are hidden in the portal for security. To see a hidden value of an app
setting, click its Value field. To see the hidden values of all app settings, click the Show values button.
3. To add a new app setting, click New application setting . To edit a setting, click the Edit button on the
right side.
4. In the dialog, you can stick the setting to the current slot.
App setting names can't contain periods ( . ). If an app setting contains a period, the period is replaced
with an underscore in the container.
NOTE
In a default Linux app service or a custom Linux container, any nested JSON key structure in the app setting name
like ApplicationInsights:InstrumentationKey needs to be configured in App Service as
ApplicationInsights__InstrumentationKey for the key name. In other words, any : should be replaced by
__ (double underscore).
5. When finished, click Update . Don't forget to click Save back in the Configuration page.
Edit app settings in bulk
Azure portal
Azure CLI
Azure PowerShell
Click the Advanced edit button. Edit the settings in the text area. When finished, click Update . Don't forget to
click Save back in the Configuration page.
App settings have the following JSON formatting:
[
{
"name": "<key-1>",
"value": "<value-1>",
"slotSetting": false
},
{
"name": "<key-2>",
"value": "<value-2>",
"slotSetting": false
},
...
]
For ASP.NET and ASP.NET Core developers, setting connection strings in App Service are like setting them in
<connectionStrings> in Web.config, but the values you set in App Service override the ones in Web.config. You
can keep development settings (for example, a database file) in Web.config and production secrets (for example,
SQL Database credentials) safely in App Service. The same code uses your development settings when you
debug locally, and it uses your production secrets when deployed to Azure.
For other language stacks, it's better to use app settings instead, because connection strings require special
formatting in the variable keys in order to access the values.
NOTE
There is one case where you may want to use connection strings instead of app settings for non-.NET languages: certain
Azure database types are backed up along with the app only if you configure a connection string for the database in your
App Service app. For more information, see What gets backed up. If you don't need this automated backup, then use app
settings.
At runtime, connection strings are available as environment variables, prefixed with the following connection
types:
SQLServer: SQLCONNSTR_
MySQL: MYSQLCONNSTR_
SQLAzure: SQLAZURECONNSTR_
Custom: CUSTOMCONNSTR_
PostgreSQL: POSTGRESQLCONNSTR_
For example, a MySQL connection string named connectionstring1 can be accessed as the environment variable
MYSQLCONNSTR_connectionString1 . For language-stack specific steps, see:
ASP.NET Core
Node.js
PHP
Python
Java
Ruby
Custom containers
Connection strings are always encrypted when stored (encrypted-at-rest).
NOTE
Connection strings can also be resolved from Key Vault using Key Vault references.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
Click the Advanced edit button. Edit the connection strings in the text area. When finished, click Update . Don't
forget to click Save back in the Configuration page.
Connection strings have the following JSON formatting:
[
{
"name": "name-1",
"value": "conn-string-1",
"type": "SQLServer",
"slotSetting": false
},
{
"name": "name-2",
"value": "conn-string-2",
"type": "PostgreSQL",
"slotSetting": false
},
...
]
Configure language stack settings
ASP.NET Core
Node.js
PHP
Python
Java
Ruby
In the Azure portal, search for and select App Ser vices , and then select your app. In the app's left menu, select
Configuration > General settings .
Here, you can configure some common settings for the app. Some settings require you to scale up to higher
pricing tiers.
Stack settings : The software stack to run the app, including the language and SDK versions.
For Linux apps, you can select the language runtime version and set an optional Star tup command or a
startup command file.
Platform settings : Lets you configure settings for the hosting platform, including:
FTP state : Allow only FTPS or disable FTP altogether.
Bitness : 32-bit or 64-bit. (Defaults to 32-bit for App Service created in the portal.)
WebSocket protocol : For ASP.NET SignalR or socket.io, for example.
Always On : Keeps the app loaded even when there's no traffic. When Always On is not turned on
(default), the app is unloaded after 20 minutes without any incoming requests. The unloaded app
can cause high latency for new requests because of its warm-up time. When Always On is turned
on, the front-end load balancer sends a GET request to the application root every five minutes. The
continuous ping prevents the app from being unloaded.
Always On is required for continuous WebJobs or for WebJobs that are triggered using a CRON
expression.
HTTP version : Set to 2.0 to enable support for HTTPS/2 protocol.
NOTE
Most modern browsers support HTTP/2 protocol over TLS only, while non-encrypted traffic continues to use
HTTP/1.1. To ensure that client browsers connect to your app with HTTP/2, secure your custom DNS name. For
more information, see Secure a custom DNS name with a TLS/SSL binding in Azure App Service.
ARR affinity : In a multi-instance deployment, ensure that the client is routed to the same instance for
the life of the session. You can set this option to Off for stateless applications.
Debugging : Enable remote debugging for ASP.NET, ASP.NET Core, or Node.js apps. This option turns off
automatically after 48 hours.
Incoming client cer tificates : require client certificates in mutual authentication.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
2. In the app's left menu, select Configuration > Default documents .
3. To add a default document, click New document . To remove a default document, click Delete to its right.
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, search for and select App Ser vices , and then select your app.
2. In the app's left menu, select Configuration > Path mappings
3. Click New vir tual application or director y .
To map a virtual directory to a physical path, leave the Director y check box selected. Specify the
virtual directory and the corresponding relative (physical) path to the website root ( D:\home ).
To mark a virtual directory as a web application, clear the Director y check box.
4. Click OK .
Next steps
Environment variables and app settings reference
Configure a custom domain name in Azure App Service
Set up staging environments in Azure App Service
Secure a custom DNS name with a TLS/SSL binding in Azure App Service
Enable diagnostic logs
Scale an app in Azure App Service
Monitoring basics in Azure App Service
Change applicationHost.config settings with applicationHost.xdt
Configure an ASP.NET app for Azure App Service
5/18/2022 • 3 minutes to read • Edit Online
NOTE
For ASP.NET Core, see Configure an ASP.NET Core app for Azure App Service
ASP.NET apps must be deployed to Azure App Service as compiled binaries. The Visual Studio publishing tool
builds the solution and then deploys the compiled binaries directly, whereas the App Service deployment engine
deploys the code repository first and then compiles the binaries.
This guide provides key concepts and instructions for ASP.NET developers. If you've never used Azure App
Service, follow the ASP.NET quickstart and ASP.NET with SQL Database tutorial first.
A value of v4.0 means the latest CLR 4 version (.NET Framework 4.x) is used. A value of v2.0 means a CLR 2
version (.NET Framework 3.5) is used.
using System.Configuration;
...
// Get an app setting
ConfigurationManager.AppSettings["MySetting"];
// Get a connection string
ConfigurationManager.ConnectionStrings["MyConnection"];
}
If you configure an app setting with the same name in App Service and in web.config, the App Service value
takes precedence over the web.config value. The local web.config value lets you debug the app locally, but the
App Service value lets your run the app in product with production settings. Connection strings work in the
same way. This way, you can keep your application secrets outside of your code repository and access the
appropriate values without changing your code.
<system.web>
<customErrors mode="Off"/>
</system.web>
Redeploy your app with the updated Web.config. You should now see the same detailed exception page.
To access the console logs generated from inside your application code in App Service, turn on diagnostics
logging by running the following command in the Cloud Shell:
az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging
filesystem --level Verbose
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
More resources
Tutorial: Build an ASP.NET app in Azure with SQL Database
Environment variables and app settings reference
Configure an ASP.NET Core app for Azure App
Service
5/18/2022 • 7 minutes to read • Edit Online
NOTE
For ASP.NET in .NET Framework, see Configure an ASP.NET app for Azure App Service
ASP.NET Core apps must be deployed to Azure App Service as compiled binaries. The Visual Studio publishing
tool builds the solution and then deploys the compiled binaries directly, whereas the App Service deployment
engine deploys the code repository first and then compiles the binaries.
This guide provides key concepts and instructions for ASP.NET Core developers. If you've never used Azure App
Service, follow the ASP.NET Core quickstart and ASP.NET Core with SQL Database tutorial first.
dotnet --info
To show all supported .NET Core versions, run the following command in the Cloud Shell:
For additional environment variables to customize build automation, see Oryx configuration.
For more information on how App Service runs and builds ASP.NET Core apps in Linux, see Oryx
documentation: How .NET Core apps are detected and built.
using Microsoft.Extensions.Configuration;
namespace SomeNamespace
{
public class SomeClass
{
private IConfiguration _configuration;
public SomeMethod()
{
// retrieve nested App Service app setting
var myHierarchicalConfig = _configuration["My:Hierarchical:Config:Data"];
// retrieve App Service connection string
var myConnString = _configuration.GetConnectionString("MyDbConnection");
}
}
}
If you configure an app setting with the same name in App Service and in appsettings.json, for example, the App
Service value takes precedence over the appsettings.json value. The local appsettings.json value lets you debug
the app locally, but the App Service value lets your run the app in production with production settings.
Connection strings work in the same way. This way, you can keep your application secrets outside of your code
repository and access the appropriate values without changing your code.
NOTE
Note the hierarchical configuration data in appsettings.json is accessed using the __ (double underscore) delimiter that's
standard on Linux to .NET Core. To override a specific hierarchical configuration setting in App Service, set the app setting
name with the same delimited format in the key. you can run the following example in the Cloud Shell:
NOTE
Note the hierarchical configuration data in appsettings.json is accessed using the : delimiter that's standard to .NET
Core. To override a specific hierarchical configuration setting in App Service, set the app setting name with the same
delimited format in the key. you can run the following example in the Cloud Shell:
You can then configure and generate logs with the standard .NET Core pattern.
To access the console logs generated from inside your application code in App Service, turn on diagnostics
logging by running the following command in the Cloud Shell:
az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging
filesystem --level Verbose
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
Putting all three elements together, your code looks like the following example:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
// These three subnets encapsulate the applicable Azure subnets. At the moment, it's not possible to
narrow it down further.
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:10.0.0.0"), 104));
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:192.168.0.0"), 112));
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:172.16.0.0"), 108));
});
}
...
app.UseMvc();
}
For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.
https://<app-name>.scm.azurewebsites.net/webssh/host
If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. Once
authenticated, you see an in-browser shell, where you can run commands inside your container.
NOTE
Any changes you make outside the /home directory are stored in the container itself and don't persist beyond an app
restart.
To open a remote SSH session from your local machine, see Open SSH session from remote shell.
robots933456 in logs
You may see the following message in the container logs:
You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if
the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it
lets App Service know that the container is healthy and ready to respond to requests.
Next steps
Tutorial: ASP.NET Core app with SQL Database
App Service Linux FAQ
Or, see additional resources:
Environment variables and app settings reference
Configure a Node.js app for Azure App Service
5/18/2022 • 11 minutes to read • Edit Online
Node.js apps must be deployed with all the required NPM dependencies. The App Service deployment engine
automatically runs npm install --production for you when you deploy a Git repository, or a Zip package with
build automation enabled. If you deploy your files using FTP/S, however, you need to upload the required
packages manually.
This guide provides key concepts and instructions for Node.js developers who deploy to App Service. If you've
never used Azure App Service, follow the Node.js quickstart and Node.js with MongoDB tutorial first.
az webapp config appsettings list --name <app-name> --resource-group <resource-group-name> --query "[?
name=='WEBSITE_NODE_DEFAULT_VERSION'].value"
To show the current Node.js version, run the following command in the Cloud Shell:
To show all supported Node.js versions, run the following command in the Cloud Shell:
NOTE
This example uses the recommended "tilde syntax" to target the latest available version of Node.js 16 runtime on App
Service.
Since the runtime is regularly patched and updated by the platform it's not recommended to target a specific minor
version/patch as these are not guaranteed to be available due to potential security risks.
NOTE
You should set the Node.js version in your project's package.json . The deployment engine runs in a separate process
that contains all the supported Node.js versions.
To set your app to a supported Node.js version, run the following command in the Cloud Shell:
This setting specifies the Node.js version to use, both at runtime and during automated package restore in Kudu.
NOTE
You should set the Node.js version in your project's package.json . The deployment engine runs in a separate container
that contains all the supported Node.js versions.
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
PRE_BUILD_COMMANDand POST_BUILD_COMMAND are environment variables that are empty by default. To run pre-
build commands, define PRE_BUILD_COMMAND . To run post-build commands, define POST_BUILD_COMMAND .
The following example specifies the two variables to a series of commands, separated by commas.
For additional environment variables to customize build automation, see Oryx configuration.
For more information on how App Service runs and builds Node.js apps in Linux, see Oryx documentation: How
Node.js apps are detected and built.
TO O L P URP O SE
To add a custom start file, run the following command in the Cloud Shell:
az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "npm run
start:prod"
{
...
"scripts": {
"start": "gulp",
...
},
...
}
To use a custom package.json in your project, run the following command in the Cloud Shell:
Debug remotely
NOTE
Remote debugging is currently in Preview.
You can debug your Node.js app remotely in Visual Studio Code if you configure it to run with PM2, except when
you run it using a .config.js,.yml, or .yaml.
In most cases, no extra configuration is required for your app. If your app is run with a process.json file (default
or custom), it must have a script property in the JSON root. For example:
{
"name" : "worker",
"script" : "./index.js",
...
}
To set up Visual Studio Code for remote debugging, install the App Service extension. Follow the instructions on
the extension page and sign in to Azure in Visual Studio Code.
In the Azure explorer, find the app you want to debug, right-click it and select Star t Remote Debugging . Click
Yes to enable it for your app. App Service starts a tunnel proxy for you and attaches the debugger. You can then
make requests to the app and see the debugger pausing at break points.
Once finished with debugging, stop the debugger by selecting Disconnect . When prompted, you should click
Yes to disable remote debugging. To disable it later, right-click your app again in the Azure explorer and select
Disable Remote Debugging .
process.env.NODE_ENV
Run Grunt/Bower/Gulp
By default, App Service build automation runs npm install --production when it recognizes a Node.js app is
deployed through Git, or through Zip deployment with build automation enabled. If your app requires any of the
popular automation tools, such as Grunt, Bower, or Gulp, you need to supply a custom deployment script to run
it.
To enable your repository to run these tools, you need to add them to the dependencies in package.json. For
example:
"dependencies": {
"bower": "^1.7.9",
"grunt": "^1.0.1",
"gulp": "^3.9.1",
...
}
From a local terminal window, change directory to your repository root and run the following commands:
Your repository root now has two additional files: .deployment and deploy.sh.
Open deploy.sh and find the Deployment section, which looks like this:
############################################################################################################
######################
# Deployment
# ----------
This section ends with running npm install --production . Add the code section you need to run the required
tool at the end of the Deployment section:
Bower
Gulp
Grunt
See an example in the MEAN.js sample, where the deployment script also runs a custom npm install
command.
Bower
This snippet runs bower install .
if [ -e "$DEPLOYMENT_TARGET/bower.json" ]; then
cd "$DEPLOYMENT_TARGET"
eval ./node_modules/.bin/bower install
exitWithMessageOnError "bower failed"
cd - > /dev/null
fi
Gulp
This snippet runs gulp imagemin .
if [ -e "$DEPLOYMENT_TARGET/gulpfile.js" ]; then
cd "$DEPLOYMENT_TARGET"
eval ./node_modules/.bin/gulp imagemin
exitWithMessageOnError "gulp failed"
cd - > /dev/null
fi
Grunt
This snippet runs grunt .
if [ -e "$DEPLOYMENT_TARGET/Gruntfile.js" ]; then
cd "$DEPLOYMENT_TARGET"
eval ./node_modules/.bin/grunt
exitWithMessageOnError "Grunt failed"
cd - > /dev/null
fi
app.set('trust proxy', 1)
...
if (req.secure) {
// Do something when HTTPS is used
}
Access diagnostic logs
To access the console logs generated from inside your application code in App Service, turn on diagnostics
logging by running the following command in the Cloud Shell:
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
Replace <app-name> and <resource-group-name> with the names appropriate for your web app.
Once container logging is turned on, run the following command to see the log stream:
robots933456 in logs
You may see the following message in the container logs:
You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if
the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it
lets App Service know that the container is healthy and ready to respond to requests.
Next steps
Tutorial: Node.js app with MongoDB
App Service Linux FAQ
Or, see additional resources:
Environment variables and app settings reference
Configure a PHP app for Azure App Service
5/18/2022 • 12 minutes to read • Edit Online
This guide shows you how to configure your PHP web apps, mobile back ends, and API apps in Azure App
Service.
This guide provides key concepts and instructions for PHP developers who deploy apps to App Service. If you've
never used Azure App Service, follow the PHP quickstart and PHP with MySQL tutorial first.
NOTE
To address a development slot, include the parameter --slot followed by the name of the slot.
To show all supported PHP versions, run the following command in the Cloud Shell:
To show the current PHP version, run the following command in the Cloud Shell:
NOTE
To address a development slot, include the parameter --slot followed by the name of the slot.
To show all supported PHP versions, run the following command in the Cloud Shell:
Run the following command in the Cloud Shell to set the PHP version to 8.0:
Your repository root now has two additional files: .deployment and deploy.sh.
Open deploy.sh and find the Deployment section, which looks like this:
############################################################################################################
######################
# Deployment
# ----------
Add the code section you need to run the required tool at the end of the Deployment section:
# 4. Use composer
echo "$DEPLOYMENT_TARGET"
if [ -e "$DEPLOYMENT_TARGET/composer.json" ]; then
echo "Found composer.json"
pushd "$DEPLOYMENT_TARGET"
php composer.phar install $COMPOSER_ARGS
exitWithMessageOnError "Composer install failed"
popd
fi
Commit all your changes and deploy your code using Git, or Zip deploy with build automation enabled.
Composer should now be running as part of deployment automation.
Run Grunt/Bower/Gulp
If you want App Service to run popular automation tools at deployment time, such as Grunt, Bower, or Gulp, you
need to supply a custom deployment script. App Service runs this script when you deploy with Git, or with Zip
deployment with with build automation enabled.
To enable your repository to run these tools, you need to add them to the dependencies in package.json. For
example:
"dependencies": {
"bower": "^1.7.9",
"grunt": "^1.0.1",
"gulp": "^3.9.1",
...
}
From a local terminal window, change directory to your repository root and run the following commands (you
need npm installed):
npm install kuduscript -g
kuduscript --node --scriptType bash --suppressPrompt
Your repository root now has two additional files: .deployment and deploy.sh.
Open deploy.sh and find the Deployment section, which looks like this:
############################################################################################################
######################
# Deployment
# ----------
This section ends with running npm install --production . Add the code section you need to run the required
tool at the end of the Deployment section:
Bower
Gulp
Grunt
See an example in the MEAN.js sample, where the deployment script also runs a custom npm install
command.
Bower
This snippet runs bower install .
if [ -e "$DEPLOYMENT_TARGET/bower.json" ]; then
cd "$DEPLOYMENT_TARGET"
eval ./node_modules/.bin/bower install
exitWithMessageOnError "bower failed"
cd - > /dev/null
fi
Gulp
This snippet runs gulp imagemin .
if [ -e "$DEPLOYMENT_TARGET/gulpfile.js" ]; then
cd "$DEPLOYMENT_TARGET"
eval ./node_modules/.bin/gulp imagemin
exitWithMessageOnError "gulp failed"
cd - > /dev/null
fi
Grunt
This snippet runs grunt .
if [ -e "$DEPLOYMENT_TARGET/Gruntfile.js" ]; then
cd "$DEPLOYMENT_TARGET"
eval ./node_modules/.bin/grunt
exitWithMessageOnError "Grunt failed"
cd - > /dev/null
fi
PRE_BUILD_COMMANDand POST_BUILD_COMMAND are environment variables that are empty by default. To run pre-
build commands, define PRE_BUILD_COMMAND . To run post-build commands, define POST_BUILD_COMMAND .
The following example specifies the two variables to a series of commands, separated by commas.
For additional environment variables to customize build automation, see Oryx configuration.
For more information on how App Service runs and builds PHP apps in Linux, see Oryx documentation: How
PHP apps are detected and built.
Customize start-up
By default, the built-in PHP container runs the Apache server. At start-up, it runs apache2ctl -D FOREGROUND" . If
you like, you can run a different command at start-up, by running the following command in the Cloud Shell:
getenv("DB_HOST")
az resource update --name web --resource-group <group-name> --namespace Microsoft.Web --resource-type config
--parent sites/<app-name> --set properties.virtualApplications[0].physicalPath="site\wwwroot\public" --api-
version 2015-06-01
By default, Azure App Service points the root virtual application path (/) to the root directory of the deployed
application files (sites\wwwroot).
The web framework of your choice may use a subdirectory as the site root. For example, Laravel, uses the
public/ subdirectory as the site root.
The default PHP image for App Service uses Apache, and it doesn't let you customize the site root for your app.
To work around this limitation, add an .htaccess file to your repository root with the following content:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)
RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]
</IfModule>
If you would rather not use .htaccess rewrite, you can deploy your Laravel application with a custom Docker
image instead.
Popular web frameworks let you access the X-Forwarded-* information in your standard app pattern. In
CodeIgniter, the is_https() checks the value of X_FORWARDED_PROTO by default.
NOTE
The best way to see the PHP version and the current php.ini configuration is to call phpinfo() in your app.
Add configuration settings to the .user.ini file using the same syntax you would use in a php.ini file. For
example, if you wanted to turn on the display_errors setting and set upload_max_filesize setting to 10M, your
.user.ini file would contain this text:
; Example Settings
display_errors=On
upload_max_filesize=10M
Redeploy your app with the changes and restart it. If you deploy it with Kudu (for example, using Git), it's
automatically restarted after deployment.
As an alternative to using .htaccess, you can use ini_set() in your app to customize these non-PHP_INI_SYSTEM
directives.
Customize PHP_INI_SYSTEM directives
To customize PHP_INI_SYSTEM directives (see php.ini directives), you can't use the .htaccess approach. App
Service provides a separate mechanism using the PHP_INI_SCAN_DIR app setting.
First, run the following command in the Cloud Shell to add an app setting called PHP_INI_SCAN_DIR :
Create a directory in d:\home\site called ini , then create an .ini file in the d:\home\site\ini directory (for
example, settings.ini) with the directives you want to customize. Use the same syntax you would use in a php.ini
file.
For example, to change the value of expose_php run the following commands:
cd /home/site
mkdir ini
echo "expose_php = Off" >> ini/setting.ini
/usr/local/etc/php/conf.d is the default directory where php.ini exists. /home/site/ini is the custom directory
in which you'll add a custom .ini file. You separate the values with a : .
Navigate to the web SSH session with your Linux container (
https://<app-name>.scm.azurewebsites.net/webssh/host ).
Create a directory in /home/site called ini , then create an .ini file in the /home/site/ini directory (for
example, settings.ini) with the directives you want to customize. Use the same syntax you would use in a php.ini
file.
TIP
In the built-in Linux containers in App Service, /home is used as persisted shared storage.
For example, to change the value of expose_php run the following commands:
cd /home/site
mkdir ini
echo "expose_php = Off" >> ini/setting.ini
NOTE
The best way to see the PHP version and the current php.ini configuration is to call phpinfo() in your app.
extension=d:\home\site\wwwroot\bin\mongodb.dll
zend_extension=d:\home\site\wwwroot\bin\xdebug.dll
NOTE
The best way to see the PHP version and the current php.ini configuration is to call phpinfo() in your app.
extension=/home/site/wwwroot/bin/mongodb.so
zend_extension=/home/site/wwwroot/bin/xdebug.so
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
Replace <app-name> and <resource-group-name> with the names appropriate for your web app.
Once container logging is turned on, run the following command to see the log stream:
Troubleshooting
When a working PHP app behaves differently in App Service or has errors, try the following:
Access the log stream.
Test the app locally in production mode. App Service runs your app in production mode, so you need to
make sure that your project works as expected in production mode locally. For example:
Depending on your composer.json, different packages may be installed for production mode ( require
vs. require-dev ).
Certain web frameworks may deploy static files differently in production mode.
Certain web frameworks may use custom startup scripts when running in production mode.
Run your app in App Service in debug mode. For example, in Laravel, you can configure your app to output
debug messages in production by setting the APP_DEBUG app setting to true .
robots933456 in logs
You may see the following message in the container logs:
You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if
the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it
lets App Service know that the container is healthy and ready to respond to requests.
Next steps
Tutorial: PHP app with MySQL
App Service Linux FAQ
Or, see additional resources:
Environment variables and app settings reference
Configure a Linux Python app for Azure App
Service
5/18/2022 • 21 minutes to read • Edit Online
This article describes how Azure App Service runs Python apps, how you can migrate existing apps to Azure,
and how you can customize the behavior of App Service when needed. Python apps must be deployed with all
the required pip modules.
The App Service deployment engine automatically activates a virtual environment and runs
pip install -r requirements.txt for you when you deploy a Git repository, or a zip package with build
automation enabled.
This guide provides key concepts and instructions for Python developers who use a built-in Linux container in
App Service. If you've never used Azure App Service, first follow the Python quickstart and Python with
PostgreSQL tutorial.
You can use either the Azure portal or the Azure CLI for configuration:
Azure por tal , use the app's Settings > Configuration page as described on Configure an App Service
app in the Azure portal.
Azure CLI : you have two options.
Run commands in the Azure Cloud Shell.
Run commands locally by installing the latest version of the Azure CLI, then sign in to Azure using az
login.
NOTE
Linux is currently the recommended option for running Python apps in App Service. For information on the Windows
option, see Python on the Windows flavor of App Service.
Replace <resource-group-name> and <app-name> with the names appropriate for your web app.
Set the Python version with az webapp config set
You can run an unsupported version of Python by building your own container image instead. For more
information, see use a custom Docker image.
2. Run pip install -r requirements.txt . The requirements.txt file must be present in the project's root
folder. Otherwise, the build process reports the error: "Could not find setup.py or requirements.txt; Not
running pip install."
3. If manage.py is found in the root of the repository (indicating a Django app), run manage.py collectstatic.
However, if the DISABLE_COLLECTSTATIC setting is true , this step is skipped.
4. Run custom post-build script if specified by the POST_BUILD_COMMAND setting. (Again, the script can run
other Python and Node.js scripts, pip and npm commands, and Node-based tools.)
By default, the PRE_BUILD_COMMAND , POST_BUILD_COMMAND , and DISABLE_COLLECTSTATIC settings are empty.
To disable running collectstatic when building Django apps, set the DISABLE_COLLECTSTATIC setting to true.
To run pre-build commands, set the PRE_BUILD_COMMAND setting to contain either a command, such as
echo Pre-build command , or a path to a script file relative to your project root, such as
scripts/prebuild.sh . All commands must use relative paths to the project root folder.
To run post-build commands, set the POST_BUILD_COMMAND setting to contain either a command, such as
echo Post-build command , or a path to a script file relative to your project root, such as
scripts/postbuild.sh . All commands must use relative paths to the project root folder.
For additional settings that customize build automation, see Oryx configuration.
To access the build and deployment logs, see Access deployment logs.
For more information on how App Service runs and builds Python apps in Linux, see How Oryx detects and
builds Python apps.
NOTE
The PRE_BUILD_SCRIPT_PATH and POST_BUILD_SCRIPT_PATH settings are identical to PRE_BUILD_COMMAND and
POST_BUILD_COMMAND and are supported for legacy purposes.
A setting named SCM_DO_BUILD_DURING_DEPLOYMENT , if it contains true or 1, triggers an Oryx build happens during
deployment. The setting is true when deploying using git, the Azure CLI command az webapp up , and Visual Studio
Code.
NOTE
Always use relative paths in all pre- and post-build scripts because the build container in which Oryx runs is different from
the runtime container in which the app runs. Never rely on the exact placement of your app project folder within the
container (for example, that it's placed under site/wwwroot).
DJANGO_STATIC_URL and DJANGO_STATIC_ROOT can be changed as necessary for your local and cloud
environments. For example, if the build process for your static files places them in a folder named
django-static , then you can set DJANGO_STATIC_URL to /django-static/ to avoid using the default.
2. If you have a pre-build script that generates static files in a different folder, include that folder in the
Django STATICFILES_DIRS variable so that Django's collectstatic process finds them. For example, if
you run yarn build in your front-end folder, and yarn generates a build/static folder containing static
files, then include that folder as follows:
FRONTEND_DIR = "path-to-frontend-folder"
STATICFILES_DIRS = [os.path.join(FRONTEND_DIR, 'build', 'static')]
Here, FRONTEND_DIR , to build a path to where a build tool like yarn is run. You can again use an
environment variable and App Setting as desired.
3. Add whitenoise to your requirements.txt file. Whitenoise (whitenoise.evans.io) is a Python package that
makes it simple for a production Django app to serve it's own static files. Whitenoise specifically serves
those files that are found in the folder specified by the Django STATIC_ROOT variable.
4. In your settings.py file, add the following line for Whitenoise:
STATICFILES_STORAGE = ('whitenoise.storage.CompressedManifestStaticFilesStorage')
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
# Add whitenoise middleware after the security middleware
'whitenoise.middleware.WhiteNoiseMiddleware',
# Other values follow
]
INSTALLED_APPS = [
"whitenoise.runserver_nostatic",
# Other values follow
]
Container characteristics
When deployed to App Service, Python apps run within a Linux Docker container that's defined in the App
Service Python GitHub repository. You can find the image configurations inside the version-specific directories.
This container has the following characteristics:
Apps are run using the Gunicorn WSGI HTTP Server, using the additional arguments
--bind=0.0.0.0 --timeout 600 .
You can provide configuration settings for Gunicorn through a gunicorn.conf.py file in the project
root, as described on Gunicorn configuration overview (docs.gunicorn.org). You can alternately
customize the startup command.
To protect your web app from accidental or deliberate DDOS attacks, Gunicorn is run behind an
Nginx reverse proxy as described on Deploying Gunicorn (docs.gunicorn.org).
By default, the base container image includes only the Flask web framework, but the container supports
other frameworks that are WSGI-compliant and compatible with Python 3.6+, such as Django.
To install additional packages, such as Django, create a requirements.txt file in the root of your project
that specifies your direct dependencies. App Service then installs those dependencies automatically when
you deploy your project.
The requirements.txt file must be in the project root for dependencies to be installed. Otherwise, the build
process reports the error: "Could not find setup.py or requirements.txt; Not running pip install." If you
encounter this error, check the location of your requirements file.
App Service automatically defines an environment variable named WEBSITE_HOSTNAME with the web app's
URL, such as msdocs-hello-world.azurewebsites.net . It also defines WEBSITE_SITE_NAME with the name of
your app, such as msdocs-hello-world .
npm and Node.js are installed in the container so you can run Node-based build tools, such as yarn.
If you want more specific control over the startup command, use a custom startup command, replace <module>
with the name of folder that contains wsgi.py, and add a --chdir argument if that module is not in the project
root. For example, if your wsgi.py is located under knboard/backend/config from your project root, use the
arguments --chdir knboard/backend config.wsgi .
To enable production logging, add the --access-logfile and --error-logfile parameters as shown in the
examples for custom startup commands.
Flask app
For Flask, App Service looks for a file named application.py or app.py and starts Gunicorn as follows:
# If application.py
gunicorn --bind=0.0.0.0 --timeout 600 application:app
# If app.py
gunicorn --bind=0.0.0.0 --timeout 600 app:app
If your main app module is contained in a different file, use a different name for the app object, or you want to
provide additional arguments to Gunicorn, use a custom startup command.
Default behavior
If the App Service doesn't find a custom command, a Django app, or a Flask app, then it runs a default read-only
app, located in the opt/defaultsite folder and shown in the following image.
If you deployed code and still see the default app, see Troubleshooting - App doesn't appear.
Again, if you expect to see a deployed app instead of the default app, see Troubleshooting - App doesn't appear.
Replace <custom-command> with either the full text of your startup command or the name of your startup
command file.
App Service ignores any errors that occur when processing a custom startup command or file, then continues
its startup process by looking for Django and Flask apps. If you don't see the behavior you expect, check that
your startup command or file is error-free and that a startup command file is deployed to App Service along
with your app code. You can also check the Diagnostic logs for additional information. Also check the app's
Diagnose and solve problems page on the Azure portal.
Example startup commands
Added Gunicorn arguments : The following example adds the --workers=4 to a Gunicorn command
line for starting a Django app:
# <module-path> is the relative path to the folder that contains the module
# that contains wsgi.py; <module> is the name of the folder containing wsgi.py.
gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi
# '-' for the log files means stdout for --access-logfile and stderr for --error-logfile.
gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi --access-
logfile '-' --error-logfile '-'
If your main module is in a subfolder, such as website , specify that folder with the --chdir argument:
Use a non-Gunicorn ser ver : To use a different web server, such as aiohttp, use the appropriate
command as the startup command or in the startup command file:
db_server = os.environ['DATABASE_SERVER']
Popular web frameworks let you access the X-Forwarded-* information in your standard app pattern. In
CodeIgniter, the is_https() checks the value of X_FORWARDED_PROTO by default.
Replace <app-name> and <resource-group-name> with the names appropriate for your web app.
Once container logging is turned on, run the following command to see the log stream:
https://<app-name>.scm.azurewebsites.net/webssh/host
If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. Once
authenticated, you see an in-browser shell, where you can run commands inside your container.
NOTE
Any changes you make outside the /home directory are stored in the container itself and don't persist beyond an app
restart.
To open a remote SSH session from your local machine, see Open SSH session from remote shell.
When you're successfully connected to the SSH session, you should see the message "SSH CONNECTION
ESTABLISHED" at the bottom of the window. If you see errors such as "SSH_CONNECTION_CLOSED" or a
message that the container is restarting, an error may be preventing the app container from starting. See
Troubleshooting for steps to investigate possible issues.
Troubleshooting
In general, the first step in troubleshooting is to use App Service Diagnostics:
1. On the Azure portal for your web app, select Diagnose and solve problems from the left menu.
2. Select Availability and performance .
3. Examine the information in the Application Logs , Container crash , and Container Issues options, where
the most common issues will appear.
Next, examine both the deployment logs and the app logs for any error messages. These logs often identify
specific issues that can prevent app deployment or app startup. For example, the build can fail if your
requirements.txt file has the wrong filename or isn't present in your project root folder.
The following sections provide additional guidance for specific issues.
App doesn't appear - default app shows
App doesn't appear - "service unavailable" message
Could not find setup.py or requirements.txt
ModuleNotFoundError on startup
Database is locked
Passwords don't appear in SSH session when typed
Commands in the SSH session appear to be cut off
Static assets don't appear in a Django app
Fatal SSL Connection is Required
App doesn't appear
You see the default app after deploying your own app code. The default app appears because you
either haven't deployed your app code to App Service, or App Service failed to find your app code and
ran the default app instead.
Restart the App Service, wait 15-20 seconds, and check the app again.
Be sure you're using App Service for Linux rather than a Windows-based instance. From the Azure
CLI, run the command
az webapp show --resource-group <resource-group-name> --name <app-name> --query kind , replacing
<resource-group-name> and <app-name> accordingly. You should see app,linux as output;
otherwise, recreate the App Service and choose Linux.
Use SSH to connect directly to the App Service container and verify that your files exist under
site/wwwroot. If your files don't exist, use the following steps:
1. Create an app setting named SCM_DO_BUILD_DURING_DEPLOYMENT with the value of 1, redeploy
your code, wait a few minutes, then try to access the app again. For more information on
creating app settings, see Configure an App Service app in the Azure portal.
2. Review your deployment process, check the deployment logs, correct any errors, and redeploy
the app.
If your files exist, then App Service wasn't able to identify your specific startup file. Check that your
app is structured as App Service expects for Django or Flask, or use a custom startup command.
You see the message "Ser vice Unavailable" in the browser. The browser has timed out waiting for
a response from App Service, which indicates that App Service started the Gunicorn server, but the app
itself did not start. This condition could indicate that the Gunicorn arguments are incorrect, or that there's
an error in the app code.
Refresh the browser, especially if you're using the lowest pricing tiers in your App Service Plan. The
app may take longer to start up when using free tiers, for example, and becomes responsive after
you refresh the browser.
Check that your app is structured as App Service expects for Django or Flask, or use a custom
startup command.
Examine the app log stream for any error messages. The logs will show any errors in the app code.
Could not find setup.py or requirements.txt
The log stream shows "Could not find setup.py or requirements.txt; Not running pip install." :
The Oryx build process failed to find your requirements.txt file.
Connect to the web app's container via SSH and verify that requirements.txt is named correctly and
exists directly under site/wwwroot. If it doesn't exist, make site the file exists in your repository and is
included in your deployment. If it exists in a separate folder, move it to the root.
ModuleNotFoundError when app starts
If you see an error like ModuleNotFoundError: No module named 'example' , this means that Python could not find
one or more of your modules when the application started. This most often occurs if you deploy your virtual
environment with your code. Virtual environments are not portable, so a virtual environment should not be
deployed with your application code. Instead, let Oryx create a virtual environment and install your packages on
the web app by creating an app setting, SCM_DO_BUILD_DURING_DEPLOYMENT , and setting it to 1 . This will force Oryx
to install your packages whenever you deploy to App Service. For more information, please see this article on
virtual environment portability.
Database is locked
When attempting to run database migrations with a Django app, you may see "sqlite3. OperationalError:
database is locked." The error indicates that your application is using a SQLite database for which Django is
configured by default, rather than using a cloud database such as PostgreSQL for Azure.
Check the DATABASES variable in the app's settings.py file to ensure that your app is using a cloud database
instead of SQLite.
If you're encountering this error with the sample in Tutorial: Deploy a Django web app with PostgreSQL, check
that you completed the steps in Configure environment variables to connect the database.
Other issues
Passwords don't appear in the SSH session when typed : For security reasons, the SSH session
keeps your password hidden as you type. The characters are being recorded, however, so type your
password as usual and press Enter when done.
Commands in the SSH session appear to be cut off : The editor may not be word-wrapping
commands, but they should still run correctly.
Static assets don't appear in a Django app : Ensure that you have enabled the whitenoise module
You see the message, "Fatal SSL Connection is Required" : Check any usernames and passwords
used to access resources (such as databases) from within the app.
More resources
Tutorial: Python app with PostgreSQL
Tutorial: Deploy from private container repository
App Service Linux FAQ
Environment variables and app settings reference
Configure a Java app for Azure App Service
5/18/2022 • 36 minutes to read • Edit Online
Azure App Service lets Java developers to quickly build, deploy, and scale their Java SE, Tomcat, and JBoss EAP
web applications on a fully managed service. Deploy applications with Maven plugins, from the command line,
or in editors like IntelliJ, Eclipse, or Visual Studio Code.
This guide provides key concepts and instructions for Java developers using App Service. If you've never used
Azure App Service, you should read through the Java quickstart first. General questions about using App Service
that aren't specific to Java development are answered in the App Service FAQ.
To show all supported Java versions, run the following command in the Cloud Shell:
To show the current Java version, run the following command in the Cloud Shell:
To show all supported Java versions, run the following command in the Cloud Shell:
mvn com.microsoft.azure:azure-webapp-maven-plugin:2.2.0:config
This command adds a azure-webapp-maven-plugin plugin and related configuration by prompting you to select
an existing Azure Web App or create a new one. Then you can deploy your Java app to Azure using the following
command:
Gradle
1. Setup the Gradle Plugin for Azure Web Apps by adding the plugin to your build.gradle :
plugins {
id "com.microsoft.azure.azurewebapp" version "1.2.0"
}
2. Configure your Web App details, corresponding Azure resources will be created if not exist. Here is a
sample configuration, for details, refer to this document.
azurewebapp {
subscription = '<your subscription id>'
resourceGroup = '<your resource group>'
appName = '<your app name>'
pricingTier = '<price tier like 'P1v2'>'
region = '<region like 'westus'>'
runtime {
os = 'Linux'
webContainer = 'Tomcat 9.0' // or 'Java SE' if you want to run an executable jar
javaVersion = 'Java 8'
}
appSettings {
<key> = <value>
}
auth {
type = 'azure_cli' // support azure_cli, oauth2, device_code and service_principal
}
}
IDEs
Azure provides seamless Java App Service development experience in popular Java IDEs, including:
VS Code: Java Web Apps with Visual Studio Code
IntelliJ IDEA:Create a Hello World web app for Azure App Service using IntelliJ
Eclipse:Create a Hello World web app for Azure App Service using Eclipse
Kudu API
Java SE
To deploy .jar files to Java SE, use the /api/publish/ endpoint of the Kudu site. For more information on this
API, see this documentation.
NOTE
Your .jar application must be named app.jar for App Service to identify and run your application. The Maven Plugin
(mentioned above) will automatically rename your application for you during deployment. If you do not wish to rename
your JAR to app.jar, you can upload a shell script with the command to run your .jar app. Paste the absolute path to this
script in the Startup File textbox in the Configuration section of the portal. The startup script does not run from the
directory into which it is placed. Therefore, always use absolute paths to reference files in your startup script (for example:
java -jar /home/myapp/myapp.jar ).
Tomcat
To deploy .war files to Tomcat, use the /api/wardeploy/ endpoint to POST your archive file. For more
information on this API, see this documentation.
JBoss EAP
To deploy .war files to JBoss, use the /api/wardeploy/ endpoint to POST your archive file. For more information
on this API, see this documentation.
To deploy .ear files, use FTP. Your .ear application will be deployed to the context root defined in your
application's configuration. For example, if the context root of your app is <context-root>myapp</context-root> ,
then you can browse the site at the /myapp path: http://my-app-name.azurewebsites.net/myapp . If you want you
web app to be served in the root path, ensure that your app sets the context root to the root path:
<context-root>/</context-root> . For more information, see Setting the context root of a web application.
Do not deploy your .war or .jar using FTP. The FTP tool is designed to upload startup scripts, dependencies, or
other runtime files. It is not the optimal choice for deploying web apps.
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
NOTE
You can also inspect the log files from the browser at https://<app-name>.scm.azurewebsites.net/api/logs/docker .
Replace <app-name> and <resource-group-name> with the names appropriate for your web app.
Once container logging is turned on, run the following command to see the log stream:
https://<app-name>.scm.azurewebsites.net/webssh/host
If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. Once
authenticated, you see an in-browser shell, where you can run commands inside your container.
NOTE
Any changes you make outside the /home directory are stored in the container itself and don't persist beyond an app
restart.
To open a remote SSH session from your local machine, see Open SSH session from remote shell.
Troubleshooting tools
The built-in Java images are based on the Alpine Linux operating system. Use the apk package manager to
install any troubleshooting tools or commands.
Flight Recorder
All Java runtimes on App Service using the Azul JVMs come with the Zulu Flight Recorder. You can use this to
record JVM, system, and application events and troubleshoot problems in your Java applications.
Timed Recording
To take a timed recording, you'll need the PID (Process ID) of the Java application. To find the PID, open a
browser to your web app's SCM site at https://<your-site-name>.scm.azurewebsites.net/ProcessExplorer/ . This
page shows the running processes in your web app. Find the process named "java" in the table and copy the
corresponding PID (Process ID).
Next, open the Debug Console in the top toolbar of the SCM site and run the following command. Replace
<pid> with the process ID you copied earlier. This command will start a 30-second profiler recording of your
Java application and generate a file named timed_recording_example.jfr in the D:\home directory.
SSH into your App Service and run the jcmd command to see a list of all the Java processes running. In
addition to jcmd itself, you should see your Java application running with a process ID number (pid).
078990bbcd11:/home# jcmd
Picked up JAVA_TOOL_OPTIONS: -Djava.net.preferIPv4Stack=true
147 sun.tools.jcmd.JCmd
116 /home/site/wwwroot/app.jar
Execute the command below to start a 30-second recording of the JVM. This will profile the JVM and create a
JFR file named jfr_example.jfr in the home directory. (Replace 116 with the pid of your Java app.)
During the 30-second interval, you can validate the recording is taking place by running jcmd 116 JFR.check .
This will show all recordings for the given Java process.
Continuous Recording
You can use Zulu Flight Recorder to continuously profile your Java application with minimal impact on runtime
performance. To do so, run the following Azure CLI command to create an App Setting named JAVA_OPTS with
the necessary configuration. The contents of the JAVA_OPTS App Setting are passed to the java command
when your app is started.
Once the recording has started, you can dump the current recording data at any time using the JFR.dump
command.
<appSettings>
<property>
<name>JAVA_OPTS</name>
<value>-Xms512m -Xmx1204m</value>
</property>
</appSettings>
NOTE
You do not need to create a web.config file when using Tomcat on Windows App Service.
Developers running a single application with one deployment slot in their App Service plan can use the
following options:
B1 and S1 instances: -Xms1024m -Xmx1024m
B2 and S2 instances: -Xms3072m -Xmx3072m
B3 and S3 instances: -Xms6144m -Xmx6144m
P1v2 instances: -Xms3072m -Xmx3072m
P2v2 instances: -Xms6144m -Xmx6144m
P3v2 instances: -Xms12800m -Xmx12800m
P1v3 instances: -Xms6656m -Xmx6656m
P2v3 instances: -Xms14848m -Xmx14848m
P3v3 instances: -Xms30720m -Xmx30720m
I1 instances: -Xms3072m -Xmx3072m
I2 instances: -Xms6144m -Xmx6144m
I3 instances: -Xms12800m -Xmx12800m
I1v2 instances: -Xms6656m -Xmx6656m
I2v2 instances: -Xms14848m -Xmx14848m
I3v2 instances: -Xms30720m -Xmx30720m
When tuning application heap settings, review your App Service plan details and take into account multiple
applications and deployment slot needs to find the optimal allocation of memory.
Turn on web sockets
Turn on support for web sockets in the Azure portal in the Application settings for the application. You'll need
to restart the application for the setting to take effect.
Turn on web socket support using the Azure CLI with the following command:
<appSettings>
<property>
<name>JAVA_OPTS</name>
<value>-Dfile.encoding=UTF-8</value>
</property>
</appSettings>
Secure applications
Java applications running in App Service have the same set of security best practices as other applications.
Authenticate users (Easy Auth)
Set up app authentication in the Azure portal with the Authentication and Authorization option. From there,
you can enable authentication using Azure Active Directory or social logins like Facebook, Google, or GitHub.
Azure portal configuration only works when configuring a single authentication provider. For more information,
see Configure your App Service app to use Azure Active Directory login and the related articles for other
identity providers. If you need to enable multiple sign-in providers, follow the instructions in the customize sign-
ins and sign-outs article.
Java SE
Spring Boot developers can use the Azure Active Directory Spring Boot starter to secure applications using
familiar Spring Security annotations and APIs. Be sure to increase the maximum header size in your
application.properties file. We suggest a value of 16384 .
Tomcat
Your Tomcat application can access the user's claims directly from the servlet by casting the Principal object to a
Map object. The Map object will map each claim type to a collection of the claims for that type. In the code
below, request is an instance of HttpServletRequest .
Now you can inspect the Map object for any specific claim. For example, the following code snippet iterates
through all the claim types and prints the contents of each collection.
To sign out users, use the /.auth/ext/logout path. To perform other actions, see the documentation on
Customize sign-ins and sign-outs. There is also official documentation on the Tomcat HttpServletRequest
interface and its methods. The following servlet methods are also hydrated based on your App Service
configuration:
To disable this feature, create an Application Setting named WEBSITE_AUTH_SKIP_PRINCIPAL with a value of 1 . To
disable all servlet filters added by App Service, create a setting named WEBSITE_SKIP_FILTERS with a value of 1 .
Configure TLS/SSL
Follow the instructions in the Secure a custom DNS name with an TLS/SSL binding in Azure App Service to
upload an existing TLS/SSL certificate and bind it to your application's domain name. By default your application
will still allow HTTP connections-follow the specific steps in the tutorial to enforce TLS/SSL.
Use KeyVault References
Azure KeyVault provides centralized secret management with access policies and audit history. You can store
secrets (such as passwords or connection strings) in KeyVault and access these secrets in your application
through environment variables.
First, follow the instructions for granting your app access to Key Vault and making a KeyVault reference to your
secret in an Application Setting. You can validate that the reference resolves to the secret by printing the
environment variable while remotely accessing the App Service terminal.
To inject these secrets in your Spring or Tomcat configuration file, use environment variable injection syntax (
${MY_ENV_VAR} ). For Spring configuration files, see this documentation on externalized configurations.
2. Create an Application Insights resource using the CLI command below. Replace the placeholders with
your desired resource name and group.
Note the values for connectionString and instrumentationKey , you will need these values in the next
step.
3. Set the instrumentation key, connection string, and monitoring agent version as app settings on the web
app. Replace <instrumentationKey> and <connectionString> with the values from the previous step.
3. Set the instrumentation key, connection string, and monitoring agent version as app settings on the web
app. Replace <instrumentationKey> and <connectionString> with the values from the previous step.
If you already have an environment variable for JAVA_OPTS or CATALINA_OPTS , append the -javaagent:/...
option to the end of the current value.
Configure AppDynamics
1. Create an AppDynamics account at AppDynamics.com
2. Download the Java agent from the AppDynamics website, the file name will be similar to
AppServerAgent-x.x.x.xxxxx.zip
3. Use the Kudu console to create a new directory /home/site/wwwroot/apm.
4. Upload the Java agent files into a directory under /home/site/wwwroot/apm. The files for your agent
should be in /home/site/wwwroot/apm/appdynamics.
5. In the Azure portal, browse to your application in App Service and create a new Application Setting.
For Java SE apps, create an environment variable named JAVA_OPTS with the value
-javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=
<app-name>
where <app-name> is your App Service name.
For Tomcat apps, create an environment variable named CATALINA_OPTS with the value
-javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=
<app-name>
where <app-name> is your App Service name.
NOTE
If you already have an environment variable for JAVA_OPTS or CATALINA_OPTS , append the -javaagent:/... option
to the end of the current value.
2. In your application.properties file, reference this connection string with the environment variable name.
For our example, we would use the following.
app.datasource.url=${CUSTOMCONNSTR_exampledb}
See the Spring Boot documentation on data access and externalized configurations for more information on this
topic.
Tomcat
These instructions apply to all database connections. You will need to fill placeholders with your chosen
database's driver class name and JAR file. Provided is a table with class names and driver downloads for
common databases.
To configure Tomcat to use Java Database Connectivity (JDBC) or the Java Persistence API (JPA), first customize
the CATALINA_OPTS environment variable that is read in by Tomcat at start-up. Set these values through an app
setting in the App Service Maven plugin:
<appSettings>
<property>
<name>CATALINA_OPTS</name>
<value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
</property>
</appSettings>
Or set the environment variables in the Configuration > Application Settings page in the Azure portal.
Next, determine if the data source should be available to one application or to all applications running on the
Tomcat servlet.
Application-level data sources
1. Create a context.xml file in the META-INF/ directory of your project. Create the META-INF/ directory if it
does not exist.
2. In context.xml, add a Context element to link the data source to a JNDI address. Replace the
driverClassName placeholder with your driver's class name from the table above.
<Context>
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${dbuser}"
driverClassName="<insert your driver class name>"
username="${dbpassword}"
password="${connURL}"
/>
</Context>
3. Update your application's web.xml to use the data source in your application.
<resource-env-ref>
<resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
<resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
</resource-env-ref>
You can use a startup script to perform actions before a web app starts. The startup script for customizing
Tomcat needs to complete the following steps:
1. Check whether Tomcat was already copied and configured locally. If it was, the startup script can end here.
2. Copy Tomcat locally.
3. Make the required configuration changes.
4. Indicate that configuration was successfully completed.
For Windows sites, create a file named startup.cmd or startup.ps1 in the wwwroot directory. This will
automatically be executed before the Tomcat server starts.
Here's a PowerShell script that completes these steps:
# Check for marker file indicating that config has already been done
if(Test-Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker"){
return 0
}
T r a n sfo r m s
A common use case for customizing a Tomcat version is to modify the server.xml , context.xml , or web.xml
Tomcat configuration files. App Service already modifies these files to provide platform features. To continue to
use these features, it's important to preserve the content of these files when you make changes to them. To
accomplish this, we recommend that you use an XSL transformation (XSLT). Use an XSL transform to make
changes to the XML files while preserving the original contents of the file.
E x a mp l e X SL T f i l e
This example transform adds a new connector node to server.xml . Note the Identity Transform, which
preserves the original contents of the file.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- Identity transform: this ensures that the original contents of the file are included in the new
file -->
<!-- Ensure that your transform files include this block -->
<xsl:template match="@* | node()" name="Copy">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- Add the new connector after the last existing Connnector if there is one -->
<xsl:template match="Connector[last()]" mode="insertConnector">
<xsl:call-template name="Copy" />
<!-- ... or before the first Engine if there is no existing Connector -->
<xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
mode="insertConnector">
<xsl:call-template name="AddConnector" />
<xsl:template name="AddConnector">
<!-- Add new line -->
<xsl:text>
</xsl:text>
<!-- This is the new connector -->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystroreFile="${{user.home}}/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS" />
</xsl:template>
</xsl:stylesheet>
F u n c t i o n f o r X SL t ra n s f o rm
PowerShell has built-in tools for transforming XML files by using XSL transforms. The following script is an
example function that you can use in startup.ps1 to perform the transform:
function TransformXML{
param ($xml, $xsl, $output)
Try
{
$xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
$XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
$xslt_settings.EnableScript = 1;
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-Host 'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
return 0
}
return 1
}
A p p se t t i n g s
The platform also needs to know where your custom version of Tomcat is installed. You can set the installation's
location in the CATALINA_BASE app setting.
You can use the Azure CLI to change this setting:
Or, you can manually change the setting in the Azure portal:
1. Go to Settings > Configuration > Application settings .
2. Select New Application Setting .
3. Use these values to create the setting:
a. Name : CATALINA_BASE
b. Value : "%LOCAL_EXPANDED%\tomcat"
Ex a m p l e st a r t u p .p s1
The following example script copies a custom Tomcat to a local folder, performs an XSL transform, and indicates
that the transform was successful:
# Locations of xml and xsl files
$target_xml="$Env:LOCAL_EXPANDED\tomcat\conf\server.xml"
$target_xsl="$Env:HOME\site\server.xsl"
Try
{
$xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
$XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
$xslt_settings.EnableScript = 1;
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
echo 'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
return 0
}
return 1
}
# Check for marker file indicating that config has already been done
if(Test-Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker"){
return 0
}
md -Path "$Env:LOCAL_EXPANDED\tomcat"
Finalize configuration
Finally, we will place the driver JARs in the Tomcat classpath and restart your App Service. Ensure that the JDBC
driver files are available to the Tomcat classloader by placing them in the /home/tomcat/lib directory. (Create
this directory if it does not already exist.) To upload these files to your App Service instance, perform the
following steps:
1. In the Cloud Shell, install the webapp extension:
2. Run the following CLI command to create an SSH tunnel from your local system to App Service:
3. Connect to the local tunneling port with your SFTP client and upload the files to the /home/tomcat/lib
folder.
Alternatively, you can use an FTP client to upload the JDBC driver. Follow these instructions for getting your FTP
credentials.
Tomcat
These instructions apply to all database connections. You will need to fill placeholders with your chosen
database's driver class name and JAR file. Provided is a table with class names and driver downloads for
common databases.
To configure Tomcat to use Java Database Connectivity (JDBC) or the Java Persistence API (JPA), first customize
the CATALINA_OPTS environment variable that is read in by Tomcat at start-up. Set these values through an app
setting in the App Service Maven plugin:
<appSettings>
<property>
<name>CATALINA_OPTS</name>
<value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
</property>
</appSettings>
Or set the environment variables in the Configuration > Application Settings page in the Azure portal.
Next, determine if the data source should be available to one application or to all applications running on the
Tomcat servlet.
Application-level data sources
1. Create a context.xml file in the META-INF/ directory of your project. Create the META-INF/ directory if it
does not exist.
2. In context.xml, add a Context element to link the data source to a JNDI address. Replace the
driverClassName placeholder with your driver's class name from the table above.
<Context>
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${dbuser}"
driverClassName="<insert your driver class name>"
username="${dbpassword}"
password="${connURL}"
/>
</Context>
3. Update your application's web.xml to use the data source in your application.
<resource-env-ref>
<resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
<resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
</resource-env-ref>
An example xsl file is provided below. The example xsl file adds a new connector node to the Tomcat server.xml.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- Add the new connector after the last existing Connnector if there is one -->
<xsl:template match="Connector[last()]" mode="insertConnector">
<xsl:call-template name="Copy" />
<!-- ... or before the first Engine if there is no existing Connector -->
<xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
mode="insertConnector">
<xsl:call-template name="AddConnector" />
<xsl:template name="AddConnector">
<!-- Add new line -->
<xsl:text>
</xsl:text>
<!-- This is the new connector -->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystroreFile="${{user.home}}/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS" />
</xsl:template>
</xsl:stylesheet>
Finalize configuration
Finally, place the driver JARs in the Tomcat classpath and restart your App Service.
1. Ensure that the JDBC driver files are available to the Tomcat classloader by placing them in the
/home/tomcat/lib directory. (Create this directory if it does not already exist.) To upload these files to your
App Service instance, perform the following steps:
a. In the Cloud Shell, install the webapp extension:
b. Run the following CLI command to create an SSH tunnel from your local system to App Service:
c. Connect to the local tunneling port with your SFTP client and upload the files to the /home/tomcat/lib
folder.
Alternatively, you can use an FTP client to upload the JDBC driver. Follow these instructions for getting
your FTP credentials.
2. If you created a server-level data source, restart the App Service Linux application. Tomcat will reset
CATALINA_BASE to /home/tomcat and use the updated configuration.
3. Put your JBoss CLI commands into a file named jboss-cli-commands.cli . The JBoss commands must add
the module and register it as a data source. The example below shows the JBoss CLI commands for
PostgreSQL.
#!/usr/bin/env bash
module add --name=org.postgres --resources=/home/site/deployments/tools/postgresql-42.2.12.jar --
module-xml=/home/site/deployments/tools/postgres-module.xml
/subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-
name="org.postgres",driver-class-name=org.postgresql.Driver,driver-xa-datasource-class-
name=org.postgresql.xa.PGXADataSource)
4. Create a startup script, startup_script.sh that calls the JBoss CLI commands. The example below shows
how to call your jboss-cli-commands.cli . Later you will configure App Service to run this script when the
container starts.
5. Using an FTP client of your choice, upload your JDBC driver, jboss-cli-commands.cli , startup_script.sh ,
and the module definition to /site/deployments/tools/ .
6. Configure your site to run startup_script.sh when the container starts. In the Azure portal, navigate to
Configuration > General Settings > Star tup Command . Set the startup command field to
/home/site/deployments/tools/startup_script.sh . Save your changes.
To confirm that the datasource was added to the JBoss server, SSH into your webapp and run
$JBOSS_HOME/bin/jboss-cli.sh --connect . Once you are connected to JBoss run the
/subsystem=datasources:read-resource to print a list of the data sources.
robots933456 in logs
You may see the following message in the container logs:
You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if
the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it
lets App Service know that the container is healthy and ready to respond to requests.
JBoss EAP
Clustering in JBoss EAP
App Service supports clustering for JBoss EAP versions 7.4.1 and greater. To enable clustering, your web app
must be integrated with a virtual network. When the web app is integrated with a virtual network, the web app
will restart and JBoss EAP will automatically startup with a clustered configuration. The JBoss EAP instances will
communicate over the subnet specified in the virtual network integration, using the ports shown in the
WEBSITES_PRIVATE_PORTS environment variable at runtime. You can disable clustering by creating an app setting
named WEBSITE_DISABLE_CLUSTERING with any value.
NOTE
If you are enabling your virtual network integration with an ARM template, you will need to manually set the property
vnetPrivatePorts to a value of 2 . If you enable virtual network integration from the CLI or Portal, this property will
be set for you automatically.
When clustering is enabled, the JBoss EAP instances use the FILE_PING JGroups discovery protocol to discover
new instances and persist the cluster information like the cluster members, their identifiers, and their IP
addresses. On App Service, these files are under /home/clusterinfo/ . The first EAP instance to start will obtain
read/write permissions on the cluster membership file. Other instances will read the file, find the primary node,
and coordinate with that node to be included in the cluster and added to the file.
JBoss EAP App Service Plans
JBoss EAP is only available on the Premium v3 and Isolated v2 App Service Plan types. Customers that created a
JBoss EAP site on a different tier during the public preview should scale up to Premium or Isolated hardware tier
to avoid unexpected behavior.
JAVA VERSIO N L IN UX W IN DO W S
Next steps
Visit the Azure for Java Developers center to find Azure quickstarts, tutorials, and Java reference documentation.
App Service Linux FAQ
Environment variables and app settings reference
Configure a Linux Ruby app for Azure App Service
5/18/2022 • 5 minutes to read • Edit Online
This article describes how Azure App Service runs Ruby apps in a Linux container, and how you can customize
the behavior of App Service when needed. Ruby apps must be deployed with all the required gems.
This guide provides key concepts and instructions for Ruby developers who use a built-in Linux container in App
Service. If you've never used Azure App Service, you should follow the Ruby quickstart and Ruby with
PostgreSQL tutorial first.
To show all supported Ruby versions, run the following command in the Cloud Shell:
You can run an unsupported version of Ruby by building your own container image instead. For more
information, see use a custom Docker image.
NOTE
If you see errors similar to the following during deployment time:
or
It means that the Ruby version configured in your project is different than the version that's installed in the container
you're running ( 2.3.3 in the example above). In the example above, check both Gemfile and .ruby-version and verify
that the Ruby version is not set, or is set to the version that's installed in the container you're running ( 2.3.3 in the
example above).
ENV['WEBSITE_SITE_NAME']
Customize deployment
When you deploy a Git repository, or a Zip package with build automation enabled, the deployment engine
(Kudu) automatically runs the following post-deployment steps by default:
1. Check if a Gemfile exists.
2. Run bundle clean .
3. Run bundle install --path "vendor/bundle" .
4. Run bundle package to package gems into vendor/cache folder.
Use --without flag
To run bundle install with the --without flag, set the BUNDLE_WITHOUT app setting to a comma-separated list of
groups. For example, the following command sets it to development,test .
If this setting is defined, then the deployment engine runs bundle install with --without $BUNDLE_WITHOUT .
Precompile assets
The post-deployment steps don't precompile assets by default. To turn on asset precompilation, set the
ASSETS_PRECOMPILE app setting to true . Then the command bundle exec rake --trace assets:precompile is run
at the end of the post-deployment steps. For example:
Customize start-up
By default, the Ruby container starts the Rails server in the following sequence (for more information, see the
start-up script):
1. Generate a secret_key_base value, if one doesn't exist already. This value is required for the app to run in
production mode.
2. Set the RAILS_ENV environment variable to production .
3. Delete any .pid file in the tmp/pids directory that's left by a previously running Rails server.
4. Check if all dependencies are installed. If not, try installing gems from the local vendor/cache directory.
5. Run rails server -e $RAILS_ENV .
However, this setting alone causes the Rails server to start in development mode, which accepts localhost
requests only and isn't accessible outside of the container. To accept remote client requests, set the
APP_COMMAND_LINE app setting to rails server -b 0.0.0.0 . This app setting lets you run a custom command in
the Ruby container. For example:
Possible values for --level are: Error , Warning , Info , and Verbose . Each subsequent level includes the
previous level. For example: Error includes only error messages, and Verbose includes all messages.
Once diagnostic logging is turned on, run the following command to see the log stream:
https://<app-name>.scm.azurewebsites.net/webssh/host
If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. Once
authenticated, you see an in-browser shell, where you can run commands inside your container.
NOTE
Any changes you make outside the /home directory are stored in the container itself and don't persist beyond an app
restart.
To open a remote SSH session from your local machine, see Open SSH session from remote shell.
robots933456 in logs
You may see the following message in the container logs:
2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415
"-" "-"
You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if
the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it
lets App Service know that the container is healthy and ready to respond to requests.
More resources
Tutorial: Rails app with PostgreSQL
App Service Linux FAQ
Environment variables and app settings reference
Configure a custom container for Azure App
Service
5/18/2022 • 18 minutes to read • Edit Online
This article shows you how to configure a custom container to run on Azure App Service.
This guide provides key concepts and instructions for containerization of Windows apps in App Service. If you've
never used Azure App Service, follow the custom container quickstart and tutorial first.
This guide provides key concepts and instructions for containerization of Linux apps in App Service. If you've
never used Azure App Service, follow the custom container quickstart and tutorial first. There's also a multi-
container app quickstart and tutorial.
For <username> and <password>, supply the login credentials for your private registry account.
Replace <app-name> with the name you used in the previous step. The output of the command (filtered by
the --query and --output arguments) is the service principal ID of the assigned identity, which you use
shortly.
2. Get the resource ID of your Azure Container Registry:
Replace <registry-name> with the name of your registry. The output of the command (filtered by the --
query and --output arguments) is the resource ID of the Azure Container Registry.
3. Grant the managed identity permission to access the container registry:
5. (Optional) If your app uses a user-assigned managed identity, make sure this is configured on the web
app and then set an additional acrUserManagedIdentityID property to specify its client ID:
az identity show --resource-group <group-name> --name <identity-name> --query clientId --output tsv
Replace the <identity-name> of your user-assigned managed identity and use the output <client-id> to
configure the user-assigned managed identity ID.
You are all set, and the web app will now use managed identity to pull from Azure Container Registry.
In PowerShell:
App Service currently allows your container to expose only one port for HTTP requests.
In PowerShell:
When your app runs, the App Service app settings are injected into the process as environment variables
automatically. You can verify container environment variables with the URL
https://<app-name>.scm.azurewebsites.net/Env) .
If your app uses images from a private registry or from Docker Hub, credentials for accessing the repository are
saved in environment variables: DOCKER_REGISTRY_SERVER_URL , DOCKER_REGISTRY_SERVER_USERNAME and
DOCKER_REGISTRY_SERVER_PASSWORD . Because of security risks, none of these reserved variable names are exposed
to the application.
For IIS or .NET Framework (4.0 or above) based containers, they're injected into System.ConfigurationManager as
.NET app settings and connection strings automatically by App Service. For all other language or framework,
they're provided as environment variables for the process, with one of the following corresponding prefixes:
APPSETTING_
SQLCONTR_
MYSQLCONTR_
SQLAZURECOSTR_
POSTGRESQLCONTR_
CUSTOMCONNSTR_
This method works both for single-container apps or multi-container apps, where the environment variables are
specified in the docker-compose.yml file.
In PowerShell:
NOTE
You can also configure your own persistent storage.
The new keys at each restart may reset ASP.NET forms authentication and view state, if your app depends on
them. To prevent the automatic regeneration of keys, set them manually as App Service app settings.
The debug console lets you execute interactive commands, such as starting PowerShell sessions, inspecting
registry keys, and navigate the entire container file system.
It functions separately from the graphical browser above it, which only shows the files in your shared
storage.
In a scaled-out app, the debug console is connected to one of the container instances. You can select a
different instance from the Instance dropdown in the top menu.
Any change you make to the container from within the console does not persist when your app is restarted
(except for changes in the shared storage), because it's not part of the Docker image. To persist your changes,
such as registry settings and software installation, make them part of the Dockerfile.
In PowerShell:
The value is defined in MB and must be less and equal to the total physical memory of the host. For example, in
an App Service plan with 8 GB RAM, the cumulative total of WEBSITE_MEMORY_LIMIT_MB for all the apps must not
exceed 8 GB. Information on how much memory is available for each pricing tier can be found in App Service
pricing, in the Premium v3 ser vice plan section.
az webapp config appsettings set --resource-group <group-name> --name <app-name> --slot staging --settings
WEBSITE_CPU_CORES_LIMIT=1
In PowerShell:
NOTE
Updating the app setting triggers automatic restart, causing minimal downtime. For a production app, consider swapping
it into a staging slot, change the app setting in the staging slot, and then swap it back into production.
Verify your adjusted number by going to the Kudu Console ( https://<app-name>.scm.azurewebsites.net ) and
typing in the following commands using PowerShell. Each command outputs a number.
The processors may be multicore or hyperthreading processors. Information on how many cores are available
for each pricing tier can be found in App Service pricing, in the Premium v3 ser vice plan section.
Customize health ping behavior
App Service considers a container to be successfully started when the container starts and responds to an HTTP
ping. The health ping request contains the header
User-Agent= "App Service Hyper-V Container Availability Check" . If the container starts but does not respond to
a ping after a certain amount of time, App Service logs an event in the Docker log, saying that the container
didn't start.
If your application is resource-intensive, the container might not respond to the HTTP ping in time. To control the
actions when HTTP pings fail, set the CONTAINER_AVAILABILITY_CHECK_MODE app setting. You can set it via the Cloud
Shell. In Bash:
In PowerShell:
VA L UE DESC RIP T IO N S
Repor tOnly The default value. Don't restart the container but report in
the Docker logs for the container after three consecutive
availability checks.
Enable SSH
SSH enables secure communication between a container and a client. In order for a custom container to support
SSH, you must add it into your Docker image itself.
TIP
All built-in Linux containers in App Service have added the SSH instructions in their image repositories. You can go
through the following instructions with the Node.js 10.14 repository to see how it's enabled there. The configuration in
the Node.js built-in image is slightly different, but the same in principle.
NOTE
This file configures OpenSSH and must include the following items:
Port must be set to 2222.
Ciphers must include at least one item in this list: aes128-cbc,3des-cbc,aes256-cbc .
MACs must include at least one item in this list: hmac-sha1,hmac-sha1-96 .
Add an ssh_setup script file to create the SSH keys using ssh-keygen to your repository.
#!/bin/sh
ssh-keygen -A
# Install OpenSSH and set the password for root to "Docker!". In this example, "apk add" is the
install instruction for an Alpine Linux-based image.
RUN apk add openssh \
&& echo "root:Docker!" | chpasswd
NOTE
The root password must be exactly Docker! as it is used by App Service to let you access the SSH session with
the container. This configuration doesn't allow external connections to the container. Port 2222 of the container is
accessible only within the bridge network of a private virtual network and is not accessible to an attacker on the
internet.
In the start-up script for your container, start the SSH server.
/usr/sbin/sshd
Replace <app-name> and <resource-group-name> with the names appropriate for your web app.
Once container logging is turned on, run the following command to see the log stream:
wordpress:
image: <image name:tag>
volumes:
- ${WEBAPP_STORAGE_HOME}/site/wwwroot:/var/www/html
- ${WEBAPP_STORAGE_HOME}/phpmyadmin:/var/www/phpmyadmin
- ${WEBAPP_STORAGE_HOME}/LogFiles:/var/log
Preview limitations
Multi-container is currently in preview. The following App Service platform features are not supported:
Authentication / Authorization
Managed Identities
CORS
VNET integration is not supported for Docker Compose scenarios
Docker Compose on Azure App Services currently has a limit of 4,000 characters at this time.
Docker Compose options
The following lists show supported and unsupported Docker Compose configuration options:
Supported options
command
entrypoint
environment
image
ports
restart
services
volumes
Unsupported options
build (not allowed)
depends_on (ignored)
networks (ignored)
secrets (ignored)
ports other than 80 and 8080 (ignored)
Syntax Limitations
the "version x.x" always needs to be the first yaml statement in the file
the ports section must use quoted numbers
the image > volume section must be quoted and cannot have a permissions definitions
the volumes section must not have an empty curly brace after the volume name
NOTE
Any other options not explicitly called out are ignored in Public Preview.
robots933456 in logs
You may see the following message in the container logs:
You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if
the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it
lets App Service know that the container is healthy and ready to respond to requests.
Next steps
Tutorial: Migrate custom software to Azure App Service using a custom container
Tutorial: Multi-container WordPress app
Or, see additional resources:
Environment variables and app settings reference
Load certificate in Windows/Linux containers
Mount Azure Storage as a local share in App
Service
5/18/2022 • 12 minutes to read • Edit Online
NOTE
Mounting Azure Storage as a local share for App Service on Windows code is currently in preview.
This guide shows how to mount Azure Storage Files as a network share in Windows code in App Service. Only
Azure Files Shares and Premium Files Shares are supported. The benefits of custom-mounted storage include:
Configure persistent storage for your App Service app and manage the storage separately.
Make static content like video and images readily available for your App Service app.
Write application log files or archive older application log to Azure File shares.
Share content across multiple apps or with other Azure services.
The following features are supported for Windows code:
Secured access to storage accounts with private endpoints and service endpoints (when VNET integration is
used).
Azure Files (read/write).
Up to five mount points per app.
Mount Azure Storage file shares using "/mounts/ <path-name> ".
This guide shows how to mount Azure Storage Files as a network share in a Windows container in App Service.
Only Azure Files Shares and Premium Files Shares are supported. The benefits of custom-mounted storage
include:
Configure persistent storage for your App Service app and manage the storage separately.
Make static content like video and images readily available for your App Service app.
Write application log files or archive older application log to Azure File shares.
Share content across multiple apps or with other Azure services.
Mount Azure Storage in a Windows container in a Standard tier or higher plan, including Isolated (App
Service environment v3).
The following features are supported for Windows containers:
Secured access to storage accounts with private endpoints and service endpoints (when VNET integration is
used).
Azure Files (read/write).
Up to five mount points per app.
Drive letter assignments ( C: to Z: ).
This guide shows how to mount Azure Storage as a network share in a built-in Linux container or a custom Linux
container in App Service. See the video how to mount Azure Storage as a local share. The benefits of custom-
mounted storage include:
Configure persistent storage for your App Service app and manage the storage separately.
Make static content like video and images readily available for your App Service app.
Write application log files or archive older application log to Azure File shares.
Share content across multiple apps or with other Azure services.
The following features are supported for Linux containers:
Secured access to storage accounts with service endpoints and private links (when VNET integration is used).
Azure Files (read/write).
Azure Blobs (read-only).
Up to five mount points per app.
Prerequisites
An existing Windows code app in App Service
Create Azure file share
Upload files to Azure File share
An existing Windows container app in App Service
Create Azure file share
Upload files to Azure File share
An existing App Service on Linux app.
An Azure Storage Account
An Azure file share and directory.
NOTE
Azure Storage is non-default storage for App Service and billed separately, not included with App Service.
Limitations
Storage firewall is supported only through private endpoints and service endpoints (when VNET integration
is used).
Azure blobs are not supported when configuring Azure storage mounts for Windows code apps deployed to
App Service.
FTP/FTPS access to mounted storage not supported (use Azure Storage Explorer).
Mapping /mounts , mounts/foo/bar , / , and /mounts/foo.bar/ to custom-mounted storage is not supported
(you can only use /mounts/pathname for mounting custom storage to your web app.)
Storage mounts cannot be used together with clone settings option during deployment slot creation.
Storage mounts are not backed up when you back up your app. Be sure to follow best practices to back up
the Azure Storage accounts.
Storage mounts are not supported for native Windows (non-containerized) apps.
Azure blobs are not supported.
Storage firewall is supported only through private endpoints and service endpoints (when VNET integration
is used).
FTP/FTPS access to mounted storage not supported (use Azure Storage Explorer).
Mapping [C-Z]:\ , [C-Z]:\home , / , and /home to custom-mounted storage is not supported.
Storage mounts cannot be used together with clone settings option during deployment slot creation.
Storage mounts are not backed up when you back up your app. Be sure to follow best practices to back up
the Azure Storage accounts.
NOTE
Ensure ports 80 and 445 are open when using Azure Files with VNET integration.
Storage firewall is supported only through service endpoints and private endpoints (when VNET integration
is used). Custom DNS support is currently unavailable when the mounted Azure Storage account uses a
private endpoint.
FTP/FTPS access to custom-mounted storage is not supported (use Azure Storage Explorer).
Azure CLI, Azure PowerShell, and Azure SDK support is in preview.
Mapping / or /home to custom-mounted storage is not supported.
Don't map the custom storage mount to /tmp or its subdirectories as this may cause timeout during app
startup.
Storage mounts cannot be used together with clone settings option during deployment slot creation.
Storage mounts are not backed up when you back up your app. Be sure to follow best practices to back up
the Azure Storage accounts.
NOTE
When VNET integration is used, ensure the following ports are open:
Azure Files: 80 and 445.
Azure Blobs: 80 and 443.
Configuration options Select Basic if the storage account is not using private
endpoints. Otherwise, select Advanced .
Access key (Advanced only) Access key for your storage account.
Mount path Directory inside your file/blob storage that you want to
mount. Only /mounts/pathname is supported.
Configuration options Select Basic if the storage account is not using private
endpoints. Otherwise, select Advanced .
Access key (Advanced only) Access key for your storage account.
Mount path Directory inside your file/blob storage that you want to
mount. Do not use a root directory ( [C-Z]:\ or / ) or
the home directory ( [C-Z]:\home , or /home ).
Configuration options Select Basic if the storage account is not using service
endpoints or private endpoints. Otherwise, select
Advanced .
Storage type Select the type based on the storage you want to
mount. Azure Blobs only supports read-only access.
Access key (Advanced only) Access key for your storage account.
NOTE
Adding, editing, or deleting a storage mount causes the app to be restarted.
df –h
3. Check if the storage share is mounted. If it's not present, there's an issue with mounting the storage share.
4. Check latency or general reachability of the storage mount with the following command:
tcpping Storageaccount.file.core.windows.net
Best practices
To avoid potential issues related to latency, place the app and the Azure Storage account in the same
Azure region. Note, however, if the app and Azure Storage account are in same Azure region, and if you
grant access from App Service IP addresses in the Azure Storage firewall configuration, then these IP
restrictions are not honored.
In the Azure Storage account, avoid regenerating the access key that's used to mount the storage in the
app. The storage account contains two different keys. Use a stepwise approach to ensure that the storage
mount remains available to the app during key regeneration. For example, assuming that you used key1
to configure storage mount in your app:
1. Regenerate key2 .
2. In the storage mount configuration, update the access the key to use the regenerated key2 .
3. Regenerate key1 .
If you delete an Azure Storage account, container, or share, remove the corresponding storage mount
configuration in the app to avoid possible error scenarios.
The mounted Azure Storage account can be either Standard or Premium performance tier. Based on the
app capacity and throughput requirements, choose the appropriate performance tier for the storage
account. See the scalability and performance targets for Files.
If your app scales to multiple instances, all the instances connect to the same mounted Azure Storage
account. To avoid performance bottlenecks and throughput issues, choose the appropriate performance
tier for the storage account.
It's not recommended to use storage mounts for local databases (such as SQLite) or for any other
applications and components that rely on file handles and locks.
If you initiate a storage failover and the storage account is mounted to the app, the mount will fail to
connect until you either restart the app or remove and add the Azure Storage mount.
When using Azure Storage private endpoints with the app, you need to enable the Route All setting.
When VNET integration is used, ensure app setting, WEBSITE_CONTENTOVERVNET is set to 1 and the
following ports are open:
Azure Files: 80 and 445
The mounted Azure Storage account can be either Standard or Premium performance tier. Based on the
app capacity and throughput requirements, choose the appropriate performance tier for the storage
account. See the scalability and performance targets for Files
To avoid potential issues related to latency, place the app and the Azure Storage account in the same
Azure region. Note, however, if the app and Azure Storage account are in same Azure region, and if you
grant access from App Service IP addresses in the Azure Storage firewall configuration, then these IP
restrictions are not honored.
In the Azure Storage account, avoid regenerating the access key that's used to mount the storage in the
app. The storage account contains two different keys. Use a stepwise approach to ensure that the storage
mount remains available to the app during key regeneration. For example, assuming that you used key1
to configure storage mount in your app:
1. Regenerate key2 .
2. In the storage mount configuration, update the access the key to use the regenerated key2 .
3. Regenerate key1 .
If you delete an Azure Storage account, container, or share, remove the corresponding storage mount
configuration in the app to avoid possible error scenarios.
The mounted Azure Storage account can be either Standard or Premium performance tier. Based on the
app capacity and throughput requirements, choose the appropriate performance tier for the storage
account. See the scalability and performance targets for Files.
If your app scales to multiple instances, all the instances connect to the same mounted Azure Storage
account. To avoid performance bottlenecks and throughput issues, choose the appropriate performance
tier for the storage account.
It's not recommended to use storage mounts for local databases (such as SQLite) or for any other
applications and components that rely on file handles and locks.
If you initiate a storage failover and the storage account is mounted to the app, the mount will fail to
connect until you either restart the app or remove and add the Azure Storage mount.
When using Azure Storage private endpoints with the app, you need to enable the Route All setting.
NOTE
In App Service environment V3, the Route All setting is disabled by default and must be explicitly enabled.
To avoid potential issues related to latency, place the app and the Azure Storage account in the same
Azure region. Note, however, if the app and Azure Storage account are in same Azure region, and if you
grant access from App Service IP addresses in the Azure Storage firewall configuration, then these IP
restrictions are not honored.
The mount directory in the custom container should be empty. Any content stored at this path is deleted
when the Azure Storage is mounted (if you specify a directory under /home , for example). If you are
migrating files for an existing app, make a backup of the app and its content before you begin.
Mounting the storage to /home is not recommended because it may result in performance bottlenecks
for the app.
In the Azure Storage account, avoid regenerating the access key that's used to mount the storage in the
app. The storage account contains two different keys. Use a stepwise approach to ensure that the storage
mount remains available to the app during key regeneration. For example, assuming that you used key1
to configure storage mount in your app:
1. Regenerate key2 .
2. In the storage mount configuration, update the access the key to use the regenerated key2 .
3. Regenerate key1 .
If you delete an Azure Storage account, container, or share, remove the corresponding storage mount
configuration in the app to avoid possible error scenarios.
The mounted Azure Storage account can be either Standard or Premium performance tier. Based on the
app capacity and throughput requirements, choose the appropriate performance tier for the storage
account. See the scalability and performance targets that correspond to the storage type:
For Files
For Blobs
If your app scales to multiple instances, all the instances connect to the same mounted Azure Storage
account. To avoid performance bottlenecks and throughput issues, choose the appropriate performance
tier for the storage account.
It's not recommended to use storage mounts for local databases (such as SQLite) or for any other
applications and components that rely on file handles and locks.
When using Azure Storage private endpoints with the app, you need to enable the Route All setting.
If you initiate a storage failover and the storage account is mounted to the app, the mount will fail to
connect until you either restart the app or remove and add the Azure Storage mount.
Next steps
Migrate .NET apps to Azure App Service.
Migrate custom software to Azure App Service using a custom container.
Configure a custom container.
Video: How to mount Azure Storage as a local share.
Run your app in Azure App Service directly from a
ZIP package
5/18/2022 • 4 minutes to read • Edit Online
In Azure App Service, you can run your apps directly from a deployment ZIP package file. This article shows how
to enable this functionality in your app.
All other deployment methods in App Service have something in common: your files are deployed to
D:\home\site\wwwroot in your app (or /home/site/wwwroot for Linux apps). Since the same directory is used
by your app at runtime, it's possible for deployment to fail because of file lock conflicts, and for the app to
behave unpredictably because some of the files are not yet updated.
In contrast, when you run directly from a package, the files in the package are not copied to the wwwroot
directory. Instead, the ZIP package itself gets mounted directly as the read-only wwwroot directory. There are
several benefits to running directly from a package:
Eliminates file lock conflicts between deployment and runtime.
Ensures only full-deployed apps are running at any time.
Can be deployed to a production app (with restart).
Improves the performance of Azure Resource Manager deployments.
May reduce cold-start times, particularly for JavaScript functions with large npm package trees.
NOTE
Currently, only ZIP package files are supported.
In a local terminal window, navigate to the root directory of your app project.
This directory should contain the entry file to your web app, such as index.html, index.php, and app.js. It can also
contain package management files like project.json, composer.json, package.json, bower.json, and
requirements.txt.
Unless you want App Service to run deployment automation for you, run all the build tasks (for example, npm ,
bower , gulp , composer , and pip ) and make sure that you have all the files you need to run the app. This step
is required if you want to run your package directly.
Create a ZIP archive of everything in your project. For dotnet projects, this folder is the output folder of the
dotnet publish command. The following command uses the default tool in your terminal:
# Bash
zip -r <file-name>.zip .
# PowerShell
Compress-Archive -Path * -DestinationPath <file-name>.zip
WEBSITE_RUN_FROM_PACKAGE="1" lets you run your app from a package local to your app. You can also run from a
remote package.
az webapp deployment source config-zip --resource-group <group-name> --name <app-name> --src <filename>.zip
Because the WEBSITE_RUN_FROM_PACKAGE app setting is set, this command doesn't extract the package content to
the D:\home\site\wwwroot directory of your app. Instead, it uploads the ZIP file as-is to
D:\home\data\SitePackages, and creates a packagename.txt in the same directory, that contains the name of the
ZIP package to load at runtime. If you upload your ZIP package in a different way (such as FTP), you need to
create the D:\home\data\SitePackages directory and the packagename.txt file manually.
The command also restarts the app. Because WEBSITE_RUN_FROM_PACKAGE is set, App Service mounts the uploaded
package as the read-only wwwroot directory and runs the app directly from that mounted directory.
If you publish an updated package with the same name to Blob storage, you need to restart your app so that the
updated package is loaded into App Service.
Fetch a package from Azure Blob Storage using a managed identity
Azure Blob Storage can be configured to authorize requests with Azure AD. This means that instead of
generating a SAS key with an expiration, you can instead rely on the application's managed identity. By default,
the app's system-assigned identity will be used. If you wish to specify a user-assigned identity, you can set the
WEBSITE_RUN_FROM_PACKAGE_BLOB_MI_RESOURCE_ID app setting to the resource ID of that identity. The setting can also
accept "SystemAssigned" as a value, although this is the same as omitting the setting altogether.
To enable the package to be fetched using the identity:
1. Ensure that the blob is configured for private access.
2. Grant the identity the Storage Blob Data Reader role with scope over the package blob. See Assign an
Azure role for access to blob data for details on creating the role assignment.
3. Set the WEBSITE_RUN_FROM_PACKAGE application setting to the blob URL of the package. This will likely be of
the form "https://{storage-account-name}.blob.core.windows.net/{container-name}/{path-to-package}" or
similar.
Troubleshooting
Running directly from a package makes wwwroot read-only. Your app will receive an error if it tries to write
files to this directory.
TAR and GZIP formats are not supported.
The ZIP file can be at most 1GB
This feature is not compatible with local cache.
For improved cold-start performance, use the local Zip option ( WEBSITE_RUN_FROM_PACKAGE =1).
More resources
Continuous deployment for Azure App Service
Deploy code with a ZIP or WAR file
Deploy files to App Service
5/18/2022 • 10 minutes to read • Edit Online
This article shows you how to deploy your code as a ZIP, WAR, JAR, or EAR package to Azure App Service. It also
shows how to deploy individual files to App Service, separate from your application package.
Prerequisites
To complete the steps in this article, create an App Service app, or use an app that you created for another
tutorial.
If you don't have an Azure subscription, create an Azure free account before you begin.
In a local terminal window, navigate to the root directory of your app project.
This directory should contain the entry file to your web app, such as index.html, index.php, and app.js. It can also
contain package management files like project.json, composer.json, package.json, bower.json, and
requirements.txt.
Unless you want App Service to run deployment automation for you, run all the build tasks (for example, npm ,
bower , gulp , composer , and pip ) and make sure that you have all the files you need to run the app. This step
is required if you want to run your package directly.
Create a ZIP archive of everything in your project. For dotnet projects, this folder is the output folder of the
dotnet publish command. The following command uses the default tool in your terminal:
# Bash
zip -r <file-name>.zip .
# PowerShell
Compress-Archive -Path * -DestinationPath <file-name>.zip
This ZIP package deployment uses the same Kudu service that powers continuous integration-based
deployments. Kudu supports the following functionality for ZIP package deployment:
Deletion of files left over from a previous deployment.
Option to turn on the default build process, which includes package restore.
Deployment customization, including running deployment scripts.
Deployment logs.
A package size limit of 2048 MB.
For more information, see Kudu documentation.
NOTE
Files in the ZIP package are copied only if their timestamps don't match what is already deployed. Generating a zip using a
build process that caches outputs can result in faster deployments. See Deploying from a zip file or url, for more
information.
Azure CLI
Azure PowerShell
Kudu API
Kudu UI
Deploy a ZIP package to your web app by using the az webapp deploy command. The CLI command uses the
Kudu publish API to deploy the files and can be fully customized.
The following example pushes a ZIP package to your site. Specify the path to your local ZIP package for
--src-path .
This command restarts the app after deploying the ZIP package.
Depending on your web apps's networking configuration, direct access to the site from your local environment
may be blocked. To deploy your code in this scenario, you can publish your ZIP to a storage system accessible
from the web app and trigger the app to pull the ZIP from the storage location, instead of pushing the ZIP to the
web app. See this article on deploying to network secured web apps for more information.
The following example uses the --src-url parameter to specify the URL of an Azure Storage account that the
site should pull the ZIP from.
Azure CLI
Azure PowerShell
Kudu API
Kudu UI
Deploy a WAR package to Tomcat or JBoss EAP by using the az webapp deploy command. Specify the path to
your local Java package for --src-path .
Depending on your web apps's networking configuration, direct access to the site from your local environment
may be blocked. To deploy your code in this scenario, you can publish your ZIP to a storage system accessible
from the web app and trigger the app to pull the ZIP from the storage location, instead of pushing the ZIP to the
web app. See this article on deploying to network secured web apps for more information.
The following example uses the --src-url parameter to specify the URL of an Azure Storage account that the
web app should pull the ZIP from.
The CLI command uses the Kudu publish API to deploy the package and can be fully customized.
Deploy a startup script, library, and static file to your web app by using the az webapp deploy command with
the --type parameter.
If you deploy a startup script this way, App Service automatically uses your script to start your app.
The CLI command uses the Kudu publish API to deploy the files and can be fully customized.
Deploy a startup script
az webapp deploy --resource-group <group-name> --name <app-name> --src-path scripts/startup.sh --
type=startup
Next steps
For more advanced deployment scenarios, try deploying to Azure with Git. Git-based deployment to Azure
enables version control, package restore, MSBuild, and more.
More resources
Kudu: Deploying from a zip file
Azure App Service Deployment Credentials
Environment variables and app settings reference
Deploy your app to Azure App Service using FTP/S
5/18/2022 • 5 minutes to read • Edit Online
This article shows you how to use FTP or FTPS to deploy your web app, mobile app backend, or API app to Azure
App Service.
The FTP/S endpoint for your app is already active. No configuration is necessary to enable FTP/S deployment.
NOTE
The Development Center (Classic) page in the Azure portal, which is the old deployment experience, will be
deprecated in March, 2021. This change will not affect any existing deployment settings in your app, and you can
continue to manage app deployment in the Deployment Center page.
A P P L IC AT IO N - SC O P E USER- SC O P E
<app-name>\$<app-name> <app-name>\<deployment-user>
In App Service, the FTP/S endpoint is shared among apps. Because the user-scope credentials aren't
linked to a specific resource, you need to prepend the user-scope username with the app name as shown
above.
In the same management page for your app where you copied the deployment credentials (Deployment
Center > FTP Credentials ), copy the FTPS endpoint .
Enforce FTPS
For enhanced security, you should allow FTP over TLS/SSL only. You can also disable both FTP and FTPS if you
don't use FTP deployment.
Azure portal
Azure CLI
Azure PowerShell
1. In your app's resource page in Azure portal, select Configuration > General settings from the left
navigation.
2. To disable unencrypted FTP, select FTPS Only in FTP state . To disable both FTP and FTPS entirely, select
Disabled . When finished, click Save . If using FTPS Only , you must enforce TLS 1.2 or higher by
navigating to the TLS/SSL settings blade of your web app. TLS 1.0 and 1.1 are not supported with FTPS
Only .
More resources
Local Git deployment to Azure App Service
Azure App Service Deployment Credentials
Sample: Create a web app and deploy files with FTP (Azure CLI).
Sample: Upload files to a web app using FTP (PowerShell).
Sync content from a cloud folder to Azure App
Service
5/18/2022 • 2 minutes to read • Edit Online
This article shows you how to sync your content to Azure App Service from Dropbox and OneDrive.
With the content sync approach, your work with your app code and content in a designated cloud folder to
make sure it's in a ready-to-deploy state, and then sync to App Service with the click of a button.
Because of underlying differences in the APIs, OneDrive for Business is not supported at this time.
NOTE
The Development Center (Classic) page in the Azure portal, which is the old deployment experience, will be
deprecated in March, 2021. This change will not affect any existing deployment settings in your app, and you can
continue to manage app deployment in the Deployment Center page.
You only need to authorize with OneDrive or Dropbox once for your Azure account. To authorize a
different OneDrive or Dropbox account for an app, click Change account .
5. In Folder , select the folder to synchronize. This folder is created under the following designated content
path in OneDrive or Dropbox.
OneDrive : Apps\Azure Web Apps
Dropbox : Apps\Azure
6. Click Save .
Synchronize content
Azure portal
Azure CLI
Azure PowerShell
1. In the Azure portal, navigate to the management page for your App Service app.
2. From the left menu, click Deployment Center > Redeploy/Sync .
Azure App Service enables continuous deployment from GitHub, Bitbucket, and Azure Repos repositories by
pulling in the latest updates.
NOTE
The Development Center (Classic) page in the Azure portal, an earlier version of the deployment functionality, was
deprecated in March 2021. This change doesn't affect existing deployment settings in your app, and you can continue to
manage app deployment from the Deployment Center page in the portal.
RUN T IM E RO OT DIREC TO RY F IL ES
PHP index.php
To customize your deployment, include a .deployment file in the repository root. For more information, see
Customize deployments and Custom deployment script.
NOTE
If you use Visual Studio, let Visual Studio create a repository for you. Your project will immediately be ready for
deployment via Git.
Configure the deployment source
1. In the Azure portal, go to the management page for your App Service app.
2. In the left pane, select Deployment Center . Then select Settings .
3. In the Source box, select one of the CI/CD options:
4. GitHub Actions is the default build provider. To change the provider, select Change provider > App
Ser vice Build Ser vice (Kudu) > OK .
NOTE
To use Azure Pipelines as the build provider for your App Service app, configure CI/CD directly from Azure
Pipelines. Don't configure it in App Service. The Azure Pipelines option just points you in the right direction.
5. If you're deploying from GitHub for the first time, select Authorize and follow the authorization prompts.
If you want to deploy from a different user's repository, select Change Account .
6. After you authorize your Azure account with GitHub, select the Organization , Repositor y , and Branch
to configure CI/CD for. If you can’t find an organization or repository, you might need to enable more
permissions on GitHub. For more information, see Managing access to your organization's repositories.
7. When GitHub Actions is selected as the build provider, you can select the workflow file you want by using
the Runtime stack and Version dropdown lists. Azure commits this workflow file into your selected
GitHub repository to handle build and deploy tasks. To see the file before saving your changes, select
Preview file .
NOTE
App Service detects the language stack setting of your app and selects the most appropriate workflow template. If
you choose a different template, it might deploy an app that doesn't run properly. For more information, see How
the GitHub Actions build provider works.
8. Select Save .
New commits in the selected repository and branch now deploy continuously into your App Service app.
You can track the commits and deployments on the Logs tab.
3. By default, the GitHub Actions workflow file is preserved in your repository, but it will continue to trigger
deployment to your app. To delete the file from your repository, select Delete workflow file .
4. Select OK .
IMPORTANT
For security, grant the minimum required access to the service principal. The scope in the previous example is
limited to the specific App Service app and not the entire resource group.
2. Save the entire JSON output for the next step, including the top-level {} .
3. In GitHub, in your repository, select Settings > Secrets > Add a new secret .
4. Paste the entire JSON output from the Azure CLI command into the secret's value field. Give the secret a
name like AZURE_CREDENTIALS .
5. In the workflow file generated by the Deployment Center, revise the azure/webapps-deploy step to look
like the following example (which is modified from a Node.js workflow file):
More resources
Deploy from Azure Pipelines to Azure App Services
Investigate common problems with continuous deployment
Use Azure PowerShell
Project Kudu
Continuous deployment with custom containers in
Azure App Service
5/18/2022 • 9 minutes to read • Edit Online
In this tutorial, you configure continuous deployment for a custom container image from managed Azure
Container Registry repositories or Docker Hub.
1. Go to Deployment Center
In the Azure portal, navigate to the management page for your App Service app.
From the left menu, click Deployment Center > Settings .
NOTE
For a Docker Compose app, select Container Registr y .
If you choose GitHub Actions, click Authorize and follow the authorization prompts. If you've already
authorized with GitHub before, you can deploy from a different user's repository by clicking Change Account .
Once you authorize your Azure account with GitHub, select the Organization , Repositor y , and Branch to
deploy from.
Follow the next steps by selecting the tab that matches your choice.
Azure Container Registry
Docker Hub
Private Registry
The Registr y dropdown displays the registries in the same subscription as your app. Select the registry you
want.
NOTE
If want to use Managed Identities to lock down ACR access follow this guide:
How to use system-assigned Managed Identities with App Service and Azure Container Registry
How to use user-assigned Managed Identities with App Service and Azure Container Registry
To deploy from a registry in a different subscription, select Private Registr y in Registr y source instead.
Select the Image and Tag to deploy. If you want, type the start up command in Star tup File .
Follow the next step depending on the Container Type :
For Docker Compose , select the registry for your private images. Click Choose file to upload your
Docker Compose file, or just paste the content of your Docker Compose file into Config .
For Single Container , select the Image and Tag to deploy. If you want, type the start up command in
Star tup File .
App Service appends the string in Star tup File to the end of the docker run command (as the
[COMMAND] [ARG...] segment) when starting your container.
3. Enable CI/CD
4. Enable CI/CD
App Service supports CI/CD integration with Azure Container Registry and Docker Hub. To enable it, select On
in Continuous deployment .
NOTE
If you select GitHub Actions in Source , you don't get this option because CI/CD is handled by GitHub Actions directly.
Instead, you see a Workflow Configuration section, where you can click Preview file to inspect the workflow file.
Azure commits this file into your selected GitHub source repository to handle build and deploy tasks. For more
information, see How CI/CD works with GitHub Actions.
When you enable this option, App Service adds a webhook to your repository in Azure Container Registry or
Docker Hub. Your repository posts to this webhook whenever your selected image is updated with docker push .
The webhook causes your App Service app to restart and run docker pull to get the updated image.
For other private registries , your can post to the webhook manually or as a step in a CI/CD pipeline. In
Webhook URL , click the Copy button to get the webhook URL.
NOTE
Support for multi-container (Docker Compose) apps is limited:
For Azure Container Registry, App Service creates a webhook in the selected registry with the registry as the scope. A
docker push to any repository in the registry (including the ones not referenced by your Docker Compose file)
triggers an app restart. You may want to modify the webhook to a narrower scope.
Docker Hub doesn't support webhooks at the registry level. You must add the webhooks manually to the images
specified in your Docker Compose file.
IMPORTANT
For security, grant the minimum required access to the service principal. The scope in the previous example is limited to
the specific App Service app and not the entire resource group.
In GitHub, browse to your repository, then select Settings > Secrets > Add a new secret . Paste the entire
JSON output from the Azure CLI command into the secret's value field. Give the secret a name like
AZURE_CREDENTIALS .
In the workflow file generated by the Deployment Center , revise the azure/webapps-deploy step with code
like the following example:
To configure a multi-container (Docker Compose) app, prepare a Docker Compose file locally, then run az
webapp config container set with the --multicontainer-config-file parameter. If your Docker Compose file
contains private images, add --docker-registry-server-* parameters as shown in the previous example.
To configure CI/CD from the container registry to your app, run az webapp deployment container config with
the --enable-cd parameter. The command outputs the webhook URL, but you must create the webhook in your
registry manually in a separate step. The following example enables CI/CD on your app, then uses the webhook
URL in the output to create the webhook in Azure Container Registry.
ci_cd_url=$(az webapp deployment container config --name <app-name> --resource-group <group-name> --enable-
cd true --query CI_CD_URL --output tsv)
More resources
Azure Container Registry
Create a .NET Core web app in App Service on Linux
Quickstart: Run a custom container on App Service
App Service on Linux FAQ
Configure custom containers
Actions workflows to deploy to Azure
Local Git deployment to Azure App Service
5/18/2022 • 5 minutes to read • Edit Online
This how-to guide shows you how to deploy your app to Azure App Service from a Git repository on your local
computer.
Prerequisites
To follow the steps in this how-to guide:
If you don't have an Azure subscription, create an Azure free account before you begin.
Install Git.
Have a local Git repository with code you want to deploy. To download a sample repository, run the
following command in your local terminal window:
RUN T IM E RO OT DIREC TO RY F IL ES
PHP index.php
To customize your deployment, include a .deployment file in the repository root. For more information, see
Customize deployments and Custom deployment script.
NOTE
If you use Visual Studio, let Visual Studio create a repository for you. Your project will immediately be ready for
deployment via Git.
Azure CLI
Azure PowerShell
Azure portal
az webapp create --resource-group <group-name> --plan <plan-name> --name <app-name> --runtime "<runtime-
flag>" --deployment-local-git
Azure CLI
Azure PowerShell
Azure portal
TIP
This URL contains the user-scope deployment username. If you like, you can use the application-scope credentials instead.
NOTE
If you created a Git-enabled app in PowerShell using New-AzWebApp, the remote is already created for you.
2. Push to the Azure remote with git push azure master (see Change deployment branch).
3. In the Git Credential Manager window, enter your user-scope or application-scope credentials, not
your Azure sign-in credentials.
If your Git remote URL already contains the username and password, you won't be prompted.
4. Review the output. You may see runtime-specific automation, such as MSBuild for ASP.NET, npm install
for Node.js, and pip install for Python.
5. Browse to your app in the Azure portal to verify that the content is deployed.
Change the deployment branch by setting the DEPLOYMENT_BRANCH app setting, then push commits to the
custom branch. To do it with Azure CLI:
Troubleshoot deployment
You may see the following common error messages when you use Git to publish to an App Service app in Azure:
Unable to access '[siteURL]': The app isn't up and running. Start the app in the Azure portal. Git
Failed to connect to deployment isn't available when the
[scmAddress]
web app is stopped.
Couldn't resolve host 'hostname' The address information for the 'azure' Use the git remote -v command to
remote is incorrect. list all remotes, along with the
associated URL. Verify that the URL for
the 'azure' remote is correct. If needed,
remove and recreate this remote using
the correct URL.
M ESSA GE C A USE RESO L UT IO N
No refs in common and none You didn't specify a branch during Run git push again, specifying the
specified; doing nothing. git push , or you haven't set the main branch: git push azure main .
Perhaps you should specify a
branch such as 'main'. push.default value in .gitconfig .
Error - Changes committed to You pushed a local branch that doesn't Verify that current branch is master .
remote repository but deployment match the app deployment branch on To change the default branch, use
to website failed.
'azure'. DEPLOYMENT_BRANCH application
setting (see Change deployment
branch).
src refspec [branchname] does You tried to push to a branch other Run git push again, specifying the
not match any. than main on the 'azure' remote. main branch: git push azure main .
RPC failed; result=22, HTTP code This error can happen if you try to Change the git configuration on the
= 5xx. push a large git repository over HTTPS. local machine to make the
postBuffer bigger. For example:
git config --global
http.postBuffer 524288000
.
Error - Changes committed to You deployed a Node.js app with a Review the npm ERR! error messages
remote repository but your web package.json file that specifies before this error for more context on
app not updated.
additional required modules. the failure. The following are the
known causes of this error, and the
corresponding npm ERR! messages:
Additional resources
App Service build server (Project Kudu documentation)
Continuous deployment to Azure App Service
Sample: Create a web app and deploy code from a local Git repository (Azure CLI)
Sample: Create a web app and deploy code from a local Git repository (PowerShell)
Deploy to App Service using GitHub Actions
5/18/2022 • 20 minutes to read • Edit Online
Get started with GitHub Actions to automate your workflow and deploy to Azure App Service from GitHub.
Prerequisites
An Azure account with an active subscription. Create an account for free.
A GitHub account. If you don't have one, sign up for free.
A working Azure App Service app.
.NET: Create an ASP.NET Core web app in Azure
ASP.NET: Create an ASP.NET Framework web app in Azure
JavaScript: Create a Node.js web app in Azure App Service
Java: Create a Java app on Azure App Service
Python: Create a Python app in Azure App Service
SEC T IO N TA SK S
A publish profile is an app-level credential. Set up your publish profile as a GitHub secret.
1. Go to your app service in the Azure portal.
2. On the Over view page, select Get Publish profile .
3. Save the downloaded file. You'll use the contents of the file to create a GitHub secret.
NOTE
As of October 2020, Linux web apps will need the app setting WEBSITE_WEBDEPLOY_USE_SCM set to true before
downloading the publish profile . This requirement will be removed in the future.
In GitHub, browse your repository, select Settings > Secrets > Add a new secret .
To use app-level credentials, paste the contents of the downloaded publish profile file into the secret's value
field. Name the secret AZURE_WEBAPP_PUBLISH_PROFILE .
When you configure your GitHub workflow, you use the AZURE_WEBAPP_PUBLISH_PROFILE in the deploy Azure Web
App action. For example:
- uses: azure/webapps-deploy@v2
with:
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
.NET actions/setup-dotnet
ASP.NET actions/setup-dotnet
Java actions/setup-java
JavaScript actions/setup-node
Python actions/setup-python
The following examples show how to set up the environment for the different supported languages:
.NET
ASP.NET
Java
JavaScript
env:
NODE_VERSION: '14.x' # set this to the node version to use
jobs:
build-and-deploy:
name: Build and Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
Python
- name: Setup Python 3.x
uses: actions/setup-python@v1
with:
python-version: 3.x
ASP.NET
You can restore NuGet dependencies and run msbuild with run .
- name: NuGet to restore dependencies as well as project-specific tools that are specified in the project
file
run: nuget restore
Java
JavaScript
For Node.js, you can set working-directory or change for npm directory in pushd .
Python
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
PA RA M ET ER EXP L A N AT IO N
Publish profile
Service principal
OpenID Connect
.NET Core
Build and deploy a .NET Core app to Azure using an Azure publish profile. The publish-profile input references
the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.
name: .NET Core CI
on: [push]
env:
AZURE_WEBAPP_NAME: my-app-name # set this to your application's name
AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the
repository root
DOTNET_VERSION: '3.1.x' # set this to the dot net version to use
jobs:
build:
runs-on: ubuntu-latest
steps:
# Checkout the repo
- uses: actions/checkout@main
ASP.NET
Build and deploy an ASP.NET MVC app that uses NuGet and publish-profile for authentication.
name: Deploy ASP.NET MVC App deploy to Azure Web App
on: [push]
env:
AZURE_WEBAPP_NAME: my-app # set this to your application's name
AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the
repository root
NUGET_VERSION: '5.3.x' # set this to the dot net version to use
jobs:
build-and-deploy:
runs-on: windows-latest
steps:
- uses: actions/checkout@main
- name: 'Run Azure webapp deploy action using publish profile credentials'
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }} # Replace with your app name
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }} # Define secret variable in repository
settings as per action documentation
package: '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}/SampleWebApplication/'
Java
Build and deploy a Java Spring app to Azure using an Azure publish profile. The publish-profile input
references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.
name: Java CI with Maven
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
working-directory: my-app-path
- name: Azure WebApp
uses: Azure/webapps-deploy@v2
with:
app-name: my-app-name
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: my/target/*.jar
JavaScript
Build and deploy a Node.js app to Azure using the app's publish profile. The publish-profile input references
the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.
# File: .github/workflows/workflow.yml
name: JavaScript CI
on: [push]
env:
AZURE_WEBAPP_NAME: my-app-name # set this to your application's name
AZURE_WEBAPP_PACKAGE_PATH: 'my-app-path' # set this to the path to your web app project, defaults to
the repository root
NODE_VERSION: '14.x' # set this to the node version to use
jobs:
build-and-deploy:
name: Build and Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
- name: npm install, build, and test
run: |
# Build and test the project, then
# deploy to Azure Web App.
npm install
npm run build --if-present
npm run test --if-present
working-directory: my-app-path
- name: 'Deploy to Azure WebApp'
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
Python
Build and deploy a Python app to Azure using the app's publish profile. Note how the publish-profile input
references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.
name: Python CI
on:
[push]
env:
AZURE_WEBAPP_NAME: my-web-app # set this to your application's name
AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository
root
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Building web app
uses: azure/appservice-build@v2
- name: Deploy web App using GH Action azure/webapps-deploy
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
Next steps
You can find our set of Actions grouped into different repositories on GitHub, each one containing
documentation and examples to help you use GitHub for CI/CD and deploy your apps to Azure.
Actions workflows to deploy to Azure
Azure login
Azure WebApp
Azure WebApp for containers
Docker login/logout
Events that trigger workflows
K8s deploy
Starter Workflows
Deploy a custom container to App Service using
GitHub Actions
5/18/2022 • 9 minutes to read • Edit Online
GitHub Actions gives you the flexibility to build an automated software development workflow. With the Azure
Web Deploy action, you can automate your workflow to deploy custom containers to App Service using GitHub
Actions.
A workflow is defined by a YAML (.yml) file in the /.github/workflows/ path in your repository. This definition
contains the various steps and parameters that are in the workflow.
For an Azure App Service container workflow, the file has three sections:
SEC T IO N TA SK S
Prerequisites
An Azure account with an active subscription. Create an account for free
A GitHub account. If you don't have one, sign up for free. You need to have code in a GitHub repository to
deploy to Azure App Service.
A working container registry and Azure App Service app for containers. This example uses Azure Container
Registry. Make sure to complete the full deployment to Azure App Service for containers. Unlike regular web
apps, web apps for containers do not have a default landing page. Publish the container to have a working
example.
Learn how to create a containerized Node.js application using Docker, push the container image to a
registry, and then deploy the image to Azure App Service
A publish profile is an app-level credential. Set up your publish profile as a GitHub secret.
1. Go to your app service in the Azure portal.
2. On the Over view page, select Get Publish profile .
NOTE
As of October 2020, Linux web apps will need the app setting WEBSITE_WEBDEPLOY_USE_SCM set to true
before downloading the file . This requirement will be removed in the future. See Configure an App Service app
in the Azure portal, to learn how to configure common web app settings.
3. Save the downloaded file. You'll use the contents of the file to create a GitHub secret.
In GitHub, browse your repository, select Settings > Secrets > Add a new secret .
To use app-level credentials, paste the contents of the downloaded publish profile file into the secret's value
field. Name the secret AZURE_WEBAPP_PUBLISH_PROFILE .
When you configure your GitHub workflow, you use the AZURE_WEBAPP_PUBLISH_PROFILE in the deploy Azure Web
App action. For example:
- uses: azure/webapps-deploy@v2
with:
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.io
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.io/myapp:${{ github.sha }}
docker push mycontainer.azurecr.io/myapp:${{ github.sha }}
You can also use Docker Login to log into multiple container registries at the same time. This example includes
two new GitHub secrets for authentication with docker.io. The example assumes that there is a Dockerfile at the
root level of the registry.
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.io
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: azure/docker-login@v1
with:
login-server: index.docker.io
username: ${{ secrets.DOCKERIO_USERNAME }}
password: ${{ secrets.DOCKERIO_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.io/myapp:${{ github.sha }}
docker push mycontainer.azurecr.io/myapp:${{ github.sha }}
PA RA M ET ER EXP L A N AT IO N
star tup-command (Optional) Enter the start-up command. For ex. dotnet run
or dotnet filename.dll
Publish profile
Service principal
OpenID Connect
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: azure/docker-login@v1
with:
login-server: mycontainer.azurecr.io
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t mycontainer.azurecr.io/myapp:${{ github.sha }}
docker push mycontainer.azurecr.io/myapp:${{ github.sha }}
- uses: azure/webapps-deploy@v2
with:
app-name: 'myapp'
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
images: 'mycontainer.azurecr.io/myapp:${{ github.sha }}'
Next steps
You can find our set of Actions grouped into different repositories on GitHub, each one containing
documentation and examples to help you use GitHub for CI/CD and deploy your apps to Azure.
Actions workflows to deploy to Azure
Azure login
Azure WebApp
Docker login/logout
Events that trigger workflows
K8s deploy
Starter Workflows
Provision and deploy microservices predictably in
Azure
5/18/2022 • 14 minutes to read • Edit Online
This tutorial shows how to provision and deploy an application composed of microservices in Azure App Service
as a single unit and in a predictable manner using JSON resource group templates and PowerShell scripting.
When provisioning and deploying high-scale applications that are composed of highly decoupled microservices,
repeatability and predictability are crucial to success. Azure App Service enables you to create microservices that
include web apps, mobile back ends, and API apps. Azure Resource Manager enables you to manage all the
microservices as a unit, together with resource dependencies such as database and source control settings. Now,
you can also deploy such an application using JSON templates and simple PowerShell scripting.
4. Next, click Deploy to start the deployment process. Once the process runs to completion, click the
http://todoappXXXX.azurewebsites.net link to browse the deployed application.
The UI would be a little slow when you first browse to it because the apps are just starting up, but
convince yourself that it’s a fully-functional application.
5. Back in the Deploy page, click the Manage link to see the new application in the Azure Portal.
6. In the Essentials dropdown, click the resource group link. Note also that the app is already connected to
the GitHub repository under External Project .
7. In the resource group blade, note that there are already two apps and one SQL Database in the resource
group.
Everything that you just saw in a few short minutes is a fully deployed two-microservice application, with all the
components, dependencies, settings, database, and continuous publishing, set up by an automated orchestration
in Azure Resource Manager. All this was done by two things:
The Deploy to Azure button
azuredeploy.json in the repo root
You can deploy this same application tens, hundreds, or thousands of times and have the exact same
configuration every time. The repeatability and the predictability of this approach enables you to deploy high-
scale applications with ease and confidence.
2. From the repository root, open azuredeploy.json in Visual Studio. If you don’t see the JSON Outline pane,
you need to install Azure .NET SDK.
I’m not going to describe every detail of the JSON format, but the More Resources section has links for learning
the resource group template language. Here, I’m just going to show you the interesting features that can help
you get started in making your own custom template for app deployment.
Parameters
Take a look at the parameters section to see that most of these parameters are what the Deploy to Azure
button prompts you to input. The site behind the Deploy to Azure button populates the input UI using the
parameters defined in azuredeploy.json. These parameters are used throughout the resource definitions, such as
resource names, property values, etc.
Resources
In the resources node, you can see that 4 top-level resources are defined, including a SQL Server instance, an
App Service plan, and two apps.
App Service plan
Let’s start with a simple root-level resource in the JSON. In the JSON Outline, click the App Service plan named
[hostingPlanName] to highlight the corresponding JSON code.
Note that the type element specifies the string for an App Service plan (it was called a server farm a long, long
time ago), and other elements and properties are filled in using the parameters defined in the JSON file, and this
resource doesn’t have any nested resources.
NOTE
Note also that the value of apiVersion tells Azure which version of the REST API to use the JSON resource definition
with, and it can affect how the resource should be formatted inside the {} .
SQL Server
Next, click on the SQL Server resource named SQLSer ver in the JSON Outline.
Note the following about the highlighted JSON code:
The use of parameters ensures that the created resources are named and configured in a way that makes
them consistent with one another.
The SQLServer resource has two nested resources, each has a different value for type .
The nested resources inside “resources”: […] , where the database and the firewall rules are defined,
have a dependsOn element that specifies the resource ID of the root-level SQLServer resource. This tells
Azure Resource Manager, “before you create this resource, that other resource must already exist; and if
that other resource is defined in the template, then create that one first”.
NOTE
For detailed information on how to use the resourceId() function, see Azure Resource Manager Template
Functions.
The effect of the dependsOn element is that Azure Resource Manager can know which resources can be
created in parallel and which resources must be created sequentially.
App Service app
Now, let’s move on to the actual apps themselves, which are more complicated. Click the
[variables(‘apiSiteName’)] app in the JSON Outline to highlight its JSON code. You’ll notice that things are
getting much more interesting. For this purpose, I’ll talk about the features one by one:
R o o t r e so u r c e
The app depends on two different resources. This means that Azure Resource Manager will create the app only
after both the App Service plan and the SQL Server instance are created.
A p p se t t i n g s
PROJECT is a KUDU setting that tells Azure deployment which project to use in a multi-project Visual Studio
solution. I will show you later how source control is configured, but since the ToDoApp code is in a multi-
project Visual Studio solution, we need this setting.
clientUrl is simply an app setting that the application code uses.
C o n n e c t i o n st r i n g s
In the properties element for config/connectionstrings , each connection string is also defined as a name:value
pair, with the specific format of "<name>" : {"value": "…", "type": "…"} . For the type element, possible values
are MySql , SQLServer , SQLAzure , and Custom .
TIP
For a definitive list of the connection string types, run the following command in Azure PowerShell:
[Enum]::GetNames("Microsoft.WindowsAzure.Commands.Utilities.Websites.Services.WebEntities.DatabaseType")
So u r c e c o n t r o l
The source control settings are also defined as a nested resource. Azure Resource Manager uses this resource to
configure continuous publishing (see caveat on IsManualIntegration later) and also to kick off the deployment
of application code automatically during the processing of the JSON file.
RepoUrl and branch should be pretty intuitive and should point to the Git repository and the name of the
branch to publish from. Again, these are defined by input parameters.
Note in the dependsOnelement that, in addition to the app resource itself, sourcecontrols/web also depends on
config/appsettings and config/connectionstrings . This is because once sourcecontrols/web is configured, the
Azure deployment process will automatically attempt to deploy, build, and start the application code. Therefore,
inserting this dependency helps you make sure that the application has access to the required app settings and
connection strings before the application code is run.
NOTE
Note also that IsManualIntegration is set to true . This property is necessary in this tutorial because you do not
actually own the GitHub repository, and thus cannot actually grant permission to Azure to configure continuous
publishing from ToDoApp (i.e. push automatic repository updates to Azure). You can use the default value false for the
specified repository only if you have configured the owner’s GitHub credentials in the Azure portal before. In other words,
if you have set up source control to GitHub or BitBucket for any app in the Azure Portal previously, using your user
credentials, then Azure will remember the credentials and use them whenever you deploy any app from GitHub or
BitBucket in the future. However, if you haven’t done this already, deployment of the JSON template will fail when Azure
Resource Manager tries to configure the app’s source control settings because it cannot log into GitHub or BitBucket with
the repository owner’s credentials.
If you drill down to an app, you should be able to see app configuration details similar to the below screenshot:
Again, the nested resources should have a hierarchy very similar to those in your JSON template file, and you
should see the app settings, connection strings, etc., properly reflected in the JSON pane. The absence of settings
here may indicate an issue with your JSON file and can help you troubleshoot your JSON template file.
You’ll now be able to see several new resources that, depending on the resource and what it does, have
dependencies on either the App Service plan or the app. These resources are not enabled by their existing
definition and you’re going to change that.
8. In the JSON Outline, click appInsights AutoScale to highlight its JSON code. This is the scaling setting
for your App Service plan.
9. In the highlighted JSON code, locate the location and enabled properties and set them as shown
below.
10. In the JSON Outline, click CPUHigh appInsights to highlight its JSON code. This is an alert.
11. Locate the location and isEnabled properties and set them as shown below. Do the same for the other
three alerts (purple bulbs).
12. You’re now ready to deploy. Right-click the project and select Deploy > New Deployment .
13. Log into your Azure account if you haven’t already done so.
14. Select an existing resource group in your subscription or create a new one, select azuredeploy.json , and
then click Edit Parameters .
You’ll now be able to edit all the parameters defined in the template file in a nice table. Parameters that
define defaults will already have their default values, and parameters that define a list of allowed values
will be shown as dropdowns.
15. Fill in all the empty parameters, and use the GitHub repo address for ToDoApp in repoUrl . Then, click
Save .
NOTE
Autoscaling is a feature offered in Standard tier or higher, and plan-level alerts are features offered in Basic tier
or higher, you’ll need to set the sku parameter to Standard or Premium in order to see all your new App
Insights resources light up.
16. Click Deploy . If you selected Save passwords , the password will be saved in the parameter file in plain
text . Otherwise, you’ll be asked to input the database password during the deployment process.
That’s it! Now you just need to go to the Azure Portal and the Azure Resource Explorer tool to see the new alerts
and autoscale settings added to your JSON deployed application.
Your steps in this section mainly accomplished the following:
1. Prepared the template file
2. Created a parameter file to go with the template file
3. Deployed the template file with the parameter file
The last step is easily done by a PowerShell cmdlet. To see what Visual Studio did when it deployed your
application, open Scripts\Deploy-AzureResourceGroup.ps1. There’s a lot of code there, but I’m just going to
highlight all the pertinent code you need to deploy the template file with the parameter file.
The last cmdlet, New-AzureResourceGroup , is the one that actually performs the action. All this should
demonstrate to you that, with the help of tooling, it is relatively straightforward to deploy your cloud application
predictably. Every time you run the cmdlet on the same template with the same parameter file, you’re going to
get the same result.
Summary
In DevOps, repeatability and predictability are keys to any successful deployment of a high-scale application
composed of microservices. In this tutorial, you have deployed a two-microservice application to Azure as a
single resource group using the Azure Resource Manager template. Hopefully, it has given you the knowledge
you need in order to start converting your application in Azure into a template and can provision and deploy it
predictably.
More resources
Azure Resource Manager Template Language
Authoring Azure Resource Manager templates
Azure Resource Manager Template Functions
Deploy an application with Azure Resource Manager template
Using Azure PowerShell with Azure Resource Manager
Troubleshooting Resource Group Deployments in Azure
Next steps
To learn about the JSON syntax and properties for resource types deployed in this article, see:
Microsoft.Sql/servers
Microsoft.Sql/servers/databases
Microsoft.Sql/servers/firewallRules
Microsoft.Web/serverfarms
Microsoft.Web/sites
Microsoft.Web/sites/slots
Microsoft.Insights/autoscalesettings
Configure deployment credentials for Azure App
Service
5/18/2022 • 5 minutes to read • Edit Online
To secure app deployment from a local computer, Azure App Service supports two types of credentials for local
Git deployment and FTP/S deployment. These credentials are not the same as your Azure subscription
credentials.
User-level credentials : one set of credentials for the entire Azure account. It can be used to deploy to
App Service for any app, in any subscription, that the Azure account has permission to access. It's the
default set that's surfaced in the portal GUI (such as the Over view and Proper ties of the app's resource
page). When a user is granted app access via Role-Based Access Control (RBAC) or coadmin permissions,
that user can use their own user-level credentials until the access is revoked. Do not share these
credentials with other Azure users.
App-level credentials : one set of credentials for each app. It can be used to deploy to that app only. The
credentials for each app are generated automatically at app creation. They can't be configured manually,
but can be reset anytime. For a user to be granted access to app-level credentials via (RBAC), that user
must be contributor or higher on the app (including Website Contributor built-in role). Readers are not
allowed to publish, and can't access those credentials.
NOTE
The Development Center (Classic) page in the Azure portal, which is the old deployment experience, will be
deprecated in March, 2021. This change will not affect any existing deployment settings in your app, and you can
continue to manage app deployment in the Deployment Center page.
Run the az webapp deployment user set command. Replace <username> and <password> with a deployment
user username and password.
The username must be unique within Azure, and for local Git pushes, must not contain the ‘@’ symbol.
The password must be at least eight characters long, with two of the following three elements: letters,
numbers, and symbols.
Get the application-scope credentials using the az webapp deployment list-publishing-profiles command. For
example:
For local Git deployment, you can also use the az webapp deployment list-publishing-credentials command to
get a Git remote URI for your app, with the application-scope credentials already embedded. For example:
To confirm that FTP access is blocked, you can try to authenticate using an FTP client such as FileZilla. To retrieve
the publishing credentials, go to the overview blade of your site and click Download Publish Profile. Use the
file’s FTP hostname, username, and password to authenticate, and you will get a 401 error response, indicating
that you are not authorized.
WebDeploy and SCM
To disable basic auth access to the WebDeploy port and SCM site, run the following CLI command. Replace the
placeholders with your resource group and site name.
To confirm that the publish profile credentials are blocked on WebDeploy, try publishing a web app using Visual
Studio 2019.
Disable access to the API
The API in the previous section is backed Azure role-based access control (Azure RBAC), which means you can
create a custom role and assign lower-priveldged users to the role so they cannot enable basic auth on any sites.
To configure the custom role, follow these instructions.
You can also use Azure Monitor to audit any successful authentication requests and use Azure Policy to enforce
this configuration for all sites in your subscription.
Next steps
Find out how to use these credentials to deploy your app from local Git or using FTP/S.
Set up staging environments in Azure App Service
5/18/2022 • 18 minutes to read • Edit Online
When you deploy your web app, web app on Linux, mobile back end, or API app to Azure App Service, you can
use a separate deployment slot instead of the default production slot when you're running in the Standard ,
Premium , or Isolated App Service plan tier. Deployment slots are live apps with their own host names. App
content and configurations elements can be swapped between two deployment slots, including the production
slot.
Deploying your application to a non-production slot has the following benefits:
You can validate app changes in a staging deployment slot before swapping it with the production slot.
Deploying an app to a slot first and swapping it into production makes sure that all instances of the slot are
warmed up before being swapped into production. This eliminates downtime when you deploy your app. The
traffic redirection is seamless, and no requests are dropped because of swap operations. You can automate
this entire workflow by configuring auto swap when pre-swap validation isn't needed.
After a swap, the slot with previously staged app now has the previous production app. If the changes
swapped into the production slot aren't as you expect, you can perform the same swap immediately to get
your "last known good site" back.
Each App Service plan tier supports a different number of deployment slots. There's no additional charge for
using deployment slots. To find out the number of slots your app's tier supports, see App Service limits.
To scale your app to a different tier, make sure that the target tier supports the number of slots your app already
uses. For example, if your app has more than five slots, you can't scale it down to the Standard tier, because the
Standard tier supports only five deployment slots.
Add a slot
The app must be running in the Standard , Premium , or Isolated tier in order for you to enable multiple
deployment slots.
1. in the Azure portal, search for and select App Ser vices and select your app.
2. In the left pane, select Deployment slots > Add Slot .
NOTE
If the app isn't already in the Standard , Premium , or Isolated tier, you receive a message that indicates the
supported tiers for enabling staged publishing. At this point, you have the option to select Upgrade and go to
the Scale tab of your app before continuing.
3. In the Add a slot dialog box, give the slot a name, and select whether to clone an app configuration from
another deployment slot. Select Add to continue.
You can clone a configuration from any existing slot. Settings that can be cloned include app settings,
connection strings, language framework versions, web sockets, HTTP version, and platform bitness.
NOTE
Currently, VNET and the Private Endpoint are not cloned across slots.
4. After the slot is added, select Close to close the dialog box. The new slot is now shown on the
Deployment slots page. By default, Traffic % is set to 0 for the new slot, with all customer traffic routed
to the production slot.
5. Select the new deployment slot to open that slot's resource page.
The staging slot has a management page just like any other App Service app. You can change the slot's
configuration. To remind you that you're viewing the deployment slot, the app name is shown as <app-
name>/<slot-name> , and the app type is App Ser vice (Slot) . You can also see the slot as a separate
app in your resource group, with the same designations.
6. Select the app URL on the slot's resource page. The deployment slot has its own host name and is also a
live app. To limit public access to the deployment slot, see Azure App Service IP restrictions.
The new deployment slot has no content, even if you clone the settings from a different slot. For example, you
can publish to this slot with Git. You can deploy to the slot from a different repository branch or a different
repository.
The slot's URL will be of the format http://sitename-slotname.azurewebsites.net . To keep the URL length within
necessary DNS limits, the site name will be truncated at 40 characters, the slot name will be truncated at 19
characters, and an additional 4 random characters will be appended to ensure the resulting domain name is
unique.
NOTE
The instances in your former production instances (those that will be swapped into staging after this swap operation) will
be recycled quickly in the last step of the swap process. In case you have any long running operations in your application,
they will be abandoned, when the workers recycle. This also applies to function apps. Therefore your application code
should be written in a fault tolerant way.
NOTE
To make aforementioned settings swappable, add the app setting
WEBSITE_OVERRIDE_PRESERVE_DEFAULT_STICKY_SLOT_SETTINGS in every slot of the app and set its value to 0 or
false . These settings are either all swappable or not at all. You can't make just some settings swappable and not the
others. Managed identities are never swapped and are not affected by this override app setting.
Certain app settings that apply to unswapped settings are also not swapped. For example, since diagnostic settings are
not swapped, related app settings like WEBSITE_HTTPLOGGING_RETENTION_DAYS and
DIAGNOSTICS_AZUREBLOBRETENTIONDAYS are also not swapped, even if they don't show up as slot settings.
To configure an app setting or connection string to stick to a specific slot (not swapped), go to the
Configuration page for that slot. Add or edit a setting, and then select deployment slot setting . Selecting
this check box tells App Service that the setting is not swappable.
Swap two slots
You can swap deployment slots on your app's Deployment slots page and the Over view page. For technical
details on the slot swap, see What happens during swap.
IMPORTANT
Before you swap an app from a deployment slot into production, make sure that production is your target slot and that
all settings in the source slot are configured exactly as you want to have them in production.
The Swap dialog box shows settings in the selected source and target slots that will be changed.
2. Select the desired Source and Target slots. Usually, the target is the production slot. Also, select the
Source Changes and Target Changes tabs and verify that the configuration changes are expected.
When you're finished, you can swap the slots immediately by selecting Swap .
To see how your target slot would run with the new settings before the swap actually happens, don't
select Swap , but follow the instructions in Swap with preview.
3. When you're finished, close the dialog box by selecting Close .
If you have any problems, see Troubleshoot swaps.
3. When you're ready to complete the pending swap, select Complete Swap in Swap action and select
Complete Swap .
To cancel a pending swap, select Cancel Swap instead.
4. When you're finished, close the dialog box by selecting Close .
If you have any problems, see Troubleshoot swaps.
To automate a multi-phase swap, see Automate with PowerShell.
NOTE
Before you configure auto swap for the production slot, consider testing auto swap on a non-production target slot.
3. Execute a code push to the source slot. Auto swap happens after a short time, and the update is reflected
at your target slot's URL.
If you have any problems, see Troubleshoot swaps.
<system.webServer>
<applicationInitialization>
<add initializationPage="/" hostName="[app hostname]" />
<add initializationPage="/Home/About" hostName="[app hostname]" />
</applicationInitialization>
</system.webServer>
For more information on customizing the applicationInitialization element, see Most common deployment
slot swap failures and how to fix them.
You can also customize the warm-up behavior with one or both of the following app settings:
WEBSITE_SWAP_WARMUP_PING_PATH : The path to ping over HTTP to warm up your site. Add this app setting by
specifying a custom path that begins with a slash as the value. An example is /statuscheck . The default value
is / .
WEBSITE_SWAP_WARMUP_PING_STATUSES : Valid HTTP response codes for the warm-up operation. Add this app
setting with a comma-separated list of HTTP codes. An example is 200,202 . If the returned status code isn't
in the list, the warmup and swap operations are stopped. By default, all response codes are valid.
WEBSITE_WARMUP_PATH : A relative path on the site that should be pinged whenever the site restarts (not only
during slot swaps). Example values include /statuscheck or the root path, / .
NOTE
The <applicationInitialization> configuration element is part of each app start-up, whereas the two warm-up
behavior app settings apply only to slot swaps.
Monitor a swap
If the swap operation takes a long time to complete, you can get information on the swap operation in the
activity log.
On your app's resource page in the portal, in the left pane, select Activity log .
A swap operation appears in the log query as Swap Web App Slots . You can expand it and select one of the
suboperations or errors to see the details.
Route traffic
By default, all client requests to the app's production URL ( http://<app_name>.azurewebsites.net ) are routed to
the production slot. You can route a portion of the traffic to another slot. This feature is useful if you need user
feedback for a new update, but you're not ready to release it to production.
Route production traffic automatically
To route production traffic automatically:
1. Go to your app's resource page and select Deployment slots .
2. In the Traffic % column of the slot you want to route to, specify a percentage (between 0 and 100) to
represent the amount of total traffic you want to route. Select Save .
After the setting is saved, the specified percentage of clients is randomly routed to the non-production slot.
After a client is automatically routed to a specific slot, it's "pinned" to that slot for the life of that client session.
On the client browser, you can see which slot your session is pinned to by looking at the x-ms-routing-name
cookie in your HTTP headers. A request that's routed to the "staging" slot has the cookie
x-ms-routing-name=staging . A request that's routed to the production slot has the cookie
x-ms-routing-name=self .
NOTE
You can also use the az webapp traffic-routing set command in the Azure CLI to set the routing percentages from
CI/CD tools like GitHub Actions, DevOps pipelines, or other automation systems.
The string x-ms-routing-name=self specifies the production slot. After the client browser accesses the link, it's
redirected to the production slot. Every subsequent request has the x-ms-routing-name=self cookie that pins the
session to the production slot.
To let users opt in to your beta app, set the same query parameter to the name of the non-production slot.
Here's an example:
<webappname>.azurewebsites.net/?x-ms-routing-name=staging
By default, new slots are given a routing rule of 0% , shown in grey. When you explicitly set this value to 0%
(shown in black text), your users can access the staging slot manually by using the x-ms-routing-name query
parameter. But they won't be routed to the slot automatically because the routing percentage is set to 0. This is
an advanced scenario where you can "hide" your staging slot from the public while allowing internal teams to
test changes on the slot.
Delete a slot
Search for and select your app. Select Deployment slots > <slot to delete> > Over view . The app type is
shown as App Ser vice (Slot) to remind you that you're viewing a deployment slot. Select Delete on the
command bar.
Azure PowerShell is a module that provides cmdlets to manage Azure through Windows PowerShell, including
support for managing deployment slots in Azure App Service.
For information on installing and configuring Azure PowerShell, and on authenticating Azure PowerShell with
your Azure subscription, see How to install and configure Microsoft Azure PowerShell.
New-AzWebApp -ResourceGroupName [resource group name] -Name [app name] -Location [location] -AppServicePlan
[app service plan name]
Create a slot
New-AzWebAppSlot -ResourceGroupName [resource group name] -Name [app name] -Slot [deployment slot name] -
AppServicePlan [app service plan name]
Initiate a swap with a preview (multi-phase swap), and apply destination slot configuration to the source slot
Cancel a pending swap (swap with review) and restore the source slot configuration
Delete a slot
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"my_site_name": {
"defaultValue": "SwapAPIDemo",
"type": "String"
},
"sites_buildVersion": {
"defaultValue": "v1",
"type": "String"
}
},
"resources": [
{
"type": "Microsoft.Web/sites/slots",
"apiVersion": "2018-02-01",
"name": "[concat(parameters('my_site_name'), '/staging')]",
"location": "East US",
"kind": "app",
"properties": {
"buildVersion": "[parameters('sites_buildVersion')]"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-02-01",
"name": "[parameters('my_site_name')]",
"location": "East US",
"kind": "app",
"dependsOn": [
"[resourceId('Microsoft.Web/sites/slots', parameters('my_site_name'), 'staging')]"
],
"properties": {
"targetBuildVersion": "[parameters('sites_buildVersion')]"
}
}
]
}
This Resource Manager template is idempotent, meaning that it can be executed repeatedly and produce the
same state of the slots. After the first execution, targetBuildVersion will match the current buildVersion , so a
swap will not be triggered.
Automate with the CLI
For Azure CLI commands for deployment slots, see az webapp deployment slot.
Troubleshoot swaps
If any error occurs during a slot swap, it's logged in D:\home\LogFiles\eventlog.xml. It's also logged in the
application-specific error log.
Here are some common swap errors:
An HTTP request to the application root is timed. The swap operation waits for 90 seconds for each HTTP
request, and retries up to 5 times. If all retries are timed out, the swap operation is stopped.
Local cache initialization might fail when the app content exceeds the local disk quota specified for the
local cache. For more information, see Local cache overview.
During custom warm-up, the HTTP requests are made internally (without going through the external
URL). They can fail with certain URL rewrite rules in Web.config. For example, rules for redirecting
domain names or enforcing HTTPS can prevent warm-up requests from reaching the app code. To work
around this issue, modify your rewrite rules by adding the following two conditions:
<conditions>
<add input="{WARMUP_REQUEST}" pattern="1" negate="true" />
<add input="{REMOTE_ADDR}" pattern="^100?\." negate="true" />
...
</conditions>
Without a custom warm-up, the URL rewrite rules can still block HTTP requests. To work around this
issue, modify your rewrite rules by adding the following condition:
<conditions>
<add input="{REMOTE_ADDR}" pattern="^100?\." negate="true" />
...
</conditions>
After slot swaps, the app may experience unexpected restarts. This is because after a swap, the hostname
binding configuration goes out of sync, which by itself doesn't cause restarts. However, certain underlying
storage events (such as storage volume failovers) may detect these discrepancies and force all worker
processes to restart. To minimize these types of restarts, set the
WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG=1 app setting on all slots. However, this app setting
does not work with Windows Communication Foundation (WCF) apps.
Next steps
Block access to non-production slots
Guidance on deploying web apps by using Azure
Resource Manager templates
5/18/2022 • 3 minutes to read • Edit Online
This article provides recommendations for creating Azure Resource Manager templates to deploy Azure App
Service solutions. These recommendations can help you avoid common problems.
Define dependencies
Defining dependencies for web apps requires an understanding of how the resources within a web app interact.
If you specify dependencies in an incorrect order, you might cause deployment errors or create a race condition
that stalls the deployment.
WARNING
If you include an MSDeploy site extension in your template, you must set any configuration resources as dependent on
the MSDeploy resource. Configuration changes cause the site to restart asynchronously. By making the configuration
resources dependent on MSDeploy, you ensure that MSDeploy finishes before the site restarts. Without these
dependencies, the site might restart during the deployment process of MSDeploy. For an example template, see
WordPress Template with Web Deploy Dependency.
The following image shows the dependency order for various App Service resources:
{
"name": "[parameters('appName')]",
"type": "Microsoft.Web/Sites",
...
"resources": [
{
"name": "MSDeploy",
"type": "Extensions",
"dependsOn": [
"[concat('Microsoft.Web/Sites/', parameters('appName'))]",
"[concat('Microsoft.Sql/servers/', parameters('dbServerName'), '/databases/',
parameters('dbName'))]",
],
...
},
{
"name": "connectionstrings",
"type": "config",
"dependsOn": [
"[concat('Microsoft.Web/Sites/', parameters('appName'), '/Extensions/MSDeploy')]"
],
...
}
]
}
For a ready-to-run sample that uses the code above, see Template: Build a simple Umbraco Web App.
{
"apiVersion": "2016-08-01",
"name": "[concat(parameters('siteNamePrefix'), uniqueString(resourceGroup().id))]",
"type": "Microsoft.Web/sites",
...
}
If your template includes a Microsoft.Web/certificates resource for TLS/SSL binding, and the certificate is stored
in a Key Vault, you must make sure the App Service identity can access the certificate.
In global Azure, the App Service service principal has the ID of abfa0a7c-a6b6-4736-8310-5855508787cd .
To grant access to Key Vault for the App Service service principal, use:
Set-AzKeyVaultAccessPolicy `
-VaultName KEY_VAULT_NAME `
-ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd `
-PermissionsToSecrets get `
-PermissionsToCertificates get
In Azure Government, the App Service service principal has the ID of 6a02c803-dafd-4136-b4c3-
5a6f318b4714 . Use that ID in the preceding example.
In your Key Vault, select Cer tificates and Generate/Impor t to upload the certificate.
In your template, provide the name of the certificate for the keyVaultSecretName .
For an example template, see Deploy a Web App certificate from Key Vault secret and use it for creating SSL
binding.
Next steps
For a tutorial on deploying web apps with a template, see Provision and deploy microservices predictably in
Azure.
To learn about JSON syntax and properties for resource types in templates, see Azure Resource Manager
template reference.
Buy a custom domain name for Azure App Service
5/18/2022 • 9 minutes to read • Edit Online
App Service domains are custom domains that are managed directly in Azure. They make it easy to manage
custom domains for Azure App Service. This tutorial shows you how to buy an App Service domain and assign
DNS names to Azure App Service.
For Azure VM or Azure Storage, see Assign App Service domain to Azure VM or Azure Storage. For Cloud
Services, see Configuring a custom domain name for an Azure cloud service.
Prerequisites
To complete this tutorial:
Create an App Service app, or use an app that you created for another tutorial. The app should be in an Azure
Public region. At this time, Azure National Clouds are not supported.
Remove the spending limit on your subscription. You cannot buy App Service domains with free subscription
credits.
4. Select Click to tr y the newer version of the App Ser vice Domains create experience .
Basics tab
1. In the Basics tab, configure the settings using the following table:
Resource Group The resource group to put the domain in. For example,
the resource group your app is in.
NOTE
The following top-level domains are supported by App Service domains: com, net, co.uk, org, nl, in, biz, org.uk,
and co.in.
NOTE
App Service Domains use GoDaddy for domain registration and Azure DNS to host the domains. In addition to
the yearly domain registration fee, usage charges for Azure DNS apply. For information, see Azure DNS Pricing.
4. When the domain registration is complete, you see a Go to resource button. Select it to see it's
management page.
You're now ready to assign an App Service app to this custom domain.
NOTE
Depending on the subscription type, a sufficient payment history may be required prior to creating an App Service
Domain.
If you have made payments and are still running into this error, you can contact support and provide proof of payments.
NOTE
App Service Free and Shared (preview) service plans are base tiers that run on the same Azure virtual machines as other
App Service apps. Some apps might belong to other customers. These tiers are intended to be used only for development
and testing purposes.
2. The app's current tier is highlighted by a blue border. Check to make sure that the app is not in the F1 tier.
Custom DNS is not supported in the F1 tier.
3. If the App Service plan is not in the F1 tier, close the Scale up page and skip to Buy the domain.
Scale up the App Service plan
1. Select any of the non-free tiers (D1 , B1 , B2 , B3 , or any tier in the Production category). For additional
options, click See additional options .
2. Click Apply .
When you see the following notification, the scale operation is complete.
3. Type the App Service domain (such as contoso.com ) or a subdomain (such as www.contoso.com ) and
click Validate .
NOTE
If you made a typo in the App Service domain name, a verification error appears at the bottom of the page to tell
you that you're missing some DNS records. You don't need to add these records manually for an App Service
domain. Just make sure that you type the domain name correctly and click Validate again.
4. Accept the Hostname record type and click Add custom domain .
5. It might take some time for the new custom domain to be reflected in the app's Custom Domains page.
Refresh the browser to update the data.
NOTE
A Not Secure label for your custom domain means that it's not yet bound to a TLS/SSL certificate. Any HTTPS
request from a browser to your custom domain will receive an error or warning, depending on the browser. To add
a TLS binding, see Secure a custom DNS name with a TLS/SSL binding in Azure App Service.
2. In the App Ser vice Domains section, select the domain you want to configure.
3. From the left navigation of the domain, select Domain renewal . To stop renewing your domain
automatically, select Off . The setting takes effect immediately.
NOTE
When navigating away from the page, disregard the "Your unsaved edits will be discarded" error by clicking OK .
To manually renew your domain, select Renew domain . However, this button is not active until 90 days before
the domain's expiration.
If your domain renewal is successful, you receive an email notification within 24 hours.
2. In the App Ser vice Domains section, select the domain you want to configure.
3. From the Over view page, select Manage DNS records .
For information on how to edit DNS records, see How to manage DNS Zones in the Azure portal.
2. In the App Ser vice Domains section, select the domain you want to configure.
3. In the domain's left navigation, select Locks .
A delete lock has been created for your domain. As long as a delete lock exists, you can't delete the App
Service domain.
4. Click Delete to remove the lock.
5. In the domain's left navigation, select Over view .
6. If the cancellation period on the purchased domain has not elapsed, select Cancel purchase . Otherwise,
you see a Delete button instead. To delete the domain without a refund, select Delete .
Next steps
Learn how to bind a custom TLS/SSL certificate to App Service.
Secure a custom DNS name with a TLS binding in Azure App Service
Configure a custom domain name in Azure App
Service with Traffic Manager integration
5/18/2022 • 5 minutes to read • Edit Online
NOTE
For Cloud Services, see Configuring a custom domain name for an Azure cloud service.
When you use Azure Traffic Manager to load balance traffic to Azure App Service, the App Service app can be
accessed using <traffic-manager-endpoint>.trafficmanager.net . You can assign a custom domain name,
such as www.contoso.com, with your App Service app in order to provide a more recognizable domain name for
your users.
This article shows you how to configure a custom domain name with an App Service app that's integrated with
Traffic Manager.
NOTE
Only CNAME records are supported when you configure a domain name using the Traffic Manager endpoint. Because A
records are not supported, a root domain mapping, such as contoso.com is also not supported.
In the left navigation of the app page, select Scale up (App Ser vice plan) .
The app's current tier is highlighted by a blue border. Check to make sure that the app is in Standard tier or
above (any tier in the Production or Isolated category). If yes, close the Scale up page and skip to Create the
CNAME mapping.
Scale up the App Service plan
If you need to scale up your app, select any of the pricing tiers in the Production category. For additional
options, click See additional options .
Click Apply .
3. In the example screenshot, select Add to create a record. Some providers have different links to add
different record types. Again, consult the provider's documentation.
NOTE
For certain providers, such as GoDaddy, changes to DNS records don't become effective until you select a separate Save
Changes link.
While the specifics of each domain provider vary, you map from a non-root custom domain name (such as
www.contoso.com ) to the Traffic Manager domain name (contoso.trafficmanager.net ) that's integrated with
your app.
NOTE
If a record is already in use and you need to preemptively bind your apps to it, you can create an additional CNAME
record. For example, to preemptively bind www.contoso.com to your app, create a CNAME record from awverify.www
to contoso.trafficmanager.net . You can then add "www.contoso.com" to your app without the need to change the
"www" CNAME record. For more information, see Migrate an active DNS name to Azure App Service.
Once you have finished adding or modifying DNS records at your domain provider, save the changes.
What about root domains?
Since Traffic Manager only supports custom domain mapping with CNAME records, and because DNS standards
don't support CNAME records for mapping root domains (for example, contoso.com ), Traffic Manager doesn't
support mapping to root domains. To work around this issue, use a URL redirect from at the app level. In
ASP.NET Core, for example, you can use URL Rewriting. Then, use Traffic Manager to load balance the subdomain
(www.contoso.com ). Another approach is you can create an alias record for your domain name apex to
reference an Azure Traffic Manager profile. An example is contoso.com. Instead of using a redirecting service,
you can configure Azure DNS to reference a Traffic Manager profile directly from your zone.
For high availability scenarios, you can implement a load-balancing DNS setup without Traffic Manager by
creating multiple A records that point from the root domain to each app copy's IP address. Then, map the same
root domain to all the app copies. Since the same domain name cannot be mapped to two different apps in the
same region, this setup only works when your app copies are in different regions.
NOTE
It can take some time for your CNAME to propagate through the DNS system. You can use a service such as
https://www.digwebinterface.com/ to verify that the CNAME is available.
1. Once domain resolution succeeds, to back to your app page in the Azure portal
2. From the left navigation, select Custom domains > Add hostname .
3. Type the custom domain name that you mapped earlier and select Validate .
4. Make sure that Hostname record type is set to CNAME (www.example.com or any subdomain) .
5. Since the App Service app is now integrated with a Traffic Manager endpoint, you should see the Traffic
Manager domain name under CNAME configuration . Select it and click Add custom domain .
Next steps
Secure a custom DNS name with an TLS/SSL binding in Azure App Service
Migrate an active DNS name to Azure App Service
5/18/2022 • 5 minutes to read • Edit Online
This article shows you how to migrate an active DNS name to Azure App Service without any downtime.
When you migrate a live site and its DNS domain name to App Service, that DNS name is already serving live
traffic. You can avoid downtime in DNS resolution during the migration by binding the active DNS name to your
App Service app preemptively.
If you're not worried about downtime in DNS resolution, see Map an existing custom DNS name to Azure App
Service.
Prerequisites
To complete this how-to, make sure that your App Service app is not in FREE tier.
NOTE
You can use Azure DNS to configure a custom DNS name for Azure App Service. For more information, see Use Azure
DNS to provide custom domain settings for an Azure service.
NOTE
For certain providers, such as GoDaddy, changes to DNS records don't become effective until you select a separate Save
Changes link.
DN S REC O RD EXA M P L E T XT H O ST T XT VA L UE
In your DNS records page, note the record type of the DNS name you want to migrate. App Service supports
mappings from CNAME and A records.
NOTE
Wildcard * records won't validate subdomains with an existing CNAME's record. You may need to explicitly create a TXT
record for each subdomain.
3. Type the fully qualified domain name you want to migrate, that corresponds to the TXT record you create,
such as contoso.com , www.contoso.com , or *.contoso.com . Select Validate .
The Add custom domain button is activated.
4. Make sure that Hostname record type is set to the DNS record type you want to migrate. Select Add
hostname .
It might take some time for the new hostname to be reflected in the app's Custom domains page. Try
refreshing the browser to update the data.
Your custom DNS name is now enabled in your Azure app.
Next steps
Learn how to bind a custom TLS/SSL certificate to App Service.
Secure a custom DNS name with a TLS binding in Azure App Service
Configure your App Service or Azure Functions app
to use Azure AD login
5/18/2022 • 10 minutes to read • Edit Online
This article shows you how to configure authentication for Azure App Service or Azure Functions so that your
app signs in users with the Microsoft identity platform (Azure AD) as the authentication provider.
The App Service Authentication feature can automatically create an app registration with the Microsoft identity
platform. You can also use a registration that you or a directory admin creates separately.
Create a new app registration automatically
Use an existing registration created separately
NOTE
The option to create a new registration is not available for government clouds. Instead, define a registration separately.
Client Secret Use the client secret you generated in the app
registration. With a client secret, hybrid flow is used and
the App Service will return access and refresh tokens.
When the client secret is not set, implicit flow is used and
only an ID token is returned. These tokens are sent by
the provider and stored in the EasyAuth token store.
NOTE
For a Microsoft Store application, use the package SID as the URI instead.
4. Select Create .
5. After the app registration is created, copy the value of Application (client) ID .
6. Select API permissions > Add a permission > My APIs .
7. Select the app registration you created earlier for your App Service app. If you don't see the app
registration, make sure that you've added the user_impersonation scope in Create an app registration
in Azure AD for your App Service app.
8. Under Delegated permissions , select user_impersonation , and then select Add permissions .
You have now configured a native client application that can request access your App Service app on behalf of a
user.
Daemon client application (service -to -service calls)
Your application can acquire a token to call a Web API hosted in your App Service or Function app on behalf of
itself (not on behalf of a user). This scenario is useful for non-interactive daemon applications that perform tasks
without a logged in user. It uses the standard OAuth 2.0 client credentials grant.
1. In the Azure portal, select Active Director y > App registrations > New registration .
2. In the Register an application page, enter a Name for your daemon app registration.
3. For a daemon application, you don't need a Redirect URI so you can keep that empty.
4. Select Create .
5. After the app registration is created, copy the value of Application (client) ID .
6. Select Cer tificates & secrets > New client secret > Add . Copy the client secret value shown in the page.
It won't be shown again.
You can now request an access token using the client ID and client secret by setting the resource parameter to
the Application ID URI of the target app. The resulting access token can then be presented to the target app
using the standard OAuth 2.0 Authorization header, and App Service Authentication / Authorization will validate
and use the token as usual to now indicate that the caller (an application in this case, not a user) is authenticated.
At present, this allows any client application in your Azure AD tenant to request an access token and
authenticate to the target app. If you also want to enforce authorization to allow only certain client applications,
you must perform some additional configuration.
1. Define an App Role in the manifest of the app registration representing the App Service or Function app you
want to protect.
2. On the app registration representing the client that needs to be authorized, select API permissions > Add a
permission > My APIs .
3. Select the app registration you created earlier. If you don't see the app registration, make sure that you've
added an App Role.
4. Under Application permissions , select the App Role you created earlier, and then select Add
permissions .
5. Make sure to click Grant admin consent to authorize the client application to request the permission.
6. Similar to the previous scenario (before any roles were added), you can now request an access token for the
same target resource , and the access token will include a roles claim containing the App Roles that were
authorized for the client application.
7. Within the target App Service or Function app code, you can now validate that the expected roles are present
in the token (this is not performed by App Service Authentication / Authorization). For more information, see
Access user claims.
You have now configured a daemon client application that can access your App Service app using its own
identity.
Best practices
Regardless of the configuration you use to set up authentication, the following best practices will keep your
tenant and applications more secure:
Give each App Service app its own permissions and consent.
Configure each App Service app with its own registration.
Avoid permission sharing between environments by using separate app registrations for separate
deployment slots. When testing new code, this practice can help prevent issues from affecting the production
app.
Next steps
App Service Authentication / Authorization overview.
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Tutorial: Authenticate and authorize users in a web app that accesses Azure Storage and Microsoft Graph
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Configure your App Service or Azure Functions app
to use Facebook login
5/18/2022 • 2 minutes to read • Edit Online
This article shows how to configure Azure App Service or Azure Functions to use Facebook as an authentication
provider.
To complete the procedure in this article, you need a Facebook account that has a verified email address and a
mobile phone number. To create a new Facebook account, go to facebook.com.
IMPORTANT
The app secret is an important security credential. Do not share this secret with anyone or distribute it within a
client application.
10. The Facebook account that you used to register the application is an administrator of the app. At this
point, only administrators can sign in to this application.
To authenticate other Facebook accounts, select App Review and enable Make <your-app-name>
public to enable the general public to access the app by using Facebook authentication.
Add Facebook information to your application
1. Sign in to the Azure portal and navigate to your app.
2. Select Authentication in the menu on the left. Click Add identity provider .
3. Select Facebook in the identity provider dropdown. Paste in the App ID and App Secret values that you
obtained previously.
The secret will be stored as a slot-sticky application setting named
FACEBOOK_PROVIDER_AUTHENTICATION_SECRET . You can update that setting later to use Key Vault references if
you wish to manage the secret in Azure Key Vault.
4. If this is the first identity provider configured for the application, you will also be prompted with an App
Ser vice authentication settings section. Otherwise, you may move on to the next step.
These options determine how your application responds to unauthenticated requests, and the default
selections will redirect all requests to log in with this new provider. You can change customize this
behavior now or adjust these settings later from the main Authentication screen by choosing Edit next
to Authentication settings . To learn more about these options, see Authentication flow.
5. (Optional) Click Next: Scopes and add any scopes needed by the application. These will be requested at
login time for browser-based flows.
6. Click Add .
You're now ready to use Facebook for authentication in your app. The provider will be listed on the
Authentication screen. From there, you can edit or delete this provider configuration.
Next steps
App Service Authentication / Authorization overview.
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Configure your App Service or Azure Functions app
to use GitHub login
5/18/2022 • 2 minutes to read • Edit Online
This article shows how to configure Azure App Service or Azure Functions to use GitHub as an authentication
provider.
To complete the procedure in this article, you need a GitHub account. To create a new GitHub account, go to
GitHub.
IMPORTANT
The client secret is an important security credential. Do not share this secret with anyone or distribute it with your
app.
This topic shows you how to configure Azure App Service or Azure Functions to use Google as an authentication
provider.
To complete the procedure in this topic, you must have a Google account that has a verified email address. To
create a new Google account, go to accounts.google.com.
IMPORTANT
The App secret is an important security credential. Do not share this secret with anyone or distribute it within a
client application.
[Note] > For adding scope: You can define what permissions your application has in the provider's
registration portal. The app can request scopes at login time which leverage these permissions.
You are now ready to use Google for authentication in your app. The provider will be listed on the
Authentication screen. From there, you can edit or delete this provider configuration.
Next steps
App Service Authentication / Authorization overview.
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Configure your App Service or Azure Functions app
to use Twitter login
5/18/2022 • 2 minutes to read • Edit Online
This article shows how to configure Azure App Service or Azure Functions to use Twitter as an authentication
provider.
To complete the procedure in this article, you need a Twitter account that has a verified email address and phone
number. To create a new Twitter account, go to twitter.com.
4. At the bottom of the page, type at least 100 characters in Tell us how this app will be used , then
select Create . Click Create again in the pop-up. The application details are displayed.
5. Select the Keys and Access Tokens tab.
Make a note of these values:
API key
API secret key
IMPORTANT
The API secret key is an important security credential. Do not share this secret with anyone or distribute it with
your app.
Next steps
App Service Authentication / Authorization overview.
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Configure your App Service or Azure Functions app
to login using an OpenID Connect provider
5/18/2022 • 2 minutes to read • Edit Online
This article shows you how to configure Azure App Service or Azure Functions to use a custom authentication
provider that adheres to the OpenID Connect specification. OpenID Connect (OIDC) is an industry standard used
by many identity providers (IDPs). You do not need to understand the details of the specification in order to
configure your app to use an adherent IDP.
You can configure your app to use one or more OIDC providers. Each must be given a unique alphanumeric
name in the configuration, and only one can serve as the default redirect target.
NOTE
Some providers may require additional steps for their configuration and how to use the values they provide. For example,
Apple provides a private key which is not itself used as the OIDC client secret, and you instead must use it craft a JWT
which is treated as the secret you provide in your app config (see the "Creating the Client Secret" section of the Sign in
with Apple documentation)
You will need to collect a client ID and client secret for your application.
IMPORTANT
The client secret is an important security credential. Do not share this secret with anyone or distribute it within a client
application.
Additionally, you will need the OpenID Connect metadata for the provider. This is often exposed via a
configuration metadata document, which is the provider's Issuer URL suffixed with
/.well-known/openid-configuration . Gather this configuration URL.
If you are unable to use a configuration metadata document, you will need to gather the following values
separately:
The issuer URL (sometimes shown as issuer )
The OAuth 2.0 Authorization endpoint (sometimes shown as authorization_endpoint )
The OAuth 2.0 Token endpoint (sometimes shown as token_endpoint )
The URL of the OAuth 2.0 JSON Web Key Set document (sometimes shown as jwks_uri )
Next steps
App Service Authentication / Authorization overview.
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Configure your App Service or Azure Functions app
to sign in using a Sign in with Apple provider
(Preview)
5/18/2022 • 6 minutes to read • Edit Online
This article shows you how to configure Azure App Service or Azure Functions to use Sign in with Apple as an
authentication provider.
To complete the procedure in this article, you must have enrolled in the Apple developer program. To enroll in
the Apple developer program, go to developer.apple.com/programs/enroll.
Cau t i on
Enabling Sign in with Apple will disable management of the App Service Authentication / Authorization feature
for your application through some clients, such as the Azure portal, Azure CLI, and Azure PowerShell. The
feature relies on a new API surface which, during preview, is not yet accounted for in all management
experiences.
4. On the Register an App ID page, provide a description and a bundle ID, and select Sign in with Apple
from the capabilities list. Then select Continue . Take note of your App ID Prefix (Team ID) from this step,
you'll need it later.
7. On the Register a New Identifier page, choose Ser vices IDs and select Continue .
8. On the Register a Ser vices ID page, provide a description and an identifier. The description is what will be
shown to the user on the consent screen. The identifier will be your client ID used in configuring the Apple
provider with your app service. Then select Configure .
9. On the pop-up window, set the Primary App ID to the App ID you created earlier. Specify your application's
domain in the domain section. For the return URL, use the URL <app-url>/.auth/login/apple/callback . For
example, https://contoso.azurewebsites.net/.auth/login/apple/callback . Then select Add and Save .
10. Review the service registration information and select Save .
{
"alg": "ES256",
"kid": "URKEYID001",
}.{
"sub": "com.yourcompany.app1",
"nbf": 1560203207,
"exp": 1560289607,
"iss": "ABC123DEFG",
"aud": "https://appleid.apple.com"
}.[Signature]
Note: Apple doesn't accept client secret JWTs with an expiration date more than six months after the creation (or
nbf) date. That means you'll need to rotate your client secret, at minimum, every six months.
More information about generating and validating tokens can be found in Apple's developer documentation.
Sign the client secret JWT
You'll use the .p8 file you downloaded previously to sign the client secret JWT. This file is a PCKS#8 file that
contains the private signing key in PEM format. There are many libraries that can create and sign the JWT for
you.
There are different kinds of open-source libraries available online for creating and signing JWT tokens. For more
information about generating JWT tokens, see JSON Web Token (JWT). For example, one way of generating the
client secret is by importing the Microsoft.IdentityModel.Tokens NuGet package and running a small amount of
C# code shown below.
using Microsoft.IdentityModel.Tokens;
public static string GetAppleClientSecret(string teamId, string clientId, string keyId, string p8key)
{
string audience = "https://appleid.apple.com";
return tokenHandler.WriteToken(token);
}
IMPORTANT
The client secret is an important security credential. Do not share this secret with anyone or distribute it within a client
application.
Add the client secret as an application setting for the app, using a setting name of your choice. Make note of this
name for later.
This section will walk you through updating the configuration to include your new IDP. An example configuration
follows.
1. Within the identityProviders object, add an apple object if one doesn't already exist.
2. Assign an object to that key with a registration object within it, and optionally a login object:
"apple" : {
"registration" : {
"clientId": "<client ID>",
"clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_CLIENT_SECRET"
},
"login": {
"scopes": []
}
}
a. Within the registration object, set the clientId to the client ID you collected.
b. Within the registration object, set clientSecretSettingName to the name of the application setting
where you stored the client secret.
c. Within the login object, you may choose to set the scopes array to include a list of scopes used when
authenticating with Apple, such as "name" and "email". If scopes are configured, they'll be explicitly
requested on the consent screen when users sign in for the first time.
Once this configuration has been set, you're ready to use your Apple provider for authentication in your app.
A complete configuration might look like the following example (where the APPLE_GENERATED_CLIENT_SECRET
setting points to an application setting containing a generated JWT):
{
"platform": {
"enabled": true
},
"globalValidation": {
"redirectToProvider": "apple",
"unauthenticatedClientAction": "RedirectToLoginPage"
},
"identityProviders": {
"apple": {
"registration": {
"clientId": "com.contoso.example.client",
"clientSecretSettingName": "APPLE_GENERATED_CLIENT_SECRET"
},
"login": {
"scopes": []
}
}
},
"login": {
"tokenStore": {
"enabled": true
}
}
}
Next steps
App Service Authentication / Authorization overview.
Tutorial: Authenticate and authorize users end-to-end in Azure App Service
Customize sign-in and sign-out in Azure App
Service authentication
5/18/2022 • 6 minutes to read • Edit Online
This article shows you how to customize user sign-ins and sign-outs while using the built-in authentication and
authorization in App Service.
When the user clicks on one of the links, the respective sign-in page opens to sign in the user.
To redirect the user post-sign-in to a custom URL, use the post_login_redirect_uri query string parameter (not
to be confused with the Redirect URI in your identity provider configuration). For example, to navigate the user
to /Home/Index after sign-in, use the following HTML code:
Client-directed sign-in
In a client-directed sign-in, the application signs in the user to the identity provider using a provider-specific
SDK. The application code then submits the resulting authentication token to App Service for validation (see
Authentication flow) using an HTTP POST request. The Azure Mobile Apps SDKs use this sign-in flow. This
validation itself doesn't actually grant you access to the desired app resources, but a successful validation will
give you a session token that you can use to access app resources.
To validate the provider token, App Service app must first be configured with the desired provider. At runtime,
after you retrieve the authentication token from your provider, post the token to /.auth/login/<provider> for
validation. For example:
POST https://<appname>.azurewebsites.net/.auth/login/aad HTTP/1.1
Content-Type: application/json
{"id_token":"<token>","access_token":"<token>"}
The token format varies slightly according to the provider. See the following table for details:
twitter {"access_token":"
<access_token>",
"access_token_secret":"
<acces_token_secret>"}
If the provider token is validated successfully, the API returns with an authenticationToken in the response body,
which is your session token.
{
"authenticationToken": "...",
"user": {
"userId": "sid:..."
}
}
Once you have this session token, you can access protected app resources by adding the X-ZUMO-AUTH header to
your HTTP requests. For example:
GET https://<appname>.azurewebsites.net/api/products/1
X-ZUMO-AUTH: <authenticationToken_value>
By default, a successful sign-out redirects the client to the URL /.auth/logout/done . You can change the post-
sign-out redirect page by adding the post_logout_redirect_uri query parameter. For example:
GET /.auth/logout?post_logout_redirect_uri=/index.html
GET /.auth/logout?post_logout_redirect_uri=https%3A%2F%2Fptop.only.wip.la%3A443%2Fhttps%2Fmyexternalurl.com
"identityProviders": {
"azureActiveDirectory": {
"login": {
"loginParameters": ["domain_hint=<domain-name>"],
}
}
}
5. Click Put .
This setting appends the domain_hint query string parameter to the login redirect URL.
IMPORTANT
It's possible for the client to remove the domain_hint parameter after receiving the redirect URL, and then login with a
different domain. So while this function is convenient, it's not a security feature.
2. In the browser explorer of your App Service files, navigate to site/wwwroot. If a Web.config doesn't exist,
create it by selecting + > New File .
3. Select the pencil for Web.config to edit it. Add the following configuration code and click Save . If
Web.config already exists, just add the <authorization> element with everything in it. Add the accounts
you want to allow in the <allow> element.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<authorization>
<allow users="[email protected],[email protected]"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration>
More resources
Tutorial: Authenticate and authorize users end-to-end
Environment variables and app settings for authentication
Work with user identities in Azure App Service
authentication
5/18/2022 • 2 minutes to read • Edit Online
This article shows you how to work with user identities when using the the built-in authentication and
authorization in App Service.
NOTE
Different language frameworks may present these headers to the app code in different formats, such as lowercase or title
case.
For ASP.NET 4.6 apps, App Service populates ClaimsPrincipal.Current with the authenticated user's claims, so
you can follow the standard .NET code pattern, including the [Authorize] attribute. Similarly, for PHP apps, App
Service populates the _SERVER['REMOTE_USER'] variable. For Java apps, the claims are accessible from the Tomcat
servlet.
For Azure Functions, ClaimsPrincipal.Current is not populated for .NET code, but you can still find the user
claims in the request headers, or get the ClaimsPrincipal object from the request context or even through a
binding parameter. See working with client identities in Azure Functions for more information.
For .NET Core, Microsoft.Identity.Web supports populating the current user with App Service authentication. To
learn more, you can read about it on the Microsoft.Identity.Web wiki, or see it demonstrated in this tutorial for a
web app accessing Microsoft Graph.
Next steps
Tutorial: Authenticate and authorize users end-to-end
Work with OAuth tokens in Azure App Service
authentication
5/18/2022 • 3 minutes to read • Edit Online
This article shows you how to work with OAuth tokens while using the built-in authentication and authorization
in App Service.
P RO VIDER H EA DER N A M ES
Google X-MS-TOKEN-GOOGLE-ID-TOKEN
X-MS-TOKEN-GOOGLE-ACCESS-TOKEN
X-MS-TOKEN-GOOGLE-EXPIRES-ON
X-MS-TOKEN-GOOGLE-REFRESH-TOKEN
Twitter X-MS-TOKEN-TWITTER-ACCESS-TOKEN
X-MS-TOKEN-TWITTER-ACCESS-TOKEN-SECRET
NOTE
Different language frameworks may present these headers to the app code in different formats, such as lowercase or title
case.
From your client code (such as a mobile app or in-browser JavaScript), send an HTTP GET request to /.auth/me
(token store must be enabled). The returned JSON has the provider-specific tokens.
NOTE
Access tokens are for accessing provider resources, so they are present only if you configure your provider with a client
secret. To see how to get refresh tokens, see Refresh access tokens.
"identityProviders": {
"azureActiveDirectory": {
"login": {
"loginParameters": ["scope=openid profile email offline_access"]
}
}
}
5. Click Put .
NOTE
The scope that gives you a refresh token is offline_access. See how it's used in Tutorial: Authenticate and authorize
users end-to-end in Azure App Service. The other scopes are requested by default by App Service already. For
information on these default scopes, see OpenID Connect Scopes.
Once your provider is configured, you can find the refresh token and the expiration time for the access token in
the token store.
To refresh your access token at any time, just call /.auth/refresh in any language. The following snippet uses
jQuery to refresh your access tokens from a JavaScript client.
function refreshTokens() {
let refreshUrl = "/.auth/refresh";
$.ajax(refreshUrl) .done(function() {
console.log("Token refresh completed successfully.");
}) .fail(function() {
console.log("Token refresh failed. See application logs for details.");
});
}
If a user revokes the permissions granted to your app, your call to /.auth/me may fail with a 403 Forbidden
response. To diagnose errors, check your application logs for details.
NOTE
The grace period only applies to the App Service authenticated session, not the tokens from the identity providers. There
is no grace period for the expired provider tokens.
Next steps
Tutorial: Authenticate and authorize users end-to-end
Manage the API and runtime versions of App
Service authentication
5/18/2022 • 8 minutes to read • Edit Online
This article shows you how to customize the API and runtime versions of the built-in authentication and
authorization in App Service.
There are two versions of the management API for App Service authentication. The V2 version is required for
the "Authentication" experience in the Azure portal. An app already using the V1 API can upgrade to the V2
version once a few changes have been made. Specifically, secret configuration must be moved to slot-sticky
application settings. This can be done automatically from the "Authentication" section of the portal for your app.
The V2 API does not support creation or editing of Microsoft Account as a distinct provider as was done in V1.
Rather, it leverages the converged Microsoft Identity Platform to sign-in users with both Azure AD and personal
Microsoft accounts. When switching to the V2 API, the V1 Azure Active Directory configuration is used to
configure the Microsoft Identity Platform provider. The V1 Microsoft Account provider will be carried forward in
the migration process and continue to operate as normal, but it is recommended that you move to the newer
Microsoft Identity Platform model. See Support for Microsoft Account provider registrations to learn more.
The automated migration process will move provider secrets into application settings and then convert the rest
of the configuration into the new format. To use the automatic migration:
1. Navigate to your app in the portal and select the Authentication menu option.
2. If the app is configured using the V1 model, you will see an Upgrade button.
3. Review the description in the confirmation prompt. If you are ready to perform the migration, click Upgrade
in the prompt.
Manually managing the migration
The following steps will allow you to manually migrate the application to the V2 API if you do not wish to use
the automatic version mentioned above.
Moving secrets to application settings
1. Get your existing configuration by using the V1 API:
In the resulting JSON payload, make note of the secret value used for each provider you have configured:
AAD: clientSecret
Google: googleClientSecret
Facebook: facebookAppSecret
Twitter: twitterConsumerSecret
Microsoft Account: microsoftAccountClientSecret
IMPORTANT
The secret values are important security credentials and should be handled carefully. Do not share these values or
persist them on a local machine.
2. Create slot-sticky application settings for each secret value. You may choose the name of each application
setting. It's value should match what you obtained in the previous step or reference a Key Vault secret
that you have created with that value.
To create the setting, you can use the Azure portal or run a variation of the following for each provider:
NOTE
The application settings for this configuration should be marked as slot-sticky, meaning that they will not move
between environments during a slot swap operation. This is because your authentication configuration itself is tied
to the environment.
3. Create a new JSON file named authsettings.json .Take the output that you received previously and
remove each secret value from it. Write the remaining output to the file, making sure that no secret is
included. In some cases, the configuration may have arrays containing empty strings. Make sure that
microsoftAccountOAuthScopes does not, and if it does, switch that value to null .
4. Add a property to authsettings.json which points to the application setting name you created earlier for
each provider:
AAD: clientSecretSettingName
Google: googleClientSecretSettingName
Facebook: facebookAppSecretSettingName
Twitter: twitterConsumerSecretSettingName
Microsoft Account: microsoftAccountClientSecretSettingName
An example file after this operation might look similar to the following, in this case only configured for
AAD:
{
"id": "/subscriptions/00d563f8-5b89-4c6a-bcec-
c1b9f6d607e0/resourceGroups/myresourcegroup/providers/Microsoft.Web/sites/mywebapp/config/authsetting
s",
"name": "authsettings",
"type": "Microsoft.Web/sites/config",
"location": "Central US",
"properties": {
"enabled": true,
"runtimeVersion": "~1",
"unauthenticatedClientAction": "AllowAnonymous",
"tokenStoreEnabled": true,
"allowedExternalRedirectUrls": null,
"defaultProvider": "AzureActiveDirectory",
"clientId": "3197c8ed-2470-480a-8fae-58c25558ac9b",
"clientSecret": "",
"clientSecretSettingName": "MICROSOFT_IDENTITY_AUTHENTICATION_SECRET",
"clientSecretCertificateThumbprint": null,
"issuer": "https://sts.windows.net/0b2ef922-672a-4707-9643-9a5726eec524/",
"allowedAudiences": [
"https://mywebapp.azurewebsites.net"
],
"additionalLoginParams": null,
"isAadAutoProvisioned": true,
"aadClaimsAuthorization": null,
"googleClientId": null,
"googleClientSecret": null,
"googleClientSecretSettingName": null,
"googleOAuthScopes": null,
"facebookAppId": null,
"facebookAppSecret": null,
"facebookAppSecretSettingName": null,
"facebookOAuthScopes": null,
"gitHubClientId": null,
"gitHubClientSecret": null,
"gitHubClientSecretSettingName": null,
"gitHubOAuthScopes": null,
"twitterConsumerKey": null,
"twitterConsumerSecret": null,
"twitterConsumerSecretSettingName": null,
"microsoftAccountClientId": null,
"microsoftAccountClientSecret": null,
"microsoftAccountClientSecretSettingName": null,
"microsoftAccountOAuthScopes": null,
"isAuthFromFile": "false"
}
}
5. Submit this file as the new Authentication/Authorization configuration for your app:
6. Validate that your app is still operating as expected after this gesture.
7. Delete the file used in the previous steps.
You have now migrated the app to store identity provider secrets as application settings.
Support for Microsoft Account provider registrations
If your existing configuration contains a Microsoft Account provider and does not contain an Azure Active
Directory provider, you can switch the configuration over to the Azure Active Directory provider and then
perform the migration. To do this:
1. Go to App registrations in the Azure portal and find the registration associated with your Microsoft
Account provider. It may be under the "Applications from personal account" heading.
2. Navigate to the "Authentication" page for the registration. Under "Redirect URIs" you should see an entry
ending in /.auth/login/microsoftaccount/callback . Copy this URI.
3. Add a new URI that matches the one you just copied, except instead have it end in /.auth/login/aad/callback
. This will allow the registration to be used by the App Service Authentication / Authorization configuration.
4. Navigate to the App Service Authentication / Authorization configuration for your app.
5. Collect the configuration for the Microsoft Account provider.
6. Configure the Azure Active Directory provider using the "Advanced" management mode, supplying the client
ID and client secret values you collected in the previous step. For the Issuer URL, use Use
<authentication-endpoint>/<tenant-id>/v2.0 , and replace <authentication-endpoint> with the authentication
endpoint for your cloud environment (e.g., "https://login.microsoftonline.com" for global Azure), also
replacing <tenant-id> with your Director y (tenant) ID .
7. Once you have saved the configuration, test the login flow by navigating in your browser to the
/.auth/login/aad endpoint on your site and complete the sign-in flow.
8. At this point, you have successfully copied the configuration over, but the existing Microsoft Account provider
configuration remains. Before you remove it, make sure that all parts of your app reference the Azure Active
Directory provider through login links, etc. Verify that all parts of your app work as expected.
9. Once you have validated that things work against the AAD Azure Active Directory provider, you may remove
the Microsoft Account provider configuration.
WARNING
It is possible to converge the two registrations by modifying the supported account types for the AAD app registration.
However, this would force a new consent prompt for Microsoft Account users, and those users' identity claims may be
different in structure, sub notably changing values since a new App ID is being used. This approach is not recommended
unless thoroughly understood. You should instead wait for support for the two registrations in the V2 API surface.
Switching to V2
Once the above steps have been performed, navigate to the app in the Azure portal. Select the "Authentication
(preview)" section.
Alternatively, you may make a PUT request against the config/authsettingsv2 resource under the site resource.
The schema for the payload is the same as captured in File-based configuration.
Using the Azure CLI, view the current middleware version with the az webapp auth show command.
In this code, replace <my_app_name> with the name of your app. Also replace <my_resource_group> with the name
of the resource group for your app.
You will see the runtimeVersion field in the CLI output. It will resemble the following example output, which has
been truncated for clarity:
{
"additionalLoginParams": null,
"allowedAudiences": null,
...
"runtimeVersion": "1.3.2",
...
}
F r o m t h e v e r si o n e n d p o i n t
You can also hit /.auth/version endpoint on an app also to view the current middleware version that the app is
running on. It will resemble the following example output:
{
"version": "1.3.2"
}
Replace <my_app_name> with the name of your app. Also replace <my_resource_group> with the name of the
resource group for your app. Also, replace <version> with a valid version of the 1.x runtime or ~1 for the latest
version. See the release notes on the different runtime versions to help determine the version to pin to.
You can run this command from the Azure Cloud Shell by choosing Tr y it in the preceding code sample. You can
also use the Azure CLI locally to execute this command after executing az login to sign in.
Next steps
Tutorial: Authenticate and authorize users end-to-end
File-based configuration in Azure App Service
authentication
5/18/2022 • 3 minutes to read • Edit Online
With App Service authentication, the authentication settings can be configured with a file. You may need to use
file-based configuration to use certain preview capabilities of App Service authentication / authorization before
they are exposed via Azure Resource Manager APIs.
IMPORTANT
Remember that your app payload, and therefore this file, may move between environments, as with slots. It is likely you
would want a different app registration pinned to each slot, and in these cases, you should continue to use the standard
configuration method instead of using the configuration file.
NOTE
The format for platform.configFilePath varies between platforms. On Windows, both relative and absolute paths are
supported. Relative is recommended. For Linux, only absolute paths are supported currently, so the value of the setting
should be "/home/site/wwwroot/auth.json" or similar.
Once you have made this configuration update, the contents of the file will be used to define the behavior of
App Service Authentication / Authorization for that site. If you ever wish to return to Azure Resource Manager
configuration, you can do so by removing changing the setting platform.configFilePath to null.
{
"platform": {
"enabled": <true|false>
},
"globalValidation": {
"unauthenticatedClientAction": "RedirectToLoginPage|AllowAnonymous|RejectWith401|RejectWith404",
"redirectToProvider": "<default provider alias>",
"excludedPaths": [
"/path1",
"/path2",
"/path3/subpath/*"
]
},
"httpSettings": {
"requireHttps": <true|false>,
"routes": {
"apiPrefix": "<api prefix>"
},
"forwardProxy": {
"convention": "NoProxy|Standard|Custom",
"customHostHeaderName": "<host header value>",
"customProtoHeaderName": "<proto header value>"
}
},
"login": {
"routes": {
"logoutEndpoint": "<logout endpoint>"
},
"tokenStore": {
"enabled": <true|false>,
"tokenRefreshExtensionHours": "<double>",
"fileSystem": {
"directory": "<directory to store the tokens in if using a file system token store
(default)>"
},
"azureBlobStorage": {
"sasUrlSettingName": "<app setting name containing the sas url for the Azure Blob Storage if
opting to use that for a token store>"
}
},
"preserveUrlFragmentsForLogins": <true|false>,
"allowedExternalRedirectUrls": [
"https://uri1.azurewebsites.net/",
"https://uri2.azurewebsites.net/",
"url_scheme_of_your_app://easyauth.callback"
],
"cookieExpiration": {
"convention": "FixedTime|IdentityDerived",
"timeToExpiration": "<timespan>"
},
"nonce": {
"validateNonce": <true|false>,
"nonceExpirationInterval": "<timespan>"
}
},
"identityProviders": {
"azureActiveDirectory": {
"enabled": <true|false>,
"registration": {
"openIdIssuer": "<issuer url>",
"clientId": "<app id>",
"clientSecretSettingName": "APP_SETTING_CONTAINING_AAD_SECRET",
},
"login": {
"loginParameters": [
"paramName1=value1",
"paramName2=value2"
]
},
"validation": {
"allowedAudiences": [
"audience1",
"audience2"
]
}
},
"facebook": {
"enabled": <true|false>,
"registration": {
"appId": "<app id>",
"appSecretSettingName": "APP_SETTING_CONTAINING_FACEBOOK_SECRET"
},
"graphApiVersion": "v3.3",
"login": {
"scopes": [
"public_profile",
"email"
]
},
},
"gitHub": {
"enabled": <true|false>,
"registration": {
"clientId": "<client id>",
"clientSecretSettingName": "APP_SETTING_CONTAINING_GITHUB_SECRET"
},
"login": {
"scopes": [
"profile",
"email"
]
}
},
"google": {
"enabled": true,
"registration": {
"clientId": "<client id>",
"clientSecretSettingName": "APP_SETTING_CONTAINING_GOOGLE_SECRET"
},
"login": {
"scopes": [
"profile",
"email"
]
},
"validation": {
"allowedAudiences": [
"audience1",
"audience2"
]
}
},
"twitter": {
"enabled": <true|false>,
"registration": {
"consumerKey": "<consumer key>",
"consumerSecretSettingName": "APP_SETTING_CONTAINING TWITTER_CONSUMER_SECRET"
}
},
"apple": {
"enabled": <true|false>,
"registration": {
"clientId": "<client id>",
"clientSecretSettingName": "APP_SETTING_CONTAINING_APPLE_SECRET"
},
"login": {
"scopes": [
"profile",
"email"
]
]
}
},
"openIdConnectProviders": {
"<providerName>": {
"enabled": <true|false>,
"registration": {
"clientId": "<client id>",
"clientCredential": {
"clientSecretSettingName": "<name of app setting containing client secret>"
},
"openIdConnectConfiguration": {
"authorizationEndpoint": "<url specifying authorization endpoint>",
"tokenEndpoint": "<url specifying token endpoint>",
"issuer": "<url specifying issuer>",
"certificationUri": "<url specifying jwks endpoint>",
"wellKnownOpenIdConfiguration": "<url specifying .well-known/open-id-configuration
endpoint - if this property is set, the other properties of this object are ignored, and
authorizationEndpoint, tokenEndpoint, issuer, and certificationUri are set to the corresponding values
listed at this endpoint>"
}
},
"login": {
"nameClaimType": "<name of claim containing name>",
"scopes": [
"openid",
"profile",
"email"
],
"loginParameterNames": [
"paramName1=value1",
"paramName2=value2"
],
}
},
//...
}
}
}
More resources
Tutorial: Authenticate and authorize users end-to-end
Environment variables and app settings for authentication
Add a TLS/SSL certificate in Azure App Service
5/18/2022 • 21 minutes to read • Edit Online
Azure App Service provides a highly scalable, self-patching web hosting service. This article shows you how to
create, upload, or import a private certificate or a public certificate into App Service.
Once the certificate is added to your App Service app or function app, you can secure a custom DNS name with
it or use it in your application code.
NOTE
A certificate uploaded into an app is stored in a deployment unit that is bound to the app service plan's resource group,
region and operating system combination (internally called a webspace). This makes the certificate accessible to other
apps in the same resource group and region combination.
The following table lists the options you have for adding certificates in App Service:
O P T IO N DESC RIP T IO N
Create a free App Service managed certificate A private certificate that's free of charge and easy to use if
you just need to secure your custom domain in App Service.
Purchase an App Service certificate A private certificate that's managed by Azure. It combines
the simplicity of automated certificate management and the
flexibility of renewal and export options.
Import a certificate from Key Vault Useful if you use Azure Key Vault to manage your PKCS12
certificates. See Private certificate requirements.
Upload a private certificate If you already have a private certificate from a third-party
provider, you can upload it. See Private certificate
requirements.
Upload a public certificate Public certificates are not used to secure custom domains,
but you can load them into your code if you need them to
access remote resources.
Prerequisites
Create an App Service app.
For a private certificate, make sure that it satisfies all requirements from App Service.
Free cer tificate only :
Map the domain you want a certificate for to App Service. For information, see Tutorial: Map an
existing custom DNS name to Azure App Service.
For a root domain (like contoso.com), make sure your app doesn't have any IP restrictions configured.
Both certificate creation and its periodic renewal for a root domain depends on your app being
reachable from the internet.
NOTE
Elliptic Cur ve Cr yptography (ECC) cer tificates can work with App Service but are not covered by this article. Work
with your certificate authority on the exact steps to create ECC certificates.
Check to make sure that your web app is not in the F1 or D1 tier. Your web app's current tier is highlighted by a
dark blue box.
Custom SSL is not supported in the F1 or D1 tier. If you need to scale up, follow the steps in the next section.
Otherwise, close the Scale up page and skip the Scale up your App Service plan section.
Scale up your App Service plan
Select any of the non-free tiers (B1 , B2 , B3 , or any tier in the Production category). For additional options, click
See additional options .
Click Apply .
When you see the following notification, the scale operation is complete.
IMPORTANT
Because Azure fully manages the certificates on your behalf, any aspect of the managed certificate, including the root
issuer, can be changed at anytime. These changes are outside of your control. You should avoid having a hard
dependency or practice certificate "pinning" to the managed certificate, or to any part of the certificate hierarchy. If you
need the certificate pinning behavior, add a certificate to your custom domain using any other available method in this
article.
Apex domain
Subdomain
NOTE
The free certificate is issued by DigiCert. For some domains, you must explicitly allow DigiCert as a certificate issuer by
creating a CAA domain record with the value: 0 issue digicert.com .
In the Azure portal, from the left menu, select App Ser vices > <app-name> .
From the left navigation of your app, select TLS/SSL settings > Private Key Cer tificates (.pfx) > Create
App Ser vice Managed Cer tificate .
Select the custom domain to create a free certificate for and select Create . You can create only one certificate
for each supported custom domain.
When the operation completes, you see the certificate in the Private Key Cer tificates list.
IMPORTANT
To secure a custom domain with this certificate, you still need to create a certificate binding. Follow the steps in Create
binding.
NOTE
All prices shown are for examples only.
Use the following table to help you configure the certificate. When finished, click Create .
Resource group The resource group that will contain the certificate. You can
use a new resource group or select the same resource group
as your App Service app, for example.
SET T IN G DESC RIP T IO N
Naked Domain Host Name Specify the root domain here. The issued certificate secures
both the root domain and the www subdomain. In the
issued certificate, the Common Name field contains the root
domain, and the Subject Alternative Name field contains the
www domain. To secure any subdomain only, specify the
fully qualified domain name of the subdomain here (for
example, mysubdomain.contoso.com ).
NOTE
App Service Certificates purchased from Azure are issued by GoDaddy. For some domains, you must explicitly allow
GoDaddy as a certificate issuer by creating a CAA domain record with the value: 0 issue godaddy.com
Key Vault is an Azure service that helps safeguard cryptographic keys and secrets used by cloud applications
and services. It's the storage of choice for App Service certificates.
In the Key Vault Status page, click Key Vault Repositor y to create a new vault or choose an existing vault. If
you choose to create a new vault, use the following table to help you configure the vault and click Create. Create
the new Key Vault inside the same subscription and resource group as your App Service app.
Pricing tier For information, see Azure Key Vault pricing details.
Access policies Defines the applications and the allowed access to the vault
resources. You can configure it later, following the steps at
Assign a Key Vault access policy.
Virtual Network Access Restrict vault access to certain Azure virtual networks. You
can configure it later, following the steps at Configure Azure
Key Vault Firewalls and Virtual Networks
Once you've selected the vault, close the Key Vault Repositor y page. The Step 1: Store option should show a
green check mark for success. Keep the page open for the next step.
NOTE
Currently, App Service Certificate only supports Key Vault access policy but not RBAC model.
Select App Ser vice Verification . Since you already mapped the domain to your web app (see Prerequisites),
it's already verified. Just click Verify to finish this step. Click the Refresh button until the message Cer tificate
is Domain Verified appears.
IMPORTANT
For a Standard certificate, the certificate provider gives you a certificate for the requested top-level domain and its www
subdomain (for example, contoso.com and www.contoso.com ). However, beginning on December 1, 2021, a restriction
is introduced on the App Ser vice and the Manual verification methods. Both of them use HTML page verification to
verify domain ownership. With this method, the certificate provider is no longer allowed to include the www subdomain
when issuing, rekeying, or renewing a certificate.
The Domain and Mail verification methods continue to include the www subdomain with the requested top-level
domain in the certificate.
NOTE
Four types of domain verification methods are supported:
App Ser vice - The most convenient option when the domain is already mapped to an App Service app in the same
subscription. It takes advantage of the fact that the App Service app has already verified the domain ownership (see
previous note).
Domain - Verify an App Service domain that you purchased from Azure. Azure automatically adds the verification TXT
record for you and completes the process.
Mail - Verify the domain by sending an email to the domain administrator. Instructions are provided when you select
the option.
Manual - Verify the domain using either an HTML page (Standard certificate only, see previous note) or a DNS TXT
record. Instructions are provided when you select the option. The HTML page option doesn't work for web apps with
"Https Only" enabled.
NOTE
Currently, Key Vault Certificate only supports Key Vault access policy but not RBAC model.
Key Vault The vault with the certificate you want to import.
Certificate Select from the list of PKCS12 certificates in the vault. All
PKCS12 certificates in the vault are listed with their
thumbprints, but not all are supported in App Service.
When the operation completes, you see the certificate in the Private Key Cer tificates list. If the import fails
with an error, the certificate doesn't meet the requirements for App Service.
NOTE
If you update your certificate in Key Vault with a new certificate, App Service automatically syncs your certificate within 24
hours.
IMPORTANT
To secure a custom domain with this certificate, you still need to create a certificate binding. Follow the steps in Create
binding.
-----BEGIN CERTIFICATE-----
<The entire Base64 encoded intermediate certificate 1>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<The entire Base64 encoded intermediate certificate 2>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<The entire Base64 encoded root certificate>
-----END CERTIFICATE-----
When prompted, define an export password. You'll use this password when uploading your TLS/SSL certificate
to App Service later.
If you used IIS or Certreq.exe to generate your certificate request, install the certificate to your local machine,
and then export the certificate to PFX.
Upload certificate to App Service
You're now ready upload the certificate to App Service.
In the Azure portal, from the left menu, select App Ser vices > <app-name> .
From the left navigation of your app, select TLS/SSL settings > Private Key Cer tificates (.pfx) > Upload
Cer tificate .
In PFX Cer tificate File , select your PFX file. In Cer tificate password , type the password that you created
when you exported the PFX file. When finished, click Upload .
When the operation completes, you see the certificate in the Private Key Cer tificates list.
IMPORTANT
To secure a custom domain with this certificate, you still need to create a certificate binding. Follow the steps in Create
binding.
Once the certificate is uploaded, copy the certificate thumbprint and see Make the certificate accessible.
Renew an expiring certificate
Before a certificate expires, you should add the renewed certificate into App Service and update any TLS/SSL
binding. The process depends on the certificate type. For example, a certificate imported from Key Vault,
including an App Service certificate, automatically syncs to App Service every 24 hours and updates the
TLS/SSL binding when you renew the certificate. For an uploaded certificate, there's no automatic binding
update. See one of the following sections depending on your scenario:
Renew an uploaded certificate
Renew an App Service certificate
Renew a certificate imported from Key Vault
Renew an uploaded certificate
To replace an expiring certificate, how you update the certificate binding with the new certificate can adversely
affect user experience. For example, your inbound IP address can change when you delete a binding, even if that
binding is IP-based. This is especially important when you renew a certificate that's already in an IP-based
binding. To avoid a change in your app's IP address, and to avoid downtime for your app due to HTTPS errors,
follow these steps in order:
1. Upload the new certificate.
2. Bind the new certificate to the same custom domain without deleting the existing (expiring) certificate. This
action replaces the binding instead of removing the existing certificate binding. To do this, navigate to the
TLS/SSL settings blade of your App Service and select the Add Binding button.
3. Delete the existing certificate.
Renew an App Service certificate
NOTE
Beginning September 23 2021, App Service certificates require domain verification during renew or rekey if you haven't
verified domain in the last 395 days. The new certificate order remains in "pending issuance" during renew or rekey until
you complete the domain verification.
Unlike App Service Managed Certificate, domain re-verification for App Service certificates is not automated, and failure
to verify domain ownership will result in failed renewals. Refer to verify domain ownership for more information on how to
verify your App Service certificate.
NOTE
The renewal process requires that the well-known service principal for App Service has the required permissions on your
key vault. This permission is configured for you when you import an App Service Certificate through the portal, and
should not be removed from your key vault.
By default, App Service certificates have a one-year validity period. Near the time of expiration, App Service
certificates, can be renewed in one-year increments automatically or manually. In effect, th renewal process
gives you a new App Service certificate with the expiration date extended to one year from the existing
certificate's expiration date.
To toggle the automatic renewal setting of your App Service certificate at any time, select the certificate in the
App Service Certificates page, then click Auto Renew Settings in the left navigation.
Select On or Off and click Save . Certificates can start automatically renewing 32 days before expiration if you
have automatic renewal turned on.
To manually renew the certificate instead, click Manual Renew . You can request to manually renew your
certificate 60 days before expiration.
Once the renew operation is complete, click Sync . The sync operation automatically updates the hostname
bindings for the certificate in App Service without causing any downtime to your apps.
NOTE
If you don't click Sync, App Service automatically syncs your certificate within 24 hours.
NOTE
If you don't click Sync, App Service automatically syncs your certificate within 24 hours.
Export certificate
Because an App Service Certificate is a Key Vault secret, you can export a PFX copy of it and use it for other
Azure services or outside of Azure.
NOTE
The exported certificate is an unmanaged artifact. For example, it isn't synced when the App Service Certificate is renewed.
You must export the renewed certificate and install it where you need it.
Azure portal
Azure CLI
1. Select the certificate in the App Service Certificates page, then select Expor t Cer tificate from the left
navigation.
2. Select Open in Key Vault .
3. Select the current version of the certificate.
4. Select Download as a cer tificate .
The downloaded PFX file is a raw PKCS12 file that contains both the public and private certificates, and its
import password is an empty string. You can install it locally by leaving the password field empty. Notable is the
fact that it can't be uploaded into App Service as-is because it's not password protected.
Delete certificate
Deletion of an App Service certificate is final and irreversible. Deletion of an App Service Certificate resource
results in the certificate being revoked. Any binding in App Service with this certificate becomes invalid. To
prevent accidental deletion, Azure puts a lock on the certificate. To delete an App Service certificate, you must
first remove the delete lock on the certificate.
Select the certificate in the App Service Certificates page, then select Locks in the left navigation.
Find the lock on your certificate with the lock type Delete . To the right of it, select Delete .
Now you can delete the App Service certificate. From the left navigation, select Over view > Delete . In the
confirmation dialog, type the certificate name and select OK .
# Before continuing, go to your DNS configuration UI for your custom domain and follow the
# instructions at https://aka.ms/appservicecustomdns to configure a CNAME record for the
# hostname "www" and point it your web app's default domain name.
# Upgrade App Service plan to Basic tier (minimum required by custom SSL certificates)
Set-AzAppServicePlan -Name $webappname -ResourceGroupName $webappname `
-Tier Basic
By setting up access restrictions, you can define a priority-ordered allow/deny list that controls network access
to your app. The list can include IP addresses or Azure Virtual Network subnets. When there are one or more
entries, an implicit deny all exists at the end of the list.
The access restriction capability works with all Azure App Service-hosted workloads. The workloads can include
web apps, API apps, Linux apps, Linux custom containers and Functions.
When a request is made to your app, the FROM address is evaluated against the rules in your access restriction
list. If the FROM address is in a subnet that's configured with service endpoints to Microsoft.Web, the source
subnet is compared against the virtual network rules in your access restriction list. If the address isn't allowed
access based on the rules in the list, the service replies with an HTTP 403 status code.
The access restriction capability is implemented in the App Service front-end roles, which are upstream of the
worker hosts where your code runs. Therefore, access restrictions are effectively network access-control lists
(ACLs).
The ability to restrict access to your web app from an Azure virtual network is enabled by service endpoints.
With service endpoints, you can restrict access to a multi-tenant service from selected subnets. It doesn't work
to restrict traffic to apps that are hosted in an App Service Environment. If you're in an App Service Environment,
you can control access to your app by applying IP address rules.
NOTE
The service endpoints must be enabled both on the networking side and for the Azure service that they're being enabled
with. For a list of Azure services that support service endpoints, see Virtual Network service endpoints.
5. On the Access Restrictions page, review the list of access restriction rules that are defined for your app.
The list displays all the current restrictions that are applied to the app. If you have a virtual network
restriction on your app, the table shows whether the service endpoints are enabled for Microsoft.Web. If
no restrictions are defined on your app, the app is accessible from anywhere.
Permissions
You must have at least the following Role-based access control permissions on the subnet or at a higher level to
configure access restrictions through Azure portal, CLI or when setting the site config properties directly:
A C T IO N DESC RIP T IO N
NOTE
There is a limit of 512 access restriction rules. If you require more than 512 access restriction rules, we suggest that
you consider installing a standalone security product, such as Azure Front Door, Azure App Gateway, or an alternative
WAF.
Specify the Subscription , Vir tual Network , and Subnet drop-down lists, matching what you want to restrict
access to.
By using service endpoints, you can restrict access to selected Azure virtual network subnets. If service
endpoints aren't already enabled with Microsoft.Web for the subnet that you selected, they'll be automatically
enabled unless you select the Ignore missing Microsoft.Web ser vice endpoints check box. The scenario
where you might want to enable service endpoints on the app but not the subnet depends mainly on whether
you have the permissions to enable them on the subnet.
If you need someone else to enable service endpoints on the subnet, select the Ignore missing
Microsoft.Web ser vice endpoints check box. Your app will be configured for service endpoints in
anticipation of having them enabled later on the subnet.
You can't use service endpoints to restrict access to apps that run in an App Service Environment. When your
app is in an App Service Environment, you can control access to it by applying IP access rules.
With service endpoints, you can configure your app with application gateways or other web application firewall
(WAF) devices. You can also configure multi-tier applications with secure back ends. For more information, see
Networking features and App Service and Application Gateway integration with service endpoints.
NOTE
Service endpoints aren't currently supported for web apps that use IP-based TLS/SSL bindings with a virtual IP (VIP).
All available service tags are supported in access restriction rules. Each service tag represents a list of IP ranges
from Azure services. A list of these services and links to the specific ranges can be found in the service tag
documentation. Use Azure Resource Manager templates or scripting to configure more advanced rules like
regional scoped rules.
Edit a rule
1. To begin editing an existing access restriction rule, on the Access Restrictions page, select the rule you
want to edit.
2. On the Edit Access Restriction pane, make your changes, and then select Update rule . Edits are
effective immediately, including changes in priority ordering.
NOTE
When you edit a rule, you can't switch between rule types.
Delete a rule
To delete a rule, on the Access Restrictions page, select the ellipsis (...) next to the rule you want to delete, and
then select Remove .
Access restriction advanced scenarios
The following sections describe some advanced scenarios using access restrictions.
Filter by http header
As part of any rule, you can add additional http header filters. The following http header names are supported:
X-Forwarded-For
X-Forwarded-Host
X-Azure-FDID
X-FD-HealthProbe
For each header name, you can add up to eight values separated by comma. The http header filters are
evaluated after the rule itself and both conditions must be true for the rule to apply.
Multi-source rules
Multi-source rules allow you to combine up to eight IP ranges or eight Service Tags in a single rule. You might
use this if you have more than 512 IP ranges or you want to create logical rules where multiple IP ranges are
combined with a single http header filter.
Multi-source rules are defined the same way you define single-source rules, but with each range separated with
comma.
PowerShell example:
PowerShell example:
NOTE
Working with service tags, http headers or multi-source rules in Azure CLI requires at least version 2.23.0. You can
verify the version of the installed module with: az version
NOTE
Working with service tags, http headers or multi-source rules in Azure PowerShell requires at least version 5.7.0.
You can verify the version of the installed module with: Get-InstalledModule -Name Az
You can also set values manually by doing either of the following:
Use an Azure REST API PUT operation on the app configuration in Azure Resource Manager. The location
for this information in Azure Resource Manager is:
management.azure.com/subscriptions/subscription ID /resourceGroups/resource
groups /providers/Microsoft.Web/sites/web app name /config/web?api-version=2020-06-01
Use a Resource Manager template. As an example, you can use resources.azure.com and edit the
ipSecurityRestrictions block to add the required JSON.
The JSON syntax for the earlier example is:
{
"properties": {
"ipSecurityRestrictions": [
{
"ipAddress": "122.133.144.0/24",
"action": "Allow",
"priority": 100,
"name": "IP example rule"
}
]
}
}
The JSON syntax for an advanced example using service tag and http header restriction is:
{
"properties": {
"ipSecurityRestrictions": [
{
"ipAddress": "AzureFrontDoor.Backend",
"tag": "ServiceTag",
"action": "Allow",
"priority": 100,
"name": "Azure Front Door example",
"headers": {
"x-azure-fdid": [
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]
}
}
]
}
}
Next steps
Access restrictions for Azure Functions
Application Gateway integration with service endpoints
How to use managed identities for App Service and
Azure Functions
5/18/2022 • 12 minutes to read • Edit Online
This article shows you how to create a managed identity for App Service and Azure Functions applications and
how to use it to access other resources.
IMPORTANT
Managed identities for App Service and Azure Functions won't behave as expected if your app is migrated across
subscriptions/tenants. The app needs to obtain a new identity, which is done by disabling and re-enabling the feature.
Downstream resources also need to have access policies updated to use the new identity.
NOTE
Managed identities are not available for apps deployed in Azure Arc.
A managed identity from Azure Active Directory (Azure AD) allows your app to easily access other Azure AD-
protected resources such as Azure Key Vault. The identity is managed by the Azure platform and does not
require you to provision or rotate any secrets. For more about managed identities in Azure AD, see Managed
identities for Azure resources.
Your application can be granted two types of identities:
A system-assigned identity is tied to your application and is deleted if your app is deleted. An app can
only have one system-assigned identity.
A user-assigned identity is a standalone Azure resource that can be assigned to your app. An app can have
multiple user-assigned identities.
1. In the left navigation of your app's page, scroll down to the Settings group.
2. Select Identity .
3. Within the System assigned tab, switch Status to On . Click Save .
NOTE
To find the managed identity for your web app or slot app in the Azure portal, under Enterprise applications , look in
the User settings section. Usually, the slot name is similar to <app name>/slots/<slot name> .
Azure portal
Azure CLI
Azure PowerShell
ARM template
IMPORTANT
The back-end services for managed identities maintain a cache per resource URI for around 24 hours. If you update the
access policy of a particular target resource and immediately retrieve a token for that resource, you may continue to get a
cached token with outdated permissions until that token expires. There's currently no way to force a token refresh.
HTTP GET
.NET
JavaScript
Python
Java
PowerShell
{
"access_token": "eyJ0eXAi…",
"expires_on": "1586984735",
"resource": "https://vault.azure.net",
"token_type": "Bearer",
"client_id": "5E29463D-71DA-4FE0-8E69-999B57DB23B0"
}
This response is the same as the response for the Azure AD service-to-service access token request. To access
Key Vault, you will then add the value of access_token to a client connection with the vault.
For more information on the REST endpoint, see REST endpoint reference.
Remove an identity
When you remove a system-assigned identity, it's deleted from Azure Active Directory. System-assigned
identities are also automatically removed from Azure Active Directory when you delete the app resource itself.
Azure portal
Azure CLI
Azure PowerShell
ARM template
1. In the left navigation of your app's page, scroll down to the Settings group.
2. Select Identity . Then follow the steps based on the identity type:
System-assigned identity : Within the System assigned tab, switch Status to Off . Click Save .
User-assigned identity : Click the User assigned tab, select the checkbox for the identity, and click
Remove . Click Yes to confirm.
NOTE
There is also an application setting that can be set, WEBSITE_DISABLE_MSI, which just disables the local token service.
However, it leaves the identity in place, and tooling will still show the managed identity as "on" or "enabled." As a result,
use of this setting is not recommended.
PA RA M ET ER N A M E IN DESC RIP T IO N
PA RA M ET ER N A M E IN DESC RIP T IO N
IMPORTANT
If you are attempting to obtain tokens for user-assigned identities, you must include one of the optional properties.
Otherwise the token service will attempt to obtain a token for a system-assigned identity, which may or may not exist.
Next steps
Tutorial: Connect to SQL Database from App Service without secrets using a managed identity
Access Azure Storage securely using a managed identity
Call Microsoft Graph securely using a managed identity
Connect securely to services with Key Vault secrets
Use Key Vault references for App Service and Azure
Functions
5/18/2022 • 8 minutes to read • Edit Online
This topic shows you how to work with secrets from Azure Key Vault in your App Service or Azure Functions
application without requiring any code changes. Azure Key Vault is a service that provides centralized secrets
management, with full control over access policies and audit history.
Azure CLI
Azure PowerShell
2. Make sure that the vault's configuration accounts for the network or subnet through which your app will
access it.
NOTE
Windows container currently does not support Key Vault references over VNet Integration.
Azure CLI
Azure PowerShell
Reference syntax
A Key Vault reference is of the form @Microsoft.KeyVault({referenceString}) , where {referenceString} is
replaced by one of the following options:
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)
Alternatively:
@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)
Rotation
If a version is not specified in the reference, then the app will use the latest version that exists in the key vault.
When newer versions become available, such as with a rotation event, the app will automatically update and
begin using the latest version within 24 hours. The delay is because App Service caches the values of the key
vault references and refetches it every 24 hours. Any configuration changes to the app that results in a site
restart causes an immediate refetch of all referenced secrets.
TIP
Most application settings using Key Vault references should be marked as slot settings, as you should have separate
vaults for each environment.
If you skip validation and either the connection string or content share are invalid, the app will be unable to start
properly and will only serve HTTP 500 errors.
As part of creating the site, it is also possible that attempted mounting of the content share could fail due to
managed identity permissions not being propagated or the virtual network integration not being set up. You can
defer setting up Azure Files until later in the deployment template to accommodate this. See Azure Resource
Manager deployment to learn more. App Service will use a default file system until Azure Files is set up, and files
are not copied over, so you will need to ensure that no deployment attempts occur during the interim period
before Azure Files is mounted.
Azure Resource Manager deployment
When automating resource deployments through Azure Resource Manager templates, you may need to
sequence your dependencies in a particular order to make this feature work. Of note, you will need to define
your application settings as their own resource, rather than using a siteConfig property in the site definition.
This is because the site needs to be defined first so that the system-assigned identity is created with it and can
be used in the access policy.
An example pseudo-template for a function app might look like the following:
{
//...
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
//...
},
{
"type": "Microsoft.Insights/components",
"name": "[variables('appInsightsName')]",
//...
},
{
"type": "Microsoft.Web/sites",
"name": "[variables('functionAppName')]",
"identity": {
"type": "SystemAssigned"
},
//...
"resources": [
{
"type": "config",
"name": "appsettings",
//...
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
"[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'),
variables('storageConnectionStringName'))]",
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'),
variables('appInsightsKeyName'))]"
],
"properties": {
"AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=',
reference(variables('storageConnectionStringResourceId')).secretUriWithVersion, ')')]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "
[concat('@Microsoft.KeyVault(SecretUri=',
reference(variables('storageConnectionStringResourceId')).secretUriWithVersion, ')')]",
"APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=',
reference(variables('appInsightsKeyResourceId')).secretUriWithVersion, ')')]",
"WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
//...
}
},
{
"type": "sourcecontrols",
"name": "web",
//...
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
"[resourceId('Microsoft.Web/sites/config', variables('functionAppName'),
'appsettings')]"
],
}
]
},
{
"type": "Microsoft.KeyVault/vaults",
"name": "[variables('keyVaultName')]",
//...
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
],
"properties": {
//...
"accessPolicies": [
{
"tenantId": "[reference(resourceId('Microsoft.Web/sites/',
variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
"objectId": "[reference(resourceId('Microsoft.Web/sites/',
variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
"permissions": {
"secrets": [ "get" ]
}
}
]
},
"resources": [
{
"type": "secrets",
"name": "[variables('storageConnectionStringName')]",
//...
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',
variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-
01').key1)]"
}
},
{
"type": "secrets",
"name": "[variables('appInsightsKeyName')]",
//...
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
"[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
],
"properties": {
"value": "[reference(resourceId('microsoft.insights/components/',
variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
}
}
]
}
]
}
NOTE
In this example, the source control deployment depends on the application settings. This is normally unsafe behavior, as
the app setting update behaves asynchronously. However, because we have included the
WEBSITE_ENABLE_SYNC_UPDATE_SITE application setting, the update is synchronous. This means that the source control
deployment will only begin once the application settings have been fully updated. For more app settings, see Environment
variables and app settings in Azure App Service.
Troubleshooting Key Vault References
If a reference is not resolved properly, the reference value will be used instead. This means that for application
settings, an environment variable would be created whose value has the @Microsoft.KeyVault(...) syntax. This
may cause the application to throw errors, as it was expecting a secret of a certain structure.
Most commonly, this is due to a misconfiguration of the Key Vault access policy. However, it could also be due to
a secret no longer existing or a syntax error in the reference itself.
If the syntax is correct, you can view other causes for error by checking the current resolution status in the
portal. Navigate to Application Settings and select "Edit" for the reference in question. Below the setting
configuration, you should see status information, including any errors. The absence of these implies that the
reference syntax is invalid.
You can also use one of the built-in detectors to get additional information.
Using the detector for App Service
1. In the portal, navigate to your app.
2. Select Diagnose and solve problems .
3. Choose Availability and Performance and select Web app down.
4. Find Key Vault Application Settings Diagnostics and click More info .
Using the detector for Azure Functions
1. In the portal, navigate to your app.
2. Navigate to Platform features.
3. Select Diagnose and solve problems .
4. Choose Availability and Performance and select Function app down or repor ting errors.
5. Click on Key Vault Application Settings Diagnostics.
Use a TLS/SSL certificate in your code in Azure App
Service
5/18/2022 • 4 minutes to read • Edit Online
In your application code, you can access the public or private certificates you add to App Service. Your app code
may act as a client and access an external service that requires certificate authentication, or it may need to
perform cryptographic tasks. This how-to guide shows how to use public or private certificates in your
application code.
This approach to using certificates in your code makes use of the TLS functionality in App Service, which
requires your app to be in Basic tier or above. If your app is in Free or Shared tier, you can include the
certificate file in your app repository.
When you let App Service manage your TLS/SSL certificates, you can maintain the certificates and your
application code separately and safeguard your sensitive data.
Prerequisites
To follow this how-to guide:
Create an App Service app
Add a certificate to your app
using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
if (cert is null)
throw new Exception($"Certificate with thumbprint {certThumbprint} was not found");
// Use certificate
Console.WriteLine(cert.FriendlyName);
// Consider to call Dispose() on the certificate after it's being used, avaliable in .NET 4.6 and later
}
In Java code, you access the certificate from the "Windows-MY" store using the Subject Common Name field
(see Public key certificate). The following code shows how to load a private key certificate:
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.PrivateKey;
...
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
Certificate cert = ks.getCertificate("<subject-cn>");
PrivateKey privKey = (PrivateKey) ks.getKey("<subject-cn>", ("<password>").toCharArray());
For languages that don't support or offer insufficient support for the Windows certificate store, see Load
certificate from file.
This approach to using certificates in your code makes use of the TLS functionality in App Service, which requires your app
to be in Basic tier or above.
The following C# example loads a public certificate from a relative path in your app:
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
...
var bytes = File.ReadAllBytes("~/<relative-path-to-cert-file>");
var cert = new X509Certificate2(bytes);
To see how to load a TLS/SSL certificate from a file in Node.js, PHP, Python, Java, or Ruby, see the documentation
for the respective language or web platform.
NOTE
App Service inject the certificate paths into Windows containers as the following environment variables
WEBSITE_PRIVATE_CERTS_PATH , WEBSITE_INTERMEDIATE_CERTS_PATH , WEBSITE_PUBLIC_CERTS_PATH , and
WEBSITE_ROOT_CERTS_PATH . It's better to reference the certificate path with the environment variables instead of
hardcoding the certificate path, in case the certificate paths change in the future.
In addition, Windows Server Core containers load the certificates into the certificate store automatically, in
LocalMachine\My . To load the certificates, follow the same pattern as Load certificate in Windows apps. For
Windows Nano based containers, use the file paths provided above to Load the certificate directly from file.
The following C# code shows how to load a public certificate in a Linux app.
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
...
var bytes = File.ReadAllBytes("/var/ssl/certs/<thumbprint>.der");
var cert = new X509Certificate2(bytes);
The following C# code shows how to load a private certificate in a Linux app.
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
...
var bytes = File.ReadAllBytes("/var/ssl/private/<thumbprint>.p12");
var cert = new X509Certificate2(bytes);
To see how to load a TLS/SSL certificate from a file in Node.js, PHP, Python, Java, or Ruby, see the documentation
for the respective language or web platform.
More resources
Secure a custom DNS name with a TLS/SSL binding in Azure App Service
Enforce HTTPS
Enforce TLS 1.1/1.2
FAQ : App Service Certificates
Environment variables and app settings reference
Configure TLS mutual authentication for Azure App
Service
5/18/2022 • 8 minutes to read • Edit Online
You can restrict access to your Azure App Service app by enabling different types of authentication for it. One
way to do it is to request a client certificate when the client request is over TLS/SSL and validate the certificate.
This mechanism is called TLS mutual authentication or client certificate authentication. This article shows how to
set up your app to use client certificate authentication.
NOTE
If you access your site over HTTP and not HTTPS, you will not receive any client certificate. So if your application requires
client certificates, you should not allow requests to your application over HTTP.
Check to make sure that your web app is not in the F1 or D1 tier. Your web app's current tier is highlighted by a
dark blue box.
Custom SSL is not supported in the F1 or D1 tier. If you need to scale up, follow the steps in the next section.
Otherwise, close the Scale up page and skip the Scale up your App Service plan section.
Scale up your App Service plan
Select any of the non-free tiers (B1 , B2 , B3 , or any tier in the Production category). For additional options, click
See additional options .
Click Apply .
When you see the following notification, the scale operation is complete.
// Configure the application to client certificate forwarded the frontend load balancer
services.AddCertificateForwarding(options => { options.CertificateHeader = "X-ARR-ClientCert"; });
// Add certificate authentication so when authorization is performed the user will be created from
the certificate
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate();
}
app.UseForwardedHeaders();
app.UseCertificateForwarding();
app.UseHttpsRedirection();
app.UseAuthentication()
app.UseAuthorization();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
namespace ClientCertificateUsageSample
{
public partial class Cert : System.Web.UI.Page
{
public string certHeader = "";
public string errorString = "";
private X509Certificate2 certificate = null;
public string certThumbprint = "";
public string certSubject = "";
public string certIssuer = "";
public string certSignatureAlg = "";
public string certIssueDate = "";
public string certExpiryDate = "";
public bool isValidCert = false;
//
// Read the certificate from the header into an X509Certificate2 object
// Display properties of the certificate on the page
//
protected void Page_Load(object sender, EventArgs e)
{
NameValueCollection headers = base.Request.Headers;
certHeader = headers["X-ARR-ClientCert"];
if (!String.IsNullOrEmpty(certHeader))
{
try
{
byte[] clientCertBytes = Convert.FromBase64String(certHeader);
certificate = new X509Certificate2(clientCertBytes);
certSubject = certificate.Subject;
certIssuer = certificate.Issuer;
certThumbprint = certificate.Thumbprint;
certSignatureAlg = certificate.SignatureAlgorithm.FriendlyName;
certIssueDate = certificate.NotBefore.ToShortDateString() + " " +
certificate.NotBefore.ToShortTimeString();
certExpiryDate = certificate.NotAfter.ToShortDateString() + " " +
certificate.NotAfter.ToShortTimeString();
}
catch (Exception ex)
{
errorString = ex.ToString();
}
finally
{
isValidCert = IsValidClientCertificate();
if (!isValidCert) Response.StatusCode = 403;
else Response.StatusCode = 200;
}
}
else
{
certHeader = "";
}
}
//
// This is a SAMPLE verification routine. Depending on your application logic and security
requirements,
// you should modify this method
//
private bool IsValidClientCertificate()
{
// In this example we will only accept the certificate as a valid certificate if all the
// In this example we will only accept the certificate as a valid certificate if all the
conditions below are met:
// 1. The certificate is not expired and is active for the current time on server.
// 2. The subject name of the certificate has the common name nildevecc
// 3. The issuer name of the certificate has the common name nildevecc and organization name
Microsoft Corp
// 4. The thumbprint of the certificate is 30757A2E831977D8BD9C8496E4C99AB26CB9622B
//
// This example does NOT test that this certificate is chained to a Trusted Root Authority
(or revoked) on the server
// and it allows for self signed certificates
//
return true;
}
}
}
Node.js sample
The following Node.js sample code gets the X-ARR-ClientCert header and uses node-forge to convert the
base64-encoded PEM string into a certificate object and validate it:
import { NextFunction, Request, Response } from 'express';
import { pki, md, asn1 } from 'node-forge';
// Validate issuer
if (incomingCert.issuer.hash.toLowerCase() !== 'abcdef1234567890abcdef1234567890abcdef12') throw
new Error('UNAUTHORIZED');
// Validate subject
if (incomingCert.subject.hash.toLowerCase() !== 'abcdef1234567890abcdef1234567890abcdef12')
throw new Error('UNAUTHORIZED');
next();
} catch (e) {
if (e instanceof Error && e.message === 'UNAUTHORIZED') {
res.status(401).send();
} else {
next(e);
}
}
}
}
Java sample
The following Java class encodes the certificate from X-ARR-ClientCert to an X509Certificate instance.
certificateIsValid() validates that the certificate's thumbprint matches the one given in the constructor and
that certificate has not expired.
import java.io.ByteArrayInputStream;
import java.security.NoSuchAlgorithmException;
import java.security.cert.*;
import java.security.MessageDigest;
import sun.security.provider.X509Factory;
import javax.xml.bind.DatatypeConverter;
import java.util.Base64;
import java.util.Date;
/**
* Constructor.
* @param certificate The certificate from the "X-ARR-ClientCert" HTTP header
* @param thumbprint The thumbprint to check against
* @throws CertificateException If the certificate factory cannot be created.
*/
public ClientCertValidator(String certificate, String thumbprint) throws CertificateException {
certificate = certificate
.replaceAll(X509Factory.BEGIN_CERT, "")
.replaceAll(X509Factory.END_CERT, "");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
byte [] base64Bytes = Base64.getDecoder().decode(certificate);
X509Certificate X509cert = (X509Certificate) cf.generateCertificate(new
ByteArrayInputStream(base64Bytes));
this.setCertificate(X509cert);
this.setThumbprint(thumbprint);
}
/**
* Check that the certificate's thumbprint matches the one given in the constructor, and that the
* certificate has not expired.
* @return True if the certificate's thumbprint matches and has not expired. False otherwise.
*/
public boolean certificateIsValid() throws NoSuchAlgorithmException, CertificateEncodingException {
return certificateHasNotExpired() && thumbprintIsValid();
}
/**
* Check certificate's timestamp.
* @return Returns true if the certificate has not expired. Returns false if it has expired.
*/
private boolean certificateHasNotExpired() {
Date currentTime = new java.util.Date();
try {
this.getCertificate().checkValidity(currentTime);
} catch (CertificateExpiredException | CertificateNotYetValidException e) {
return false;
}
return true;
}
/**
* Check the certificate's thumbprint matches the given one.
* @return Returns true if the thumbprints match. False otherwise.
*/
private boolean thumbprintIsValid() throws NoSuchAlgorithmException, CertificateEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] der = this.getCertificate().getEncoded();
md.update(der);
byte[] digest = md.digest();
String digestHex = DatatypeConverter.printHexBinary(digest);
return digestHex.toLowerCase().equals(this.getThumbprint().toLowerCase());
}
Encrypting your web app's application data at rest requires an Azure Storage Account and an Azure Key Vault.
These services are used when you run your app from a deployment package.
Azure Storage provides encryption at rest. You can use system-provided keys or your own, customer-
managed keys. This is where your application data is stored when it's not running in a web app in Azure.
Running from a deployment package is a deployment feature of App Service. It allows you to deploy your
site content from an Azure Storage Account using a Shared Access Signature (SAS) URL.
Key Vault references are a security feature of App Service. It allows you to import secrets at runtime as
application settings. Use this to encrypt the SAS URL of your Azure Storage Account.
NOTE
Save this SAS URL, this is used later to enable secure access of the deployment package at runtime.
Adding this application setting causes your web app to restart. After the app has restarted, browse to it and
make sure that the app has started correctly using the deployment package. If the application didn't start
correctly, see the Run from package troubleshooting guide.
Encrypt the application setting using Key Vault references
Now you can replace the value of the WEBSITE_RUN_FROM_PACKAGE application setting with a Key Vault reference to
the SAS-encoded URL. This keeps the SAS URL encrypted in Key Vault, which provides an extra layer of security.
1. Use the following az keyvault create command to create a Key Vault instance.
2. Follow these instructions to grant your app access to your key vault:
3. Use the following az keyvault secret set command to add your external URL as a secret in your key
vault:
az keyvault secret set --vault-name "Contoso-Vault" --name "external-url" --value "<SAS-URL>"
4. Use the following az webapp config appsettings set command to create the WEBSITE_RUN_FROM_PACKAGE
application setting with the value as a Key Vault reference to the external URL:
The <secret-version> will be in the output of the previous az keyvault secret set command.
Updating this application setting causes your web app to restart. After the app has restarted, browse to it make
sure it has started correctly using the Key Vault reference.
3. Update the key vault reference in your application setting to the new secret version:
The <secret-version> will be in the output of the previous az keyvault secret set command.
Summary
Your application files are now encrypted at rest in your storage account. When your web app starts, it retrieves
the SAS URL from your key vault. Finally, the web app loads the application files from the storage account.
If you need to revoke the web app's access to your storage account, you can either revoke access to the key vault
or rotate the storage account keys, which invalidates the SAS URL.
Next steps
Key Vault references for App Service
Azure Storage encryption for data at rest
Scale up an app in Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
This article shows you how to scale your app in Azure App Service. There are two workflows for scaling, scale up
and scale out, and this article explains the scale up workflow.
Scale up: Get more CPU, memory, disk space, and extra features like dedicated virtual machines (VMs),
custom domains and certificates, staging slots, autoscaling, and more. You scale up by changing the pricing
tier of the App Service plan that your app belongs to.
Scale out: Increase the number of VM instances that run your app. You can scale out to as many as 30
instances, depending on your pricing tier. App Service Environments in Isolated tier further increases your
scale-out count to 100 instances. For more information about scaling out, see Scale instance count manually
or automatically. There, you find out how to use autoscaling, which is to scale instance count automatically
based on predefined rules and schedules.
The scale settings take only seconds to apply and affect all apps in your App Service plan. They don't require you
to change your code or redeploy your application.
For information about the pricing and features of individual App Service plans, see App Service Pricing Details.
NOTE
Before you switch an App Service plan from the Free tier, you must first remove the spending limits in place for your
Azure subscription. To view or change options for your Microsoft Azure App Service subscription, see Microsoft Azure
Subscriptions.
2. In the Summar y part of the Resource group page, select a resource that you want to scale. The
following screenshot shows a SQL Database resource.
To scale up the related resource, see the documentation for the specific resource type. For example, to
scale up a single SQL Database, see Scale single database resources in Azure SQL Database. To scale up a
Azure Database for MySQL resource, see Scale MySQL resources.
More resources
Scale instance count manually or automatically
Configure PremiumV3 tier for App Service
Tutorial: Run a load test to identify performance bottlenecks in a web app
Configure PremiumV3 tier for Azure App Service
5/18/2022 • 4 minutes to read • Edit Online
The new PremiumV3 pricing tier gives you faster processors, SSD storage, and quadruple the memory-to-core
ratio of the existing pricing tiers (double the PremiumV2 tier). With the performance advantage, you could save
money by running your apps on fewer instances. In this article, you learn how to create an app in PremiumV3
tier or scale up an app to PremiumV3 tier.
Prerequisites
To scale-up an app to PremiumV3 , you need to have an Azure App Service app that runs in a pricing tier lower
than PremiumV3 , and the app must be running in an App Service deployment that supports PremiumV3.
PremiumV3 availability
The PremiumV3 tier is available for both native and custom containers, including both Windows containers
and Linux containers.
NOTE
Any Windows containers running in the Premium Container tier during the preview period continue to function as is,
but the Premium Container tier will continue to remain in preview. The PremiumV3 tier is the official replacement for
the Premium Container tier.
PremiumV3 is available in some Azure regions and availability in additional regions is being added continually.
To see if it's available in your region, run the following Azure CLI command in the Azure Cloud Shell:
If your operation finishes successfully, your app's overview page shows that it's now in a PremiumV3 tier.
If you get an error
Some App Service plans can't scale up to the PremiumV3 tier if the underlying App Service deployment doesn’t
support PremiumV3. See Scale up from an unsupported resource group and region combination for more
details.
In the Clone app page, you can create an App Service plan using PremiumV3 in the region you want,
and specify the app settings and configuration that you want to clone.
Azure PowerShell
NOTE
This article uses the Azure Az PowerShell module, which is the recommended PowerShell module for interacting with
Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az
PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
The following command creates an App Service plan in P1V3. The options for -WorkerSize are Small, Medium,
and Large.
More resources
Scale up an app in Azure
Scale instance count manually or automatically
Tutorial: Run a load test to identify performance bottlenecks in a web app
Get started with Autoscale in Azure
5/18/2022 • 5 minutes to read • Edit Online
This article describes how to set up your Autoscale settings for your resource in the Microsoft Azure portal.
Azure Monitor autoscale applies only to Virtual Machine scale sets, Cloud Services, App Service - Web Apps, and
API Management services.
3. Click Autoscale to view all the resources for which Autoscale is applicable, along with their current
Autoscale status.
You can use the filter pane at the top to scope down the list to select resources in a specific resource group,
specific resource types, or a specific resource.
For each resource, you will find the current instance count and the Autoscale status. The Autoscale status can be:
Not configured : You have not enabled Autoscale yet for this resource.
Enabled : You have enabled Autoscale for this resource.
Disabled : You have disabled Autoscale for this resource.
Additionally, you can reach the scaling page by clicking on All Resources on the home page and filter to the
resource you're interested in scaling.
Once you've selected the resource that you're interested in, select the Scaling tab to configure autoscaling rules.
3. Provide a name for the scale setting, and then click Add a rule . This opens as a context pane on the right
side. By default, this sets the option to scale your instance count by 1 if the CPU percentage of the
resource exceeds 70 percent. Leave it at its default values and click Add .
4. You've now created your first scale rule. Note that the UX recommends best practices and states that "It is
recommended to have at least one scale in rule." To do so:
a. Click Add a rule .
b. Set Operator to Less than .
c. Set Threshold to 20 .
d. Set Operation to Decrease count by .
You should now have a scale setting that scales out/scales in based on CPU usage.
5. Click Save .
Congratulations! You've now successfully created your first scale setting to autoscale your web app based on
CPU usage.
NOTE
The same steps are applicable to get started with a Virtual Machine Scale Set or cloud service role.
Other considerations
Scale based on a schedule
In addition to scale based on CPU, you can set your scale differently for specific days of the week.
1. Click Add a scale condition .
2. Setting the scale mode and the rules is the same as the default condition.
3. Select Repeat specific days for the schedule.
4. Select the days and the start/end time for when the scale condition should be applied.
Scale differently on specific dates
In addition to scale based on CPU, you can set your scale differently for specific dates.
1. Click Add a scale condition .
2. Setting the scale mode and the rules is the same as the default condition.
3. Select Specify star t/end dates for the schedule.
4. Select the start/end dates and the start/end time for when the scale condition should be applied.
You can make changes in JSON directly, if required. These changes will be reflected after you save them.
Cool-down period effects
Autoscale uses a cool-down period to prevent "flapping", which is the rapid, repetitive up and down scaling of
instances. For more information, see Autoscale evaluation steps. Other valuable information on flapping and
understanding how to monitor the autoscale engine can be found in Autoscale Best Practices and
Troubleshooting autoscale respectively.
Next steps
Create an Activity Log Alert to monitor all Autoscale engine operations on your subscription
Create an Activity Log Alert to monitor all failed Autoscale scale-in/scale-out operations on your subscription
High-density hosting on Azure App Service using
per-app scaling
5/18/2022 • 3 minutes to read • Edit Online
NOTE
This article uses the Azure Az PowerShell module, which is the recommended PowerShell module for interacting with
Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az
PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
When using App Service, you can scale your apps by scaling the App Service plan they run on. When multiple
apps are running in the same App Service plan, each scaled-out instance runs all the apps in the plan.
Per-app scaling can be enabled at the App Service plan level to allow for scaling an app independently from the
App Service plan that hosts it. This way, an App Service plan can be scaled to 10 instances, but an app can be set
to use only five.
NOTE
Per-app scaling is available only for Standard , Premium , Premium V2 , Premium V3 , and Isolated pricing tiers.
Apps are allocated to available App Service plan using a best effort approach for an even distribution across
instances. While an even distribution is not guaranteed, the platform will make sure that two instances of the
same app will not be hosted on the same App Service plan instance.
The platform does not rely on metrics to decide on worker allocation. Applications are rebalanced only when
instances are added or removed from the App Service plan.
Enable per-app scaling with an existing App Service Plan by passing in the -PerSiteScaling $true parameter to
the Set-AzAppServicePlan cmdlet.
# Enable per-app scaling for the App Service Plan using the "PerSiteScaling" parameter.
Set-AzAppServicePlan -ResourceGroupName $ResourceGroup `
-Name $AppServicePlan -PerSiteScaling $true
At the app level, configure the number of instances the app can use in the App Service plan.
In the example below, the app is limited to two instances regardless of how many instances the underlying app
service plan scales out to.
# Get the app we want to configure to use "PerSiteScaling"
$newapp = Get-AzWebApp -ResourceGroupName $ResourceGroup -Name $webapp
IMPORTANT
$newapp.SiteConfig.NumberOfWorkers is different from $newapp.MaxNumberOfWorkers . Per-app scaling uses
$newapp.SiteConfig.NumberOfWorkers to determine the scale characteristics of the app.
Next steps
Azure App Service plans in-depth overview
Introduction to App Service Environment
Tutorial: Run a load test to identify performance bottlenecks in a web app
Monitoring App Service
5/18/2022 • 4 minutes to read • Edit Online
When you have critical applications and business processes relying on Azure resources, you want to monitor
those resources for their availability, performance, and operation. This article describes the monitoring data
generated by App Service and shipped to Azure Monitor. You can also use built-in diagnostics to monitor
resources to assist with debugging an App Service app. If you're unfamiliar with the features of Azure Monitor
common to all Azure services, read Monitoring Azure resources with Azure Monitor.
Monitoring data
App Service collects the same kinds of monitoring data as other Azure resources that are described in
Monitoring data from Azure resources.
See Monitoring App Service data reference for detailed information on App Service metrics and logs.
App Service also provides built-in diagnostics to assist with debugging apps. See Enable diagnostics logging for
more information on enabling the built-in logs. To monitor App Service instances, see Monitor App Service
instances using Health check.
Application Insights
Application Insights monitors the availability, performance, and usage of your web applications. It leverages the
powerful data analysis platform in Azure Monitor to provide you with deep insights into your application's
operations. It enables you to diagnose errors without waiting for a user to report them. Application Insights
includes connection points to a variety of development tools and integrates with Visual Studio to support your
DevOps processes. Learn more about Application Insights in the Application Monitoring for App Service
Overview.
Analyzing metrics
You can analyze metrics for App Service with metrics from other Azure services using metrics explorer by
opening Metrics from the Azure Monitor menu. See Getting started with Azure Metrics Explorer for details on
using this tool.
For a list of platform metrics collected for App Service, see Monitoring App Service data reference metrics
For reference, you can see a list of all resource metrics supported in Azure Monitor.
Analyzing logs
Data in Azure Monitor Logs is stored in tables where each table has its own set of unique properties.
All resource logs in Azure Monitor have the same fields followed by service-specific fields. The common schema
is outlined in Azure Monitor resource log schema.
The Activity log is a type of platform log that provides insight into subscription-level events. You can view it
independently or route to Azure Monitor Logs. Routing to Azure Monitor Logs gives the benefit of using Log
Analytics to run complex queries.
For a list of types of resource logs collected for App Service, see Monitoring App Service data reference
For a list of queryable tables used by Azure Monitor Logs and Log Analytics, see Monitoring App Service data
reference.
Sample Kusto queries
IMPORTANT
When you select Logs from the App Service menu, Log Analytics is opened with the query scope set to the current
resource. This means that log queries will only include data from that resource. If you want to run a query that includes
data from other [resource] or data from other Azure services, select Logs from the Azure Monitor menu. See Log query
scope and time range in Azure Monitor Log Analytics for details.
The following sample query can help you monitor app logs using AppServiceAppLogs :
AppServiceAppLogs
| project CustomLevel, _ResourceId
| summarize count() by CustomLevel, _ResourceId
The following sample query can help you monitor HTTP logs using AppServiceHTTPLogs where the
HTTP response code is 500 or higher:
AppServiceHTTPLogs
//| where ResourceId = "MyResourceId" // Uncomment to get results for a specific resource Id when querying
over a group of Apps
| where ScStatus >= 500
| reduce by strcat(CsMethod, ':\\', CsUriStem)
The following sample query can help you monitor HTTP 500 errors by joining AppServiceConsoleLogs and
AppserviceHTTPLogs :
See Azure Monitor queries for App Service for more sample queries.
Alerts
Azure Monitor alerts proactively notify you when important conditions are found in your monitoring data. They
allow you to identify and address issues in your system before your customers notice them. You can set alerts
on metrics, logs, and the activity log.
If you're running an application on App Service Azure Monitor Application Insights offers more types of alerts.
The following table lists common and recommended alert rules for App Service.
Metric HTTP Server Errors When HTTP 5xx errors exceed a set
value
Activity Log Create or Update Web App When app is created or updated
Next steps
See Monitoring App Service data reference for a reference of metrics, logs, and other important values
created by App Service.
See Monitoring Azure resources with Azure Monitor for details on monitoring Azure resources.
Monitor apps in Azure App Service
5/18/2022 • 7 minutes to read • Edit Online
Azure App Service provides built-in monitoring functionality for web apps, mobile, and API apps in the Azure
portal.
In the Azure portal, you can review quotas and metrics for an app and App Service plan, and set up alerts and
autoscaling rules based metrics.
Understand quotas
Apps that are hosted in App Service are subject to certain limits on the resources they can use. The limits are
defined by the App Service plan that's associated with the app.
NOTE
App Service Free and Shared (preview) service plans are base tiers that run on the same Azure virtual machines as other
App Service apps. Some apps might belong to other customers. These tiers are intended to be used only for development
and testing purposes.
If the app is hosted in a Free or Shared plan, the limits on the resources that the app can use are defined by
quotas.
If the app is hosted in a Basic, Standard, or Premium plan, the limits on the resources that they can use are set by
the size (Small, Medium, Large) and instance count (1, 2, 3, and so on) of the App Service plan.
Quotas for Free or Shared apps are:
CPU (Shor t) The amount of CPU allowed for this app in a 5-minute
interval. This quota resets every five minutes.
CPU (Day) The total amount of CPU allowed for this app in a day. This
quota resets every 24 hours at midnight UTC.
The only quota applicable to apps that are hosted in Basic, Standard, and Premium is Filesystem.
For more information about the specific quotas, limits, and features available to the various App Service SKUs,
see Azure Subscription service limits.
Quota enforcement
If an app exceeds the CPU (short), CPU (Day), or bandwidth quota, the app is stopped until the quota resets.
During this time, all incoming requests result in an HTTP 403 error.
If the app Memory quota is exceeded, the app is stopped temporarily.
If the Filesystem quota is exceeded, any write operation fails. Write operation failures include any writes to logs.
You can increase or remove quotas from your app by upgrading your App Service plan.
Understand metrics
NOTE
File System Usage is now available globally for apps hosted in multi-tenants and App Service Environment.
IMPORTANT
Average Response Time will be deprecated to avoid confusion with metric aggregations. Use Response Time as a
replacement.
NOTE
Metrics for an app include the requests to the app's SCM site(Kudu). This includes requests to view the site's logstream
using Kudu. Logstream requests may span several minutes, which will affect the Request Time metrics. Users should be
aware of this relationship when using these metrics with autoscale logic.
Metrics provide information about the app or the App Service plan's behavior.
For an app, the available metrics are:
Response Time The time taken for the app to serve requests, in seconds.
Average Response Time (deprecated) The average time taken for the app to serve requests, in
seconds.
M ET RIC DESC RIP T IO N
Average memor y working set The average amount of memory used by the app, in
megabytes (MiB).
CPU Time The amount of CPU consumed by the app, in seconds. For
more information about this metric, see CPU time vs CPU
percentage.
Gen 0 Garbage Collections The number of times the generation 0 objects are garbage
collected since the start of the app process. Higher
generation GCs include all lower generation GCs.
Gen 1 Garbage Collections The number of times the generation 1 objects are garbage
collected since the start of the app process. Higher
generation GCs include all lower generation GCs.
Gen 2 Garbage Collections The number of times the generation 2 objects are garbage
collected since the start of the app process.
Handle Count The total number of handles currently open by the app
process.
Health Check Status The average health status across the application's instances
in the App Service Plan.
Http 401 The count of requests resulting in HTTP 401 status code.
Http 403 The count of requests resulting in HTTP 403 status code.
Http 404 The count of requests resulting in HTTP 404 status code.
Http 406 The count of requests resulting in HTTP 406 status code.
M ET RIC DESC RIP T IO N
Http Ser ver Errors The count of requests resulting in an HTTP status code ≥
500 but < 600.
IO Other Bytes Per Second The rate at which the app process is issuing bytes to I/O
operations that don't involve data, such as control
operations.
IO Other Operations Per Second The rate at which the app process is issuing I/O operations
that aren't read or write operations.
IO Read Bytes Per Second The rate at which the app process is reading bytes from I/O
operations.
IO Read Operations Per Second The rate at which the app process is issuing read I/O
operations.
IO Write Bytes Per Second The rate at which the app process is writing bytes to I/O
operations.
IO Write Operations Per Second The rate at which the app process is issuing write I/O
operations.
Memor y working set The current amount of memory used by the app, in MiB.
Private Bytes Private Bytes is the current size, in bytes, of memory that
the app process has allocated that can't be shared with other
processes.
Requests In Application Queue The number of requests in the application request queue.
Thread Count The number of threads currently active in the app process.
Total App Domains Unloaded The total number of AppDomains unloaded since the start
of the application.
NOTE
App Service plan metrics are available only for plans in Basic, Standard, and Premium tiers.
M ET RIC DESC RIP T IO N
CPU Percentage The average CPU used across all instances of the plan.
Memor y Percentage The average memory used across all instances of the plan.
Data Out The average outgoing bandwidth used across all instances of
the plan.
Disk Queue Length The average number of both read and write requests that
were queued on storage. A high disk queue length is an
indication of an app that might be slowing down because of
excessive disk I/O.
Http Queue Length The average number of HTTP requests that had to sit on the
queue before being fulfilled. A high or increasing HTTP
Queue length is a symptom of a plan under heavy load.
You can access metrics directly from the resource Over view page. Here you'll see charts representing some of
the apps metrics.
Clicking on any of those charts will take you to the metrics view where you can create custom charts, query
different metrics and much more.
To learn more about metrics, see Monitor service metrics.
Overview
Azure provides built-in diagnostics to assist with debugging an App Service app. In this article, you learn how to
enable diagnostic logging and add instrumentation to your application, as well as how to access the information
logged by Azure.
This article uses the Azure portal and Azure CLI to work with diagnostic logs. For information on working with
diagnostic logs using Visual Studio, see Troubleshooting Azure in Visual Studio.
NOTE
In addition to the logging instructions in this article, there's new, integrated logging capability with Azure Monitoring.
You'll find more on this capability in the Send logs to Azure Monitor section.
Application logging Windows, Linux App Service file system Logs messages generated
and/or Azure Storage blobs by your application code.
The messages can be
generated by the web
framework you choose, or
from your application code
directly using the standard
logging pattern of your
language. Each message is
assigned one of the
following categories:
Critical, Error , Warning ,
Info , Debug , and Trace .
You can select how verbose
you want the logging to be
by setting the severity level
when you enable
application logging.
Web server logging Windows App Service file system or Raw HTTP request data in
Azure Storage blobs the W3C extended log file
format. Each log message
includes data such as the
HTTP method, resource URI,
client IP, client port, user
agent, response code, and
so on.
TYPE P L AT F O RM LO C AT IO N DESC RIP T IO N
Detailed Error Messages Windows App Service file system Copies of the .htm error
pages that would have
been sent to the client
browser. For security
reasons, detailed error
pages shouldn't be sent to
clients in production, but
App Service can save the
error page each time an
application error occurs that
has HTTP code 400 or
greater. The page may
contain information that
can help determine why the
server returns the error
code.
Failed request tracing Windows App Service file system Detailed tracing information
on failed requests, including
a trace of the IIS
components used to
process the request and the
time taken in each
component. It's useful if you
want to improve site
performance or isolate a
specific HTTP error. One
folder is generated for each
failed request, which
contains the XML log file,
and the XSL stylesheet to
view the log file with.
Deployment logging Windows, Linux App Service file system Logs for when you publish
content to an app.
Deployment logging
happens automatically and
there are no configurable
settings for deployment
logging. It helps you
determine why a
deployment failed. For
example, if you use a
custom deployment script,
you might use deployment
logging to determine why
the script is failing.
NOTE
App Service provides a dedicated, interactive diagnostics tool to help you troubleshoot your application. For more
information, see Azure App Service diagnostics overview.
In addition, you can use other Azure services to improve the logging and monitoring capabilities of your app, such as
Azure Monitor.
NOTE
If your Azure Storage account is secured by firewall rules, see Networking considerations.
NOTE
Currently only .NET application logs can be written to the blob storage. Java, PHP, Node.js, Python application logs can
only be stored on the App Service file system (without code modifications to write logs to external storage).
Also, if you regenerate your storage account's access keys, you must reset the respective logging configuration to use the
updated access keys. To do this:
1. In the Configure tab, set the respective logging feature to Off . Save your setting.
2. Enable logging to the storage account blob again. Save your setting.
Select the Level , or the level of details to log. The following table shows the log categories included in each
level:
Disabled None
NOTE
If you write logs to blobs, the retention policy no longer applies if you delete the app but keep the logs in the blobs. For
more information, see Costs that might accrue after resource deletion.
NOTE
If your Azure Storage account is secured by firewall rules, see Networking considerations.
In Retention Period (Days) , set the number of days the logs should be retained.
NOTE
If you regenerate your storage account's access keys, you must reset the respective logging configuration to use the
updated keys. To do this:
1. In the Configure tab, set the respective logging feature to Off . Save your setting.
2. Enable logging to the storage account blob again. Save your setting.
NOTE
If you write logs to blobs, the retention policy no longer applies if you delete the app but keep the logs in the blobs. For
more information, see Costs that might accrue after resource deletion.
Stream logs
Before you stream logs in real time, enable the log type that you want. Any information written to files ending in
.txt, .log, or .htm that are stored in the /LogFiles directory (d:/home/logfiles) is streamed by App Service.
NOTE
Some types of logging buffer write to the log file, which can result in out of order events in the stream. For example, an
application log entry that occurs when a user visits a page may be displayed in the stream before the corresponding HTTP
log entry for the page request.
In Azure portal
To stream logs in the Azure portal, navigate to your app and select Log stream .
In Cloud Shell
To stream logs live in Cloud Shell, use the following command:
IMPORTANT
This command may not work with web apps hosted in a Linux app service plan.
To filter specific log types, such as HTTP, use the --Provider parameter. For example:
In local terminal
To stream logs in the local console, install Azure CLI and sign in to your account. Once signed in, followed the
instructions for Cloud Shell
Failed Request Traces /LogFiles/W3SVC#########/ Contains XML files, and an XSL file. You
can view the formatted XML files in the
browser.
Detailed Error Logs /LogFiles/DetailedErrors/ Contains HTM error files. You can view
the HTM files in the browser.
Another way to view the failed request
traces is to navigate to your app page
in the portal. From the left menu,
select Diagnose and solve
problems , then search for Failed
Request Tracing Logs , then click the
icon to browse and view the trace you
want.
Web Ser ver Logs /LogFiles/http/RawLogs/ Contains text files formatted using the
W3C extended log file format. This
information can be read using a text
editor or a utility like Log Parser.
App Service doesn't support the
s-computername , s-ip , or
cs-version fields.
Deployment logs /LogFiles/Git/ and /deployments/ Contain logs generated by the internal
deployment processes, as well as logs
for Git deployments.
W IN DO W S L IN UX
LO G T Y P E W IN DO W S C O N TA IN ER L IN UX C O N TA IN ER DESC RIP T IO N
AppServiceAppL ASP.NET & ASP.NET & Java SE & Java SE & Tomcat Application logs
ogs Tomcat 1 Tomcat 1 Tomcat Blessed Blessed Images 2
Images 2
1 For Tomcat apps, add TOMCAT_USE_STARTUP_BAT to the app settings and set it to false or 0 . Need to be on the
latest Tomcat version and use java.util.logging.
2 For Java SE apps, add WEBSITE_AZMON_PREVIEW_ENABLED to the app settings and set it to true or to 1 .
3 AppServiceAntivirusScanAuditLogs log type is still currently in Preview
Networking considerations
If you secure your Azure Storage account by only allowing selected networks, it can receive logs from App
Service only if both of the following are true:
The Azure Storage account is in a different Azure region from the App Service app.
All outbound addresses of the App Service app are added to the Storage account's firewall rules. To find the
outbound addresses for your app, see Find outbound IPs.
Next steps
Query logs with Azure Monitor
How to Monitor Azure App Service
Troubleshooting Azure App Service in Visual Studio
Analyze app Logs in HDInsight
Tutorial: Run a load test to identify performance bottlenecks in a web app
Get resource events in Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
Azure App Service provides built-in tools to monitor the status and health of your resources. Resource events
help you understand any changes that were made to your underlying web app resources and take action as
necessary. Event examples include: scaling of instances, updates to application settings, restarting of the web
app, and many more. In this article, you'll learn how to view Azure Activity Logs and enable Event Grid to
monitor App Service resource events.
Next steps
Query logs with Azure Monitor
How to Monitor Azure App Service
Troubleshooting Azure App Service in Visual Studio
Analyze app Logs in HDInsight
Monitor App Service instances using Health check
5/18/2022 • 8 minutes to read • Edit Online
This article uses Health check in the Azure portal to monitor App Service instances. Health check increases your
application's availability by re-routing requests away from unhealthy instances, and replacing instances if they
remain unhealthy. Your App Service plan should be scaled to two or more instances to fully utilize Health check.
The Health check path should check critical components of your application. For example, if your application
depends on a database and a messaging system, the Health check endpoint should connect to those
components. If the application cannot connect to a critical component, then the path should return a 500-level
response code to indicate the app is unhealthy.
NOTE
Health check doesn't follow 302 redirects.
At most one instance will be replaced per hour, with a maximum of three instances per day per App Service Plan.
If your health check is giving the status Waiting for health check response then the check is likely failing due to
an HTTP status code of 307, which can happen if you have HTTPS redirect enabled but have HTTPS Only disabled.
Enable Health Check
To enable Health check, browse to the Azure portal and select your App Service app.
Under Monitoring , select Health check .
Select Enable and provide a valid URL path on your application, such as /health or /api/health .
Click Save .
Cau t i on
Health check configuration changes restart your app. To minimize impact to production apps, we recommend
configuring staging slots and swapping to production.
Configuration
In addition to configuring the Health check options, you can also configure the following app settings:
0 - 100
WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT By default, no more than half of the
instances will be excluded from the
load balancer at one time to avoid
overwhelming the remaining healthy
instances. For example, if an App
Service Plan is scaled to four instances
and three are unhealthy, two will be
excluded. The other two instances (one
healthy and one unhealthy) will
continue to receive requests. In the
worst-case scenario where all instances
are unhealthy, none will be excluded.
To override this behavior, set app
setting to a value between 0 and
100 . A higher value means more
unhealthy instances will be removed
(default value is 50 ).
.NET
Python
Java
Node.js
using System;
using System.Text;
/// <summary>
/// Method <c>HeaderMatchesEnvVar</c> returns true if <c>headerValue</c> matches
WEBSITE_AUTH_ENCRYPTION_KEY.
/// </summary>
public Boolean HeaderMatchesEnvVar(string headerValue) {
var sha = System.Security.Cryptography.SHA256.Create();
String envVar = Environment.GetEnvironmentVariable("WEBSITE_AUTH_ENCRYPTION_KEY");
String hash = System.Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(envVar)));
return hash == headerValue;
}
NOTE
The x-ms-auth-internal-token header is only available on Windows App Service.
Monitoring
After providing your application's Health check path, you can monitor the health of your site using Azure
Monitor. From the Health check blade in the Portal, click the Metrics in the top toolbar. This will open a new
blade where you can see the site's historical health status and option to create a new alert rule. Health check
metrics will aggregate the successful pings & display failures only when the instance was deemed unhealthy
based on the health check configuration. For more information on monitoring your sites, see the guide on Azure
Monitor.
Limitations
Health check should not be enabled on Premium Functions sites. Due to the rapid scaling of Premium
Functions, the Health check requests can cause unnecessary fluctuations in HTTP traffic. Premium Functions
have their own internal health probes that are used to inform scaling decisions.
Health check can be enabled for Free and Shared App Service Plans so you can have metrics on the site's
health and set up alerts, but because Free and Shared sites cannot scale out, any unhealthy instances will
not be replaced. You should scale up to the Basic tier or higher so you can scale out to 2 or more instances
and utilize the full benefit of Health check. This is recommended for production-facing applications as it will
increase your app's availability and performance.
Next steps
Create an Activity Log Alert to monitor all Autoscale engine operations on your subscription
Create an Activity Log Alert to monitor all failed Autoscale scale-in/scale-out operations on your subscription
Environment variables and app settings reference
Open an SSH session to a Linux container in Azure
App Service
5/18/2022 • 3 minutes to read • Edit Online
Secure Shell (SSH) is commonly used to execute administrative commands remotely from a command-line
terminal. App Service on Linux provides SSH support into the app container.
You can also connect to the container directly from your local development machine using SSH and SFTP.
https://<app-name>.scm.azurewebsites.net/webssh/host
If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. Once
authenticated, you see an in-browser shell, where you can run commands inside your container.
Use SSH support with custom Docker images
See Configure SSH in a custom container.
Using TCP tunneling you can create a network connection between your development machine and Web App
for Containers over an authenticated WebSocket connection. It enables you to open an SSH session with your
container running in App Service from the client of your choice.
To get started, you need to install Azure CLI. To see how it works without installing Azure CLI, open Azure Cloud
Shell.
Open a remote connection to your app using the az webapp create-remote-connection command. Specify
<subscription-id>, <group-name> and <app-name> for your app.
TIP
& at the end of the command is just for convenience if you are using Cloud Shell. It runs the process in the background
so that you can run the next command in the same shell.
NOTE
If this command fails, make sure remote debugging is disabled with the following command:
The command output gives you the information you need to open an SSH session.
Open an SSH session with your container with the client of your choice, using the local port. The following
example uses the default ssh command:
When being prompted, type yes to continue connecting. You are then prompted for the password. Use
Docker! , which was shown to you earlier.
Once you're authenticated, you should see the session welcome screen.
_____
/ _ \ __________ _________ ____
/ /_\ \___ / | \_ __ \_/ __ \
/ | \/ /| | /| | \/\ ___/
\____|__ /_____ \____/ |__| \___ >
\/ \/ \/
A P P S E R V I C E O N L I N U X
0e690efa93e2:~#
Next steps
You can post questions and concerns on the Azure forum.
For more information on Web App for Containers, see:
Introducing remote debugging of Node.js apps on Azure App Service from VS Code
Quickstart: Run a custom container on App Service
Using Ruby in Azure App Service on Linux
Azure App Service Web App for Containers FAQ
Manage an App Service plan in Azure
5/18/2022 • 3 minutes to read • Edit Online
An Azure App Service plan provides the resources that an App Service app needs to run. This guide shows how
to manage an App Service plan.
You can create an empty App Service plan, or you can create a plan as part of app creation.
1. In the Azure portal, select Create a resource .
2. Select New > Web App or another kind of App service app.
3. Configure the Instance Details section before configuring the App Service plan. Settings such as
Publish and Operating Systems can change the available pricing tiers for your App Service plan.
Region determines where your App Service plan is created.
4. In the App Ser vice Plan section, select an existing plan, or create a plan by selecting Create new .
5. When creating a plan, you can select the pricing tier of the new plan. In Sku and size , select Change
size to change the pricing tier.
1. In the Azure portal, search for and select App ser vices and select the app that you want to move.
2. From the left menu, select Change App Ser vice plan .
3. In the App Ser vice plan dropdown, select an existing plan to move the app to. The dropdown shows
only plans that are in the same resource group and geographical region as the current App Service plan.
If no such plan exists, it lets you create a plan by default. You can also create a new plan manually by
selecting Create new .
4. If you create a plan, you can select the pricing tier of the new plan. In Pricing Tier , select the existing tier
to change it.
IMPORTANT
If you're moving an app from a higher-tiered plan to a lower-tiered plan, such as from D1 to F1 , the app may lose
certain capabilities in the target plan. For example, if your app uses TLS/SSL certificates, you might see this error
message:
Cannot update the site with hostname '<app_name>' because its current TLS/SSL configuration 'SNI
based SSL enabled' is not allowed in the target compute mode. Allowed TLS/SSL configuration is
'Disabled'.
IMPORTANT
Cloning has some limitations. You can read about them in Azure App Service App cloning.
Next steps
Scale up an app in Azure
Back up your app in Azure
5/18/2022 • 8 minutes to read • Edit Online
The Backup and Restore feature in Azure App Service lets you easily create app backups manually or on a
schedule. You can configure the backups to be retained up to an indefinite amount of time. You can restore the
app to a snapshot of a previous state by overwriting the existing app or restoring to another app.
For information on restoring an app from backup, see Restore an app in Azure.
NOTE
Each backup is a complete offline copy of your app, not an incremental update.
NOTE
If you see the following message, click it to upgrade your App Service plan before you can proceed with backups.
For more information, see Scale up an app in Azure.
2. In the Backup page, select Backup is not configured. Click here to configure backup for your
app .
3. In the Backup Configuration page, click Storage not configured to configure a storage account.
4. Choose your backup destination by selecting a Storage Account and Container . The storage account
must belong to the same subscription as the app you want to back up. If you wish, you can create a new
storage account or a new container in the respective pages. When you're done, click Select .
5. In the Backup Configuration page that is still left open, you can configure Backup Database , then
select the databases you want to include in the backups (SQL Database or MySQL), then click OK .
NOTE
For a database to appear in this list, its connection string must exist in the Connection strings section of the
Application settings page for your app.
In-app MySQL databases are automatically backed up without any configuration. If you make settings for in-app
MySQL databases manually, such as adding connection strings, the backups may not work correctly.
NOTE
Individual databases in the backup can be 4GB max but the total max size of the backup is 10GB
\site\wwwroot\Images\brand.png
\site\wwwroot\Images\2014
\site\wwwroot\Images\2013
Upload _backup.filter file to the D:\home\site\wwwroot\ directory of your site using ftp or any other method. If
you wish, you can create the file directly using Kudu DebugConsole and insert the content there.
Run backups the same way you would normally do it, manually or automatically. Now, any files and folders that
are specified in _backup.filter is excluded from the future backups scheduled or manually initiated.
NOTE
You restore partial backups of your site the same way you would restore a regular backup. The restore process does the
right thing.
When a full backup is restored, all content on the site is replaced with whatever is in the backup. If a file is on the site, but
not in the backup it gets deleted. But when a partial backup is restored, any content that is located in one of the
restricted directories, or any restricted file, is left as is.
WARNING
Altering any of the files in your websitebackups container can cause the backup to become invalid and therefore non-
restorable.
Troubleshooting
The Backups page shows you the status of each backup. If you click on a failed backup, you can get log details
regarding the failure. Use the following table to help you troubleshoot your backup. If the failure isn't
documented in the table, open a support ticket.
ERRO R F IX
Storage access failed. Delete backup schedule and reconfigure it. Or, reconfigure
the backup storage.
The website + database size exceeds the {0} GB limit for Exclude some files from the backup, or remove the database
backups. Your content size is {1} GB. portion of the backup and use externally offered backups
instead.
Error occurred while connecting to the database {0} on Update database connection string.
server {1}: Authentication to host '{1}' for user '<username>'
using method 'mysql_native_password' failed with message:
Unknown database '<db-name>'
Cannot resolve {0}. {1} (CannotResolveStorageAccount) Delete the backup schedule and reconfigure it.
Login failed for user '{0}'. Update the database connection string.
Create Database copy of {0} ({1}) threw an exception. Could Use an administrative user in the connection string.
not create Database copy.
The server principal "<name>" is not able to access the Use an administrative user in the connection string.
database "master" under the current security context.
Cannot open database "master" requested by the login. The
login failed. Login failed for user '<name>'.
A network-related or instance-specific error occurred while Check that the connection string is valid. Allow the app's
establishing a connection to SQL Server. The server was not outbound IPs in the database server settings.
found or was not accessible. Verify that the instance name is
correct and that SQL Server is configured to allow remote
connections. (provider: Named Pipes Provider, error: 40 -
Could not open a connection to SQL Server).
Cannot open server "<name>" requested by the login. The Check that the connection string is valid.
login failed.
Missing mandatory parameters for valid Shared Access Delete the backup schedule and reconfigure it.
Signature.
SSL connection is required. Please specify SSL options and Use the built-in backup feature in Azure MySQL or Azure
retry. when trying to connect. Postgressql instead.
Next Steps
For information on restoring an app from a backup, see Restore an app in Azure.
Restore an app in Azure
5/18/2022 • 2 minutes to read • Edit Online
This article shows you how to restore an app in Azure App Service that you have previously backed up (see Back
up your app in Azure). You can restore your app with its linked databases on-demand to a previous state, or
create a new app based on one of your original app's backups. Azure App Service supports the following
databases for backup and restore:
SQL Database
Azure Database for MySQL
Azure Database for PostgreSQL
MySQL in-app
Restoring from backups is available to apps running in Standard and Premium tier. For information about
scaling up your app, see Scale up an app in Azure. Premium tier allows a greater number of daily backups to be
performed than Standard tier.
The App backup option shows you all the existing backups of the current app, and you can easily select
one. The Storage option lets you select any backup ZIP file from any existing Azure Storage account and
container in your subscription. If you're trying to restore a backup of another app, use the Storage
option.
3. Then, specify the destination for the app restore in Restore destination .
WARNING
If you choose Over write , all existing data in your current app is erased and overwritten. Before you click OK ,
make sure that it is exactly what you want to do.
WARNING
If the App Service is writing data to the database while you are restoring it, it may result in symptoms such as
violation of PRIMARY KEY and data loss. It is suggested to stop the App Service first before you start to restore
the database.
You can select Existing App to restore the app backup to another app in the same resource group.
Before you use this option, you should have already created another app in your resource group with
mirroring database configuration to the one defined in the app backup. You can also Create a New app to
restore your content to.
4. Click OK .
This article shows you how to restore an app in Azure App Service from a snapshot. You can restore your app to
a previous state, based on one of your app's snapshots. You do not need to enable snapshot backups; the
platform automatically saves a hourly snapshot of each app's content and configuration for data recovery
purposes. Hourly snapshots for the last 30 days are available. The retention period and snapshot frequency are
not configurable.
Restoring from snapshots is available to apps running in one of the Standard or Premium tiers. For
information about scaling up your app, see Scale up an app in Azure.
NOTE
Snapshot restore is not available for:
App Service environments (Isolated tier)
Azure Functions in the Consumption or Elastic Premium pricing plans.
Snapshot restore is available in preview for Azure Functions in dedicated (App Service) Standard or Premium tiers.
Snapshots vs Backups
Snapshots are incremental shadow copies and offer several advantages over standard backups:
No file copy errors due to file locks.
Higher snapshot size (maximum 30 GB).
Enabled by default in supported pricing tiers and no configuration required.
Restore to a new or existing App Service app or slot in any Azure region.
NOTE
Maximum supported size for snapshot restore is 30GB. Snapshot restore fails if your storage size is greater than 30GB. To
reduce your storage size, consider moving files like logs, images, audios, and videos to Azure Storage, for example.
The following table shows which app configuration is restored:
Native log settings, including the Azure Storage account and Yes
container settings
Authentication No
Managed identities No
Custom domains No
TLS/SSL No
Scale out No
Backup No
Azure portal
Azure CLI
1. On the Settings page of your app in the Azure portal, click Backups to display the Backups page. Then
click Restore under the Snapshot section.
2. In the Restore page, select the snapshot to restore.
3. Specify the destination for the app restore in Restore destination . To restore to a deployment slot,
select Existing app .
NOTE
It's recommended that you restore to a deployment slot and then perform a swap into production. If you choose
Over write , all existing data in your app's current file system is erased and overwritten. Before you click OK , make
sure that it is what you want to do.
5. Click OK .
Azure App Service App Cloning Using PowerShell
5/18/2022 • 5 minutes to read • Edit Online
NOTE
This article uses the Azure Az PowerShell module, which is the recommended PowerShell module for interacting with
Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az
PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
With the release of Microsoft Azure PowerShell version 1.1.0, a new option has been added to New-AzWebApp
that lets you clone an existing App Service app to a newly created app in a different region or in the same
region. This option enables customers to deploy a number of apps across different regions quickly and easily.
App cloning is supported for Standard, Premium, Premium V2, and Isolated app service plans. The new feature
uses the same limitations as App Service Backup feature, see Back up an app in Azure App Service.
To create a new App Service Plan, you can use New-AzAppServicePlan command as in the following example
Using the New-AzWebApp command, you can create the new app in the North Central US region, and tie it to an
existing App Service Plan. Moreover, you can use the same resource group as the source app, or define a new
resource group, as shown in the following command:
To clone an existing app including all associated deployment slots, you need to use the
IncludeSourceWebAppSlots parameter. Note that the IncludeSourceWebAppSlots parameter is only supported for
cloning an entire app including all of its slots. The following PowerShell command demonstrates the use of that
parameter with the New-AzWebApp command:
To clone an existing app within the same region, you need to create a new resource group and a new app service
plan in the same region, and then use the following PowerShell command to clone the app:
Knowing the ASE's name, and the resource group name that the ASE belongs to, you can create the new app in
the existing ASE, as shown in the following command:
The Location parameter is required due to legacy reason, but it is ignored when you create the app in an ASE.
The following command demonstrates creating a clone of the source app to a new app:
After having the traffic manger ID, the following command demonstrates creating a clone of the source app to a
new app while adding them to an existing Traffic Manager profile:
$destapp = New-AzWebApp -ResourceGroupName <Resource group name> -Name dest-webapp -Location "South Central
US" -AppServicePlan DestinationAppServicePlan -SourceWebApp $srcapp -TrafficManagerProfileId $TMProfileID
NOTE
If you are receiving an error that states, "SSL validation on the traffic manager hostname is failing" then we suggest you
use -IgnoreCustomHostNames attribute in the powershell cmdlet while performing the clone operation or else use the
portal.
Current Restrictions
Here are the known restrictions of app cloning:
Auto scale settings are not cloned
Backup schedule settings are not cloned
VNET settings are not cloned
App Insights are not automatically set up on the destination app
Easy Auth settings are not cloned
Kudu Extension are not cloned
TiP rules are not cloned
Database content is not cloned
Outbound IP Addresses changes if cloning to a different scale unit
Not available for Linux Apps
Managed Identities are not cloned
Not available for Function Apps
References
App Service Cloning
Back up an app in Azure App Service
Azure Resource Manager support for Azure Traffic Manager Preview
Introduction to App Service Environment
Using Azure PowerShell with Azure Resource Manager
Restore deleted App Service app Using PowerShell
5/18/2022 • 2 minutes to read • Edit Online
If you happened to accidentally delete your app in Azure App Service, you can restore it using the commands
from the Az PowerShell module.
NOTE
Deleted apps are purged from the system 30 days after the initial deletion. After an app is purged, it can't be
recovered.
Undelete functionality isn't supported for the Consumption plan.
Apps Service apps running in an App Service Environment don't support snapshots. Therefore, undelete functionality
and clone functionality aren't supported for App Service apps running in an App Service Environment.
Once the app you want to restore has been identified, you can restore it using Restore-AzDeletedWebApp .
Restore-AzDeletedWebApp -TargetResourceGroupName <my_rg> -Name <my_app> -TargetAppServicePlanName <my_asp>
NOTE
Deployment slots are not restored as part of your app. If you need to restore a staging slot, use the -Slot <slot-name>
flag.
NOTE
If the app was hosted on and then deleted from an App Service Environment, it can be restored only if the corresponding
App Service Environment still exists.
This article describes how to bring App Service resources back online in a different Azure region during a
disaster that impacts an entire Azure region. When a disaster brings an entire Azure region offline, all App
Service apps hosted in that region are placed in disaster recovery mode. Features are available to help you
restore the app to a different region or recover files from the impacted app.
App Service resources are region-specific and can't be moved across regions. You must restore the app to a new
app in a different region, and then create mirroring configurations or resources for the new app.
Prerequisites
None. Restoring from snapshot usually requires Premium tier, but in disaster recovery mode, it's
automatically enabled for your impacted app, regardless which tier the impacted app is in.
Prepare
Identify all the App Service resources that the impacted app currently uses. For example:
App Service apps
App Service plans
Deployment slots
Custom domains purchased in Azure
TLS/SSL certificates
Azure Virtual Network integration
Hybrid connections.
Managed identities
Backup settings
Certain resources, such as imported certificates or hybrid connections, contain integration with other Azure
services. For information on how to move those resources across regions, see the documentation for the
respective services.
Snapshot (Preview) Select a snapshot. The two most recent snapshots are
available.
Restore destination Existing app Click the note below that says Click
here to change the restore
destination app and select the
target app. In a disaster scenario,
you can only restore the snapshot
to an app in a different Azure
region.
3. Use the FTP client of your choice, connect to the impacted app's FTP host using the hostname and
credentials.
4. Once connected, download the entire /site/wwwroot folder. The following screenshot shows how you
download in FileZilla.
Next steps
Restore an app in Azure from a snapshot
Set up an Azure Arc-enabled Kubernetes cluster to
run App Service, Functions, and Logic Apps
(Preview)
5/18/2022 • 8 minutes to read • Edit Online
If you have an Azure Arc-enabled Kubernetes cluster, you can use it to create an App Service enabled custom
location and deploy web apps, function apps, and logic apps to it.
Azure Arc-enabled Kubernetes lets you make your on-premises or cloud Kubernetes cluster visible to App
Service, Functions, and Logic Apps in Azure. You can create an app and deploy to it just like another Azure
region.
Prerequisites
If you don't have an Azure account, sign up today for a free account.
Because these CLI commands are not yet part of the core CLI set, add them with the following commands.
1. Create a cluster in Azure Kubernetes Service with a public IP address. Replace <group-name> with the
resource group name you want.
bash
PowerShell
aksClusterGroupName="<group-name>" # Name of resource group for the AKS cluster
aksName="${aksClusterGroupName}-aks" # Name of the AKS cluster
resourceLocation="eastus" # "eastus" or "westeurope"
2. Get the kubeconfig file and test your connection to the cluster. By default, the kubeconfig file is saved to
~/.kube/config .
kubectl get ns
3. Create a resource group to contain your Azure Arc resources. Replace <group-name> with the resource
group name you want.
bash
PowerShell
bash
PowerShell
5. Validate the connection with the following command. It should show the provisioningState property as
Succeeded . If not, run the command again after a minute.
bash
PowerShell
workspaceName="$groupName-workspace" # Name of the Log Analytics workspace
2. Run the following commands to get the encoded workspace ID and shared key for an existing Log
Analytics workspace. You need them in the next step.
bash
PowerShell
bash
PowerShell
2. Install the App Service extension to your Azure Arc-connected cluster, with Log Analytics enabled. Again,
while Log Analytics is not required, you can't add it to the extension later, so it's easier to do it now.
bash
PowerShell
az k8s-extension create \
--resource-group $groupName \
--name $extensionName \
--cluster-type connectedClusters \
--cluster-name $clusterName \
--extension-type 'Microsoft.Web.Appservice' \
--release-train stable \
--auto-upgrade-minor-version true \
--scope cluster \
--release-namespace $namespace \
--configuration-settings "Microsoft.CustomLocation.ServiceAccount=default" \
--configuration-settings "appsNamespace=${namespace}" \
--configuration-settings "clusterName=${kubeEnvironmentName}" \
--configuration-settings "keda.enabled=true" \
--configuration-settings "buildService.storageClassName=default" \
--configuration-settings "buildService.storageAccessMode=ReadWriteOnce" \
--configuration-settings "customConfigMap=${namespace}/kube-environment-config" \
--configuration-settings "envoy.annotations.service.beta.kubernetes.io/azure-load-balancer-
resource-group=${aksClusterGroupName}" \
--configuration-settings "logProcessor.appLogs.destination=log-analytics" \
--configuration-protected-settings
"logProcessor.appLogs.logAnalyticsConfig.customerId=${logAnalyticsWorkspaceIdEnc}" \
--configuration-protected-settings
"logProcessor.appLogs.logAnalyticsConfig.sharedKey=${logAnalyticsKeyEnc}"
NOTE
To install the extension without Log Analytics integration, remove the last three --configuration-settings
parameters from the command.
The following table describes the various --configuration-settings parameters when running the
command:
PA RA M ET ER DESC RIP T IO N
buildService.storageClassName The name of the storage class for the build service to
store build artifacts. A value like default specifies a
class named default , and not any class that is marked
as default. Default is a valid storage class for AKS and
AKS HCI but it may not be for other
distrubtions/platforms.
buildService.storageAccessMode The access mode to use with the named storage class
above. Accepts ReadWriteOnce or ReadWriteMany .
PA RA M ET ER DESC RIP T IO N
customConfigMap The name of the config map that will be set by the App
Service Kubernetes environment. Currently, it must be
<namespace>/kube-environment-config , replacing
<namespace> with the value of appsNamespace above.
bash
PowerShell
4. Wait for the extension to fully install before proceeding. You can have your terminal session wait until this
complete by running the following command:
You can use kubectl to see the pods that have been created in your Kubernetes cluster:
You can learn more about these pods and their role in the system from Pods created by the App Service
extension.
Create a custom location
The custom location in Azure is used to assign the App Service Kubernetes environment.
1. Set the following environment variables for the desired name of the custom location and for the ID of the
Azure Arc-connected cluster.
bash
PowerShell
bash
PowerShell
az customlocation create \
--resource-group $groupName \
--name $customLocationName \
--host-resource-id $connectedClusterId \
--namespace $namespace \
--cluster-extension-ids $extensionId
3. Validate that the custom location is successfully created with the following command. The output should
show the provisioningState property as Succeeded . If not, run it again after a minute.
bash
PowerShell
bash
PowerShell
az appservice kube create \
--resource-group $groupName \
--name $kubeEnvironmentName \
--custom-location $customLocationId
2. Validate that the App Service Kubernetes environment is successfully created with the following
command. The output should show the provisioningState property as Succeeded . If not, run it again
after a minute.
Next steps
Quickstart: Create a web app on Azure Arc
Create your first function on Azure Arc
Create your first logic app on Azure Arc
Enable virtual network integration in Azure App
Service
5/18/2022 • 2 minutes to read • Edit Online
Through integrating with an Azure virtual network (VNet) from your Azure App Service app, you can reach
private resources from your app within the virtual network. The VNet integration feature has two variations:
Regional vir tual network integration : Connect to Azure virtual networks in the same region. You must
have a dedicated subnet in the virtual network you're integrating with.
Gateway-required vir tual network integration : When you connect directly to a virtual network in other
regions or to a classic virtual network in the same region, you must use gateway-required virtual network
integration.
This article describes how to set up regional virtual network integration.
Prerequisites
The VNet integration feature requires:
An App Service pricing tier that supports virtual network integration.
A virtual network in the same region with an empty subnet.
The subnet must be delegated to Microsoft.Web/serverFarms. If the delegation isn't done before integration, the
provisioning process will configure this delegation. The subnet must be allocated an IPv4 /28 block (16
addresses). We recommend that you have a minimum of 64 addresses (IPv4 /26 block) to allow for maximum
horizontal scale.
3. The dropdown list contains all the virtual networks in your subscription in the same region. Select an
empty preexisting subnet or create a new subnet.
During the integration, your app is restarted. When integration is finished, you'll see details on the virtual
network you're integrated with.
az webapp vnet-integration add --resource-group <group-name> --name <app-name> --vnet <vnet-name> --subnet
<subnet-name>
NOTE
The command checks if the subnet is delegated to Microsoft.Web/serverFarms and applies the necessary delegation if it
isn't configured. If the subnet was configured, and you don't have permissions to check it, or if the virtual network is in
another subscription, you can use the --skip-delegation-check parameter to bypass the validation.
Next steps
Configure virtual network integration routing
General networking overview
Manage Azure App Service virtual network
integration routing
5/18/2022 • 2 minutes to read • Edit Online
When you configure application routing, you can either route all traffic or only private traffic (also known as
RFC1918 traffic) into your Azure virtual network (VNet). This article describes how to configure application
routing.
Prerequisites
Your app is already integrated using the regional VNet integration feature.
Next steps
Enable virtual network integration
General networking overview
Control outbound traffic with Azure Firewall
5/18/2022 • 5 minutes to read • Edit Online
This article shows you how to lock down the outbound traffic from your App Service app to back-end Azure
resources or other network resources with Azure Firewall. This configuration helps prevent data exfiltration or
the risk of malicious program implantation.
By default, an App Service app can make outbound requests to the public internet (for example, when installing
required Node.js packages from NPM.org.). If your app is integrated with an Azure virtual network, you can
control outbound traffic with network security groups to a limited extent, such as the target IP address, port, and
protocol. Azure Firewall lets you control outbound traffic at a much more granular level and filter traffic based
on real-time threat intelligence from Microsoft Cyber Security. You can centrally create, enforce, and log
application and network connectivity policies across subscriptions and virtual networks (see Azure Firewall
features).
For detailed network concepts and security enhancements in App Service, see Networking features and Zero to
Hero with App Service, Part 6: Securing your web app.
Prerequisites
Enable regional virtual network integration for your app.
Verify that Route All is enabled. This setting is enabled by default, which tells App Service to route all
outbound traffic through the integrated virtual network. If you disable it, only traffic to private IP addresses
will be routed through the virtual network.
If you want to route access to back-end Azure services through Azure Firewall as well, disable all service
endpoints on the App Service subnet in the integrated virtual network. After Azure Firewall is configured,
outbound traffic to Azure Services will be routed through the firewall instead of the service endpoints.
SET T IN G VA L UE
SET T IN G VA L UE
Next hop address The private IP address for the firewall that you copied in
2. Deploy the firewall and get its IP.
13. Select OK .
4. Select Add .
3. Run curl -s <protocol>://<fqdn-address> again with a URL that doesn't match the application rule you
configured. In the following screenshot, you get no response, which indicates that your firewall has
blocked the outbound request from the app.
TIP
Because these outbound requests are going through the firewall, you can capture them in the firewall logs by enabling
diagnostic logging for the firewall (enable the AzureFirewallApplicationRule ).
If you run the curl commands with diagnostic logs enabled, you can find them in the firewall logs.
1. In the Azure portal, navigate to your firewall.
2. From the left navigation, select Logs .
3. Close the welcome message by selecting X .
4. From All Queries, select Firewall Logs > Application rule log data .
5. Click Run . You can see these two access logs in query result.
More resources
Monitor Azure Firewall logs and metrics.
Move an App Service resource to another region
5/18/2022 • 2 minutes to read • Edit Online
This article describes how to move App Service resources to a different Azure region. You might move your
resources to another region for a number of reasons. For example, to take advantage of a new Azure region, to
deploy features or services available in specific regions only, to meet internal policy and governance
requirements, or in response to capacity planning requirements.
App Service resources are region-specific and can't be moved across regions. You must create a copy of your
existing App Service resources in the target region, then move your content over to the new app. If your source
app uses a custom domain, you can migrate it to the new app in the target region when you're finished.
To make copying your app easier, you can clone an individual App Service app into an App Service plan in
another region, but it does have limitations, especially that it doesn't support Linux apps.
Prerequisites
Make sure that the App Service app is in the Azure region from which you want to move.
Make sure that the target region supports App Service and any related service, whose resources you want to
move.
Prepare
Identify all the App Service resources that you're currently using. For example:
App Service apps
App Service plans
Deployment slots
Custom domains purchased in Azure
TLS/SSL certificates
Azure Virtual Network integration
Hybrid connections.
Managed identities
Backup settings
Certain resources, such as imported certificates or hybrid connections, contain integration with other Azure
services. For information on how to move those resources across regions, see the documentation for the
respective services.
Move
1. Create a back up of the source app.
2. Create an app in a new App Service plan, in the target region.
3. Restore the back up in the target app
4. If you use a custom domain, bind it preemptively to the target app with awverify. and enable the domain in
the target app.
5. Configure everything else in your target app to be the same as the source app and verify your configuration.
6. When you're ready for the custom domain to point to the target app, remap the domain name.
Clean up source resources
Delete the source app and App Service plan. An App Service plan in the non-free tier carries a charge, even if no
app is running in it.
Next steps
Azure App Service App Cloning Using PowerShell
Move resources to a new resource group or
subscription
5/18/2022 • 13 minutes to read • Edit Online
This article shows you how to move Azure resources to either another Azure subscription or another resource
group under the same subscription. You can use the Azure portal, Azure PowerShell, Azure CLI, or the REST API
to move resources.
Both the source group and the target group are locked during the move operation. Write and delete operations
are blocked on the resource groups until the move completes. This lock means you can't add, update, or delete
resources in the resource groups. It doesn't mean the resources are frozen. For example, if you move an Azure
SQL logical server, its databases and other dependent resources to a new resource group or subscription,
applications that use the databases experience no downtime. They can still read and write to the databases. The
lock can last for a maximum of four hours, but most moves complete in much less time.
If your move requires setting up new dependent resources, you'll experience an interruption in those services
until they've been reconfigured.
Moving a resource only moves it to a new resource group or subscription. It doesn't change the location of the
resource.
Changed resource ID
When you move a resource, you change its resource ID. The standard format for a resource ID is
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
. When you move a resource to a new resource group or subscription, you change one or more values in that
path.
If you use the resource ID anywhere, you'll need to change that value. For example, if you have a custom
dashboard in the portal that references a resource ID, you'll need to update that value. Look for any scripts or
templates that need to be updated for the new resource ID.
If the tenant IDs for the source and destination subscriptions aren't the same, use the following methods
to reconcile the tenant IDs:
Transfer ownership of an Azure subscription to another account
How to associate or add an Azure subscription to Azure Active Directory
6. The destination subscription must be registered for the resource provider of the resource being moved. If
not, you receive an error stating that the subscription is not registered for a resource type . You
might see this error when moving a resource to a new subscription, but that subscription has never been
used with that resource type.
For PowerShell, use the following commands to get the registration status:
For Azure CLI, use the following commands to get the registration status:
7. The account moving the resources must have at least the following permissions:
Microsoft.Resources/subscriptions/resourceGroups/moveResources/action on the source
resource group.
Microsoft.Resources/subscriptions/resourceGroups/write on the destination resource group.
8. Before moving the resources, check the subscription quotas for the subscription you're moving the
resources to. If moving the resources means the subscription will exceed its limits, you need to review
whether you can request an increase in the quota. For a list of limits and how to request an increase, see
Azure subscription and service limits, quotas, and constraints.
9. For a move across subscriptions, the resource and its dependent resources must be located
in the same resource group and they must be moved together. For example, a VM with managed
disks would require the VM and the managed disks to be moved together, along with other dependent
resources.
If you're moving a resource to a new subscription, check to see whether the resource has any dependent
resources, and whether they're located in the same resource group. If the resources aren't in the same
resource group, check to see whether the resources can be combined into the same resource group. If so,
bring all these resources into the same resource group by using a move operation across resource
groups.
For more information, see Scenario for move across subscriptions.
{} Finished ..
If validation fails, you see an error message describing why the resources can't be moved.
Move
To move existing resources to another resource group or subscription, use the az resource move command.
Provide the resource IDs of the resources to move. The following example shows how to move several resources
to a new resource group. In the --ids parameter, provide a space-separated list of the resource IDs to move.
POST https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<source-
group>/validateMoveResources?api-version=2019-05-10
Authorization: Bearer <access-token>
Content-type: application/json
{
"resources": ["<resource-id-1>", "<resource-id-2>"],
"targetResourceGroup": "/subscriptions/<subscription-id>/resourceGroups/<target-group>"
}
The 202 status code indicates the validation request was accepted, but it hasn't yet determined if the move
operation will succeed. The location value contains a URL that you use to check the status of the long-running
operation.
To check the status, send the following request:
GET <location-url>
Authorization: Bearer <access-token>
While the operation is still running, you continue to receive the 202 status code. Wait the number of seconds
indicated in the retry-after value before trying again. If the move operation validates successfully, you receive
the 204 status code. If the move validation fails, you receive an error message, such as:
{"error":{"code":"ResourceMoveProviderValidationFailed","message":"<message>"...}}
Move
To move existing resources to another resource group or subscription, use the Move resources operation.
POST https://management.azure.com/subscriptions/{source-subscription-id}/resourcegroups/{source-resource-
group-name}/moveResources?api-version={api-version}
In the request body, you specify the target resource group and the resources to move.
{
"resources": ["<resource-id-1>", "<resource-id-2>"],
"targetResourceGroup": "/subscriptions/<subscription-id>/resourceGroups/<target-group>"
}
Frequently asked questions
Question: My resource move operation, which usually takes a few minutes, has been running for
almost an hour. Is there something wrong?
Moving a resource is a complex operation that has different phases. It can involve more than just the resource
provider of the resource you're trying to move. Because of the dependencies between resource providers, Azure
Resource Manager allows 4 hours for the operation to complete. This time period gives resource providers a
chance to recover from transient issues. If your move request is within the four-hour period, the operation keeps
trying to complete and may still succeed. The source and destination resource groups are locked during this
time to avoid consistency issues.
Question: Why is my resource group locked for four hours during resource move?
A move request is allowed a maximum of four hours to complete. To prevent modifications on the resources
being moved, both the source and destination resource groups are locked during the resource move.
There are two phases in a move request. In the first phase, the resource is moved. In the second phase,
notifications are sent to other resource providers that are dependent on the resource being moved. A resource
group can be locked for the entire four hours when a resource provider fails either phase. During the allowed
time, Resource Manager retries the failed step.
If a resource can't be moved within four hours, Resource Manager unlocks both resource groups. Resources that
were successfully moved are in the destination resource group. Resources that failed to move are left the source
resource group.
Question: What are the implications of the source and destination resource groups being locked
during the resource move?
The lock prevents you from deleting either resource group, creating a new resource in either resource group, or
deleting any of the resources involved in the move.
The following image shows an error message from the Azure portal when a user tries to delete a resource
group that is part of an ongoing move.
Next steps
For a list of which resources support move, see Move operation support for resources.
Run background tasks with WebJobs in Azure App
Service
5/18/2022 • 7 minutes to read • Edit Online
Deploy WebJobs by using the Azure portal to upload an executable or script. You can run background tasks in
the Azure App Service.
If instead of the Azure App Service you are using Visual Studio 2019 to develop and deploy WebJobs, see
Deploy WebJobs using Visual Studio.
Overview
WebJobs is a feature of Azure App Service that enables you to run a program or script in the same instance as a
web app, API app, or mobile app. There is no additional cost to use WebJobs.
You can use the Azure WebJobs SDK with WebJobs to simplify many programming tasks. WebJobs is not yet
supported for App Service on Linux. For more information, see What is the WebJobs SDK.
Azure Functions provides another way to run programs and scripts. For a comparison between WebJobs and
Functions, see Choose between Flow, Logic Apps, Functions, and WebJobs.
WebJob types
The following table describes the differences between continuous and triggered WebJobs.
C O N T IN UO US T RIGGERED
Starts immediately when the WebJob is created. To keep the Starts only when triggered manually or on a schedule.
job from ending, the program or script typically does its
work inside an endless loop. If the job does end, you can
restart it. Typically used with WebJobs SDK.
Runs on all instances that the web app runs on. You can Runs on a single instance that Azure selects for load
optionally restrict the WebJob to a single instance. balancing.
NOTE
A web app can time out after 20 minutes of inactivity, and only requests to the actual web app can reset the timer.
Viewing the app's configuration in the Azure portal or making requests to the advanced tools site (
https://<app_name>.scm.azurewebsites.net ) doesn't reset the timer. If you set the web app that hosts your job to run
continuously, run on a schedule, or use event-driven triggers, enable the Always on setting on your web app's Azure
Configuration page. The Always on setting helps to make sure that these kinds of WebJobs run reliably. This feature is
available only in the Basic, Standard, and Premium pricing tiers.
1. In the Azure portal, go to the App Ser vice page of your App Service web app, API app, or mobile app.
2. In the left pane of your app's App Ser vice page, search for and select WebJobs .
5. Select OK .
The new WebJob appears on the WebJobs page. If you see a message that says the WebJob was added,
but you don't see it, select Refresh .
6. To stop or restart a continuous WebJob, right-click the WebJob in the list and select Stop or Star t .
Triggers Manual
6. Select OK .
The new WebJob appears on the WebJobs page. If you see a message that says the WebJob was added,
but you don't see it, select Refresh .
7. To run the WebJob, right-click its name in the list and select Run .
6. Select OK .
The new WebJob appears on the WebJobs page. If you see a message that says the WebJob was added,
but you don't see it, select Refresh .
NCRONTAB expressions
You can enter a NCRONTAB expression in the portal or include a settings.job file at the root of your WebJob
.zip file, as in the following example:
{
"schedule": "0 */15 * * * *"
}
NOTE
The default time zone used to run CRON expressions is Coordinated Universal Time (UTC). To have your CRON expression
run based on another time zone, create an app setting for your function app named WEBSITE_TIME_ZONE. To learn more,
see NCRONTAB time zones.
Manage WebJobs
You can manage the running state individual WebJobs running in your site in the Azure portal. Just go to
Settings > WebJobs , choose the WebJob, and you can start and stop the WebJob. You can also view and
modify the password of the webhook that runs the WebJob.
You can also add an application setting named WEBJOBS_STOPPED with a value of 1 to stop all WebJobs running
on your site. This can be handy as a way to prevent conflicting WebJobs from running both in staging and
production slots. You can similarly use a value of 1 for the WEBJOBS_DISABLE_SCHEDULE setting to disable
triggered WebJobs in the site or a staging slot. For slots, remember to enable the Deployment slot setting
option so that the setting itself doesn't get swapped.
3. In the WebJob Run Details page, select Toggle Output to see the text of the log contents.
To see the output text in a separate browser window, select download . To download the text itself, right-
click download and use your browser options to save the file contents.
4. Select the WebJobs breadcrumb link at the top of the page to go to a list of WebJobs.
Next steps
The Azure WebJobs SDK can be used with WebJobs to simplify many programming tasks. For more
information, see What is the WebJobs SDK.
Develop and deploy WebJobs using Visual Studio
5/18/2022 • 10 minutes to read • Edit Online
This article explains how to use Visual Studio to deploy a console app project to a web app in Azure App Service
as an Azure WebJob. For information about how to deploy WebJobs by using the Azure portal, see Run
background tasks with WebJobs in Azure App Service.
You can choose to develop a WebJob that runs as either a .NET Core app or a .NET Framework app. Version 3.x
of the Azure WebJobs SDK lets you develop WebJobs that run as either .NET Core apps or .NET Framework
apps, while version 2.x supports only the .NET Framework. The way that you deploy a WebJobs project is
different for .NET Core projects than for .NET Framework projects.
You can publish multiple WebJobs to a single web app, provided that each WebJob in a web app has a unique
name.
NOTE
.NET Core Web Apps and/or .NET Core WebJobs can't be linked with web projects. If you need to deploy your WebJob
with a web app, create your WebJobs as a .NET Framework console app.
Hosting Plan App Service plan An App Service plan specifies the
location, size, and features of the
web server farm that hosts your
app. You can save money when
hosting multiple apps by
configuring the web apps to share a
single App Service plan. App Service
plans define the region, instance
size, scale count, and SKU (Free,
Shared, Basic, Standard, or
Premium). Choose New to create a
new App Service plan. Free and
Basic tiers don't support the Always
On option to keep your site running
continuously.
6. Select Create to create a WebJob and related resources in Azure with these settings and deploy your
project code.
7. Select Finish to return to the Publish page.
You can add these items to an existing console app project or use a template to create a new WebJobs-enabled
console app project.
Deploy a project as a WebJob by itself, or link it to a web project so that it automatically deploys whenever you
deploy the web project. To link projects, Visual Studio includes the name of the WebJobs-enabled project in a
webjobs-list.json file in the web project.
Prerequisites
Install Visual Studio 2017 or Visual Studio 2019 with the Azure development workload.
Enable WebJobs deployment for an existing console app project
You have two options:
Enable automatic deployment with a web project.
Configure an existing console app project so that it automatically deploys as a WebJob when you deploy
a web project. Use this option when you want to run your WebJob in the same web app in which you run
the related web application.
Enable deployment without a web project.
Configure an existing console app project to deploy as a WebJob by itself, without a link to a web project.
Use this option when you want to run a WebJob in a web app by itself, with no web application running
in the web app. You might want to do so to scale your WebJob resources independently of your web
application resources.
Enable automatic WebJobs deployment with a web project
1. Right-click the web project in Solution Explorer , and then select Add > Existing Project as Azure
WebJob .
The Add Azure WebJob dialog box appears.
2. In the Project name drop-down list, select the console app project to add as a WebJob.
3. Complete the Add Azure WebJob dialog box, and then select OK .
Enable WebJobs deployment without a web project
1. Right-click the console app project in Solution Explorer , and then select Publish as Azure WebJob .
The Add Azure WebJob dialog box appears, with the project selected in the Project name box.
2. Complete the Add Azure WebJob dialog box, and then select OK .
The Publish Web wizard appears. If you don't want to publish immediately, close the wizard. The
settings that you've entered are saved for when you do want to deploy the project.
Create a new WebJobs-enabled project
To create a new WebJobs-enabled project, use the console app project template and enable WebJobs
deployment as explained in the previous section. As an alternative, you can use the WebJobs new-project
template:
Use the WebJobs new-project template for an independent WebJob
Create a project and configure it to deploy by itself as a WebJob, with no link to a web project. Use this
option when you want to run a WebJob in a web app by itself, with no web application running in the
web app. You might want to do so to scale your WebJob resources independently of your web application
resources.
Use the WebJobs new-project template for a WebJob linked to a web project
Create a project that is configured to deploy automatically as a WebJob when you deploy a web project in
the same solution. Use this option when you want to run your WebJob in the same web app in which you
run the related web application.
NOTE
The WebJobs new-project template automatically installs NuGet packages and includes code in Program.cs for the
WebJobs SDK. If you don't want to use the WebJobs SDK, remove or change the host.RunAndBlock statement in
Program.cs.
{
"$schema": "http://schemastore.org/schemas/json/webjob-publish-settings.json",
"webJobName": "WebJob1",
"startTime": "null",
"endTime": "null",
"jobRecurrenceFrequency": "null",
"interval": null,
"runMode": "Continuous"
}
You can edit this file directly, and Visual Studio provides IntelliSense. The file schema is stored at
https://schemastore.org and can be viewed there.
webjobs-list.json file
When you link a WebJobs-enabled project to a web project, Visual Studio stores the name of the WebJobs
project in a webjobs-list.json file in the web project's Properties folder. The list might contain multiple WebJobs
projects, as shown in the following example:
{
"$schema": "http://schemastore.org/schemas/json/webjobs-list.json",
"WebJobs": [
{
"filePath": "../ConsoleApplication1/ConsoleApplication1.csproj"
},
{
"filePath": "../WebJob1/WebJob1.csproj"
}
]
}
You can edit this file directly in Visual Studio, with IntelliSense. The file schema is stored at
https://schemastore.org.
Deploy a WebJobs project
A WebJobs project that you've linked to a web project deploys automatically with the web project. For
information about web project deployment, see How-to guides > Deploy the app in the left navigation.
To deploy a WebJobs project by itself, right-click the project in Solution Explorer and select Publish as Azure
WebJob .
For an independent WebJob, the same Publish Web wizard that is used for web projects appears, but with
fewer settings available to change.
Add Azure WebJob dialog box
The Add Azure WebJob dialog box lets you enter the WebJob name and the run mode setting for your
WebJob.
Some of the fields in this dialog box correspond to fields on the Add WebJob dialog box of the Azure portal.
For more information, see Run background tasks with WebJobs in Azure App Service.
WebJob deployment information:
For information about command-line deployment, see Enabling Command-line or Continuous Delivery
of Azure WebJobs.
If you deploy a WebJob, and then decide you want to change the type of WebJob and redeploy, delete the
webjobs-publish-settings.json file. Doing so causes Visual Studio to redisplay the publishing options, so
you can change the type of WebJob.
If you deploy a WebJob and later change the run mode from continuous to non-continuous or vice versa,
Visual Studio creates a new WebJob in Azure when you redeploy. If you change other scheduling settings,
but leave run mode the same or switch between Scheduled and On Demand, Visual Studio updates the
existing job instead of creating a new one.
WebJob types
The type of a WebJob can be either triggered or continuous:
Triggered (default): A triggered WebJob starts based on a binding event, on a schedule, or when you
trigger it manually (on demand). It runs on a single instance that the web app runs on.
Continuous: A continuous WebJob starts immediately when the WebJob is created. It runs on all web app
scaled instances by default but can be configured to run as a single instance via settings.job.
NOTE
A web app can time out after 20 minutes of inactivity, and only requests to the actual web app can reset the timer.
Viewing the app's configuration in the Azure portal or making requests to the advanced tools site (
https://<app_name>.scm.azurewebsites.net ) doesn't reset the timer. If you set the web app that hosts your job to run
continuously, run on a schedule, or use event-driven triggers, enable the Always on setting on your web app's Azure
Configuration page. The Always on setting helps to make sure that these kinds of WebJobs run reliably. This feature is
available only in the Basic, Standard, and Premium pricing tiers.
{
"schedule": "0 0 9-17 * * *"
}
This file is located at the root of the WebJobs folder with your WebJob's script, such as
wwwroot\app_data\jobs\triggered\{job name} or wwwroot\app_data\jobs\continuous\{job name} . When you deploy
a WebJob from Visual Studio, mark your settings.job file properties in Visual Studio as Copy if newer .
If you create a WebJob from the Azure portal, the settings.job file is created for you.
CRON expressions
WebJobs uses the same CRON expressions for scheduling as the timer trigger in Azure Functions. To learn more
about CRON support, see Timer trigger for Azure Functions.
NOTE
The default time zone used to run CRON expressions is Coordinated Universal Time (UTC). To have your CRON expression
run based on another time zone, create an app setting for your function app named WEBSITE_TIME_ZONE. To learn more,
see NCRONTAB time zones.
settings.job reference
The following settings are supported by WebJobs:
Continuous execution
If you enable Always on in Azure, you can use Visual Studio to change the WebJob to run continuously:
1. If you haven't already done so, publish the project to Azure.
2. In Solution Explorer , right-click the project and select Publish .
3. In the Publish tab, choose Edit .
4. In the Profile settings dialog box, choose Continuous for WebJob Type , and then choose Save .
5. Select Publish in the Publish tab to republish the WebJob with the updated settings.
Next steps
Learn more about the WebJobs SDK
Tutorial: Get started with the Azure WebJobs SDK
for event-driven background processing
5/18/2022 • 16 minutes to read • Edit Online
Get started with the Azure WebJobs SDK for Azure App Service to enable your web apps to run background
tasks, scheduled tasks, and respond to events.
Use Visual Studio 2019 to create a .NET core console app that uses the WebJobs SDK to respond to Azure
Storage Queue messages, run the project locally, and finally deploy it to Azure.
In this tutorial, you will learn how to:
Create a console app
Add a function
Test locally
Deploy to Azure
Enable Application Insights logging
Add input/output bindings
Prerequisites
Visual Studio 2019 with the Azure development workload. Install Visual Studio 2019.
An Azure account with an active subscription. Create an account for free.
NOTE
The procedures in this article are verified for creating a .NET Core console app that runs on .NET Core 3.1.
Create a project
1. In Visual Studio, select File > New > Project .
2. Under Create a new project , select Console Application (C#) , and then select Next .
3. Under Configure your new project , name the project WebJobsSDKSample, and then select Next .
4. Choose your Target framework and select Create . This tutorial has been verified using .NET Core 3.1.
Install WebJobs NuGet packages
Install the latest WebJobs NuGet package. This package includes Microsoft.Azure.WebJobs (WebJobs SDK),
which lets you publish your function code to WebJobs in Azure App Service.
1. Get the latest stable 3.x version of the Microsoft.Azure.WebJobs.Extensions NuGet package.
2. In Visual Studio, go to Tools > NuGet Package Manager .
3. Select Package Manager Console . You'll see a list of NuGet cmdlets, a link to documentation, and a
PM> entry point.
4. In the following command, replace <3_X_VERSION> with the current version number you found in step 1.
5. In the Package Manager Console , execute the command. The extension list appears and automatically
installs.
Create the Host
The host is the runtime container for functions that listens for triggers and calls functions. The following steps
create a host that implements IHost , which is the Generic Host in ASP.NET Core.
1. Select the Program.cs tab and add these using statements:
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
2. Also under Program.cs , replace the Main method with the following code:
In ASP.NET Core, host configurations are set by calling methods on the HostBuilder instance. For more
information, see .NET Generic Host. The ConfigureWebJobs extension method initializes the WebJobs host. In
ConfigureWebJobs , initialize specific binding extensions, such as the Storage binding extension, and set
properties of those extensions.
Enable console logging
Set up console logging that uses the ASP.NET Core logging framework. This framework,
Microsoft.Extensions.Logging, includes an API that works with a variety of built-in and third-party logging
providers.
1. Get the latest stable version of the Microsoft.Extensions.Logging.Console NuGet package, which includes
Microsoft.Extensions.Logging .
2. In the following command, replace <3_X_VERSION> with the current version number you found in step 1.
Each type of NuGet Package has a unique version number.
3. In the Package Manager Console , fill in the current version number and execute the command. The
extension list appears and automatically installs.
4. Under the tab Program.cs , add this using statement:
using Microsoft.Extensions.Logging;
5. Continuing under Program.cs , add the ConfigureLogging method to HostBuilder , before the Build
command. The AddConsole method adds console logging to the configuration.
builder.ConfigureLogging((context, b) =>
{
b.AddConsole();
});
Add a function
A function is unit of code that runs on a schedule, is triggered based on events, or is run on demand. A trigger
listens to a service event. In the context of the WebJobs SDK, triggered doesn't refer to the deployment mode.
Event-driven or scheduled WebJobs created using the SDK should always be deployed as continuous WebJobs
with "Always on" enabled.
In this section, you create a function triggered by messages in an Azure Storage queue. First, you need to add a
binding extension to connect to Azure Storage.
Install the Storage binding extension
Starting with version 3 of the WebJobs SDK, to connect to Azure Storage services you must install a separate
Storage binding extension package.
NOTE
Beginning with 5.x, Microsoft.Azure.WebJobs.Extensions.Storage has been split by storage service and has migrated the
AddAzureStorage() extension method by service type.
1. Get the latest stable version of the Microsoft.Azure.WebJobs.Extensions.Storage NuGet package, version
3.x.
2. In the following command, replace <3_X_VERSION> with the current version number you found in step 1.
Each type of NuGet Package has a unique version number.
3. In the Package Manager Console , execute the command with the current version number at the PM>
entry point.
4. Continuing in Program.cs , in the ConfigureWebJobs extension method, add the AddAzureStorage method
on the HostBuilder instance (before the Build command) to initialize the Storage extension. At this
point, the ConfigureWebJobs method looks like this:
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
});
5. Add the following code in the Main method after the builder is instantiated:
builder.UseEnvironment(EnvironmentName.Development);
Running in development mode reduces the queue polling exponential backoff that can significantly delay
the amount of time it takes for the runtime to find the message and invoke the function. You should
remove this line of code or switch to Production when you're done with development and testing.
The Main method should now look like the following example:
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace WebJobsSDKSample
{
public class Functions
{
public static void ProcessQueueMessage([QueueTrigger("queue")] string message, ILogger
logger)
{
logger.LogInformation(message);
}
}
}
You should mark the Functions class as public static in order for the runtime to access and execute the
method. In the above code sample, when a message is added to a queue named queue , the function
executes and the message string is written to the logs. The queue being monitored is in the default Azure
Storage account, which you create next.
The message parameter doesn't have to be a string. You can also bind to a JSON object, a byte array, or a
CloudQueueMessage object. See Queue trigger usage. Each binding type (such as queues, blobs, or tables) has a
different set of parameter types that you can bind to.
Create an Azure storage account
The Azure Storage Emulator that runs locally doesn't have all of the features that the WebJobs SDK needs. You'll
create a storage account in Azure and configure the project to use it.
To learn how to create a general-purpose v2 storage account, see Create an Azure Storage account.
Locate and copy your connection string
A connection string is required to configure storage. Keep this connection string for the next steps.
1. In the Azure portal, navigate to your storage account and select Settings .
2. In Settings , select Access keys .
3. For the Connection string under key1 , select the Copy to clipboard icon.
Configure storage to run locally
The WebJobs SDK looks for the storage connection string in the Application Settings in Azure. When you run
locally, it looks for this value in the local configuration file or in environment variables.
1. Right-click the project, select Add > New Item , select JavaScript JSON configuration file , name the
new file appsettings.json file, and select Add .
2. In the new file, add a AzureWebJobsStorage field, as in the following example:
{
"AzureWebJobsStorage": "{storage connection string}"
}
3. Replace {storage connection string} with the connection string that you copied previously.
4. Select the appsettings.json file in Solution Explorer and in the Proper ties window, set the Copy to
Output Director y action to Copy if newer .
Because this file contains a connection string secret, you shouldn't store the file in a remote code repository.
After publishing your project to Azure, you can add the same connection string app setting in your app in Azure
App Service.
Test locally
Build and run the project locally and create a message queue to trigger the function.
1. In Cloud Explorer in Visual Studio, expand the node for your new storage account, and then right-click
Queues .
2. Select Create Queue .
3. Enter queue as the name for the queue, and then select OK .
4. Right-click the node for the new queue, and then select Open .
5. Select the Add Message icon.
6. In the Add Message dialog, enter Hello World! as the Message text , and then select OK . There is now a
message in the queue.
Deploy to Azure
During deployment, you create an app service instance where you'll run your functions. When you publish a
.NET Core console app to App Service in Azure, it automatically runs as a WebJob. To learn more about
publishing, see Develop and deploy WebJobs using Visual Studio.
Create Azure resources
1. In Solution Explorer , right-click the project and select Publish .
2. In the Publish dialog box, select Azure for Target , and then select Next .
3. Select Azure WebJobs for Specific target , and then select Next .
4. Above App Ser vice instances select the plus (+ ) button to Create a new Azure WebJob .
5. In the App Ser vice (Windows) dialog box, use the hosting settings in the following table.
Hosting Plan App Service plan An App Service plan specifies the
location, size, and features of the
web server farm that hosts your
app. You can save money when
hosting multiple apps by
configuring the web apps to share a
single App Service plan. App Service
plans define the region, instance
size, scale count, and SKU (Free,
Shared, Basic, Standard, or
Premium). Choose New to create a
new App Service plan. Free and
Basic tiers don't support the Always
On option to keep your site running
continuously.
6. Select Create to create a WebJob and related resources in Azure with these settings and deploy your
project code.
7. Select Finish to return to the Publish page.
Enable Always On
For a continuous WebJob, you should enable the Always on setting in the site so that your WebJobs run
correctly. If you don't enable Always on, the runtime goes idle after a few minutes of inactivity.
1. In the Publish page, select the three dots above Hosting to show Hosting profile section actions
and choose Open in Azure por tal .
2. Under Settings , choose Configuration > General settings , set Always on to On , and then select
Save and Continue to restart the site.
Publish the project
With the web app created in Azure, it's time to publish the WebJobs project.
1. In the Publish page under Hosting , select the edit button and change the WebJob Type to Continuous
and select Save . This makes sure that the WebJob is running when messages are added to the queue.
Triggered WebJobs are typically used only for manual webhooks.
2. Select the Publish button at the top right corner of the Publish page. When the operation completes,
your WebJob is running on Azure.
Create a storage connection app setting
You need to create the same storage connection string setting in Azure that you used locally in your
appsettings.json config file. This lets you more securely store the connection string and
1. In your Publish profile page, select the three dots above Hosting to show Hosting profile section
actions and choose Manage Azure App Ser vice settings .
2. In Application settings , choose + Add setting .
3. In New app setting name , type AzureWebJobsStorage and select OK .
4. In Remote , paste in the connection string from your local setting and select OK .
The connection string is now set in your app in Azure.
Trigger the function in Azure
1. Make sure you're not running locally. Close the console window if it's still open. Otherwise, the local
instance might be the first to process any queue messages you create.
2. In the Queue page in Visual Studio, add a message to the queue as before.
3. Refresh the Queue page, and the new message disappears because it has been processed by the function
running in Azure.
3. In the Package Manager Console , execute the command with the current version number at the PM>
entry point.
Initialize the Application Insights logging provider
Open Program.cs and add the following initializer in the ConfigureLogging after the call to AddConsole :
// If the key exists in settings, use it to enable Application Insights.
string instrumentationKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
if (!string.IsNullOrEmpty(instrumentationKey))
{
b.AddApplicationInsightsWebJobs(o => o.InstrumentationKey = instrumentationKey);
}
The Main method code should now look like the following example:
This initializes the Application Insights logging provider with default filtering. When running locally, all
Information and higher-level logs are written to both the console and Application Insights.
Republish the project and trigger the function again
1. In Solution Explorer , right-click the project and select Publish .
2. As before, use Cloud Explorer in Visual Studio to create a queue message like you did earlier, except
enter Hello App Insights! as the message text.
3. In your Publish profile page, select the three dots above Hosting to show Hosting profile section
actions and choose Open in Azure Por tal .
4. In the web app under Settings , choose Application Insights , and select View Application Insights
data .
5. Select Search and then select See all data in the last 24 hours .
6. If you don't see the Hello App Insights! message, select Refresh periodically for several minutes. Logs
don't appear immediately, because it takes a while for the Application Insights client to flush the logs it
processes.
In this code, queueTrigger is a binding expression, which means it resolves to a different value at
runtime. At runtime, it has the contents of the queue message.
2. Add a using :
using System.IO;
2. Create another queue message with Program.cs as the text of the message.
3. Run the project locally.
The queue message triggers the function, which then reads the blob, logs its length, and creates a new
blob. The console output is the same, but when you go to the blob container window and select Refresh ,
you see a new blob named copy-Program.cs.
Republish the project
1. In Solution Explorer , right-click the project and select Publish .
2. In the Publish dialog, make sure that the current profile is selected and then select Publish . Results of
the publish are detailed in the Output window.
3. Verify the function in Azure by again uploading a file to the blob container and adding a message to the
queue that is the name of the uploaded file. You see the message get removed from the queue and a copy
of the file created in the blob container.
Next steps
This tutorial showed you how to create, run, and deploy a WebJobs SDK 3.x project.
Learn more about the WebJobs SDK
How to use the Azure WebJobs SDK for event-
driven background processing
5/18/2022 • 26 minutes to read • Edit Online
This article provides guidance on how to work with the Azure WebJobs SDK. To get started with WebJobs right
away, see Get started with the Azure WebJobs SDK.
WebJobs host
The host is a runtime container for functions. The Host listens for triggers and calls functions. In version 3.x, the
host is an implementation of IHost . In version 2.x, you use the JobHost object. You create a host instance in
your code and write code to customize its behavior.
This is a key difference between using the WebJobs SDK directly and using it indirectly through Azure Functions.
In Azure Functions, the service controls the host, and you can't customize the host by writing code. Azure
Functions lets you customize host behavior through settings in the host.json file. Those settings are strings, not
code, and use of these strings limits the kinds of customizations you can do.
Host connection strings
The WebJobs SDK looks for Azure Storage and Azure Service Bus connection strings in the local.settings.json file
when you run locally or in the environment of the WebJob when you run in Azure. By default, the WebJobs SDK
requires a storage connection string setting with the name AzureWebJobsStorage .
Version 2.x of the SDK doesn't require a specific name. Version 2.x lets you use your own names for these
connection strings and allows you to store them elsewhere. You can set names in code using the
JobHostConfiguration , like this:
static void Main(string[] args)
{
var _storageConn = ConfigurationManager
.ConnectionStrings["MyStorageConnection"].ConnectionString;
NOTE
Because version 3.x uses the default .NET Core configuration APIs, there is no API to change connection string names. See
Develop and deploy WebJobs using Visual Studio
The process for enabling development mode depends on the SDK version.
Version 3.x
Version 3.x uses the standard ASP.NET Core APIs. Call the UseEnvironment method on the HostBuilder instance.
Pass a string named development , as in this example:
Version 2.x
The JobHostConfiguration class has a UseDevelopmentSettings method that enables development mode. The
following example shows how to use development settings. To make config.IsDevelopment return true when it
runs locally, set a local environment variable named AzureWebJobsEnv with the value Development .
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
The QueueTrigger attribute tells the runtime to call the function whenever a queue message appears in
myqueue-items . The Blob attribute tells the runtime to use the queue message to read a blob in the sample-
workitems container. The name of the blob item in the samples-workitems container is obtained directly from the
queue trigger as a binding expression ( {queueTrigger} ).
NOTE
A web app can time out after 20 minutes of inactivity, and only requests to the actual web app can reset the timer.
Viewing the app's configuration in the Azure portal or making requests to the advanced tools site (
https://<app_name>.scm.azurewebsites.net ) doesn't reset the timer. If you set the web app that hosts your job to run
continuously, run on a schedule, or use event-driven triggers, enable the Always on setting on your web app's Azure
Configuration page. The Always on setting helps to make sure that these kinds of WebJobs run reliably. This feature is
available only in the Basic, Standard, and Premium pricing tiers.
Manual triggers
To trigger a function manually, use the NoAutomaticTrigger attribute, as shown here:
[NoAutomaticTrigger]
public static void CreateQueueMessage(
ILogger logger,
string value,
[Queue("outputqueue")] out string message)
{
message = value;
logger.LogInformation("Creating queue message: ", message);
}
The process for manually triggering the function depends on the SDK version.
Version 3.x
static async Task Main(string[] args)
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
});
var host = builder.Build();
using (host)
{
var jobHost = host.Services.GetService(typeof(IJobHost)) as JobHost;
var inputs = new Dictionary<string, object>
{
{ "value", "Hello world!" }
};
await host.StartAsync();
await jobHost.CallAsync("CreateQueueMessage", inputs);
await host.StopAsync();
}
}
Version 2.x
To use other trigger and binding types, install the NuGet package that contains them and call the Add<binding>
extension method implemented in the extension. For example, if you want to use an Azure Cosmos DB binding,
install Microsoft.Azure.WebJobs.Extensions.CosmosDB and call AddCosmosDB , like this:
To use the Timer trigger or the Files binding, which are part of core services, call the AddTimers or AddFiles
extension methods.
Version 2.x
These trigger and binding types are included in version 2.x of the Microsoft.Azure.WebJobs package:
Blob storage
Queue storage
Table storage
To use other trigger and binding types, install the NuGet package that contains them and call a Use<binding>
method on the JobHostConfiguration object. For example, if you want to use a Timer trigger, install
Microsoft.Azure.WebJobs.Extensions and call UseTimers in the Main method, as shown here:
The process for binding to the ExecutionContext depends on your SDK version.
Version 3.x
Call the AddExecutionContextBinding extension method in the ConfigureWebJobs method, as shown here:
Version 2.x
The Microsoft.Azure.WebJobs.Extensions package mentioned earlier also provides a special binding type that
you can register by calling the UseCore method. This binding lets you define an ExecutionContext parameter in
your function signature, which is enabled like this:
class Program
{
static void Main()
{
config = new JobHostConfiguration();
config.UseCore();
var host = new JobHost(config);
host.RunAndBlock();
}
}
Binding configuration
You can configure the behavior of some triggers and bindings. The process for configuring them depends on the
SDK version.
Version 3.x : Set configuration when the Add<Binding> method is called in ConfigureWebJobs .
Version 2.x : Set configuration by setting properties in a configuration object that you pass in to JobHost .
These binding-specific settings are equivalent to settings in the host.json project file in Azure Functions.
You can configure the following bindings:
Azure CosmosDB trigger
Event Hubs trigger
Queue storage trigger
SendGrid binding
Service Bus trigger
Azure CosmosDB trigger configuration (version 3.x )
This example shows how to configure the Azure Cosmos DB trigger:
});
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Version 2.x
Binding expressions
In attribute constructor parameters, you can use expressions that resolve to values from various sources. For
example, in the following code, the path for the BlobTrigger attribute creates an expression named filename .
When used for the output binding, filename resolves to the name of the triggering blob.
For more information about binding expressions, see Binding expressions and patterns in the Azure Functions
documentation.
Custom binding expressions
Sometimes you want to specify a queue name, a blob name or container, or a table name in code rather than
hard-coding it. For example, you might want to specify the queue name for the QueueTrigger attribute in a
configuration file or environment variable.
You can do that by passing a NameResolver object in to the JobHostConfiguration object. You include
placeholders in trigger or binding attribute constructor parameters, and your NameResolver code provides the
actual values to be used in place of those placeholders. You identify placeholders by surrounding them with
percent (%) signs, as shown here:
This code lets you use a queue named logqueuetest in the test environment and one named logqueueprod in
production. Instead of a hard-coded queue name, you specify the name of an entry in the appSettings
collection.
There's a default NameResolver that takes effect if you don't provide a custom one. The default gets values from
app settings or environment variables.
Your NameResolver class gets the queue name from appSettings , as shown here:
Version 3.x
You configure the resolver by using dependency injection. These samples require the following using
statement:
using Microsoft.Extensions.DependencyInjection;
You add the resolver by calling the ConfigureServices extension method on HostBuilder , as in this example:
static async Task Main(string[] args)
{
var builder = new HostBuilder();
var resolver = new CustomNameResolver();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
});
builder.ConfigureServices(s => s.AddSingleton<INameResolver>(resolver));
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Version 2.x
Pass your NameResolver class in to the JobHost object, as shown here:
Azure Functions implements INameResolver to get values from app settings, as shown in the example. When
you use the WebJobs SDK directly, you can write a custom implementation that gets placeholder replacement
values from whatever source you prefer.
Binding at runtime
If you need to do some work in your function before you use a binding attribute like Queue , Blob , or Table ,
you can use the IBinder interface.
The following example takes an input queue message and creates a new message with the same content in an
output queue. The output queue name is set by code in the body of the function.
For more information, see Binding at runtime in the Azure Functions documentation.
Binding reference information
The Azure Functions documentation provides reference information about each binding type. You'll find the
following information in each binding reference article. (This example is based on Storage queue.)
Packages. The package you need to install to include support for the binding in a WebJobs SDK project.
Examples. Code samples. The C# class library example applies to the WebJobs SDK. Just omit the
FunctionName attribute.
Attributes. The attributes to use for the binding type.
Configuration. Explanations of the attribute properties and constructor parameters.
Usage. The types you can bind to and information about how the binding works. For example: polling
algorithm, poison queue processing.
NOTE
The HTTP, Webhooks, and Event Grid bindings are supported only by Azure Functions, not by the WebJobs SDK.
For a full list of bindings supported in Azure Functions runtime, see Supported bindings.
[Disable("Disable_TestJob")]
public static void TestJob([QueueTrigger("testqueue2")] string message)
{
Console.WriteLine("Function with Disable attribute executed!");
}
When you change app setting values in the Azure portal, the WebJob restarts to pick up the new setting.
The attribute can be declared at the parameter, method, or class level. The setting name can also contain binding
expressions.
Timeout attribute
The Timeout attribute causes a function to be canceled if it doesn't finish within a specified amount of time. In
the following example, the function would run for one day without the Timeout attribute. Timeout causes the
function to be canceled after 15 seconds.
[Timeout("00:00:15")]
public static async Task TimeoutJob(
[QueueTrigger("testqueue2")] string message,
CancellationToken token,
TextWriter log)
{
await log.WriteLineAsync("Job starting");
await Task.Delay(TimeSpan.FromDays(1), token);
await log.WriteLineAsync("Job completed");
}
You can apply the Timeout attribute at the class or method level, and you can specify a global timeout by using
JobHostConfiguration.FunctionTimeout . Class-level or method-level timeouts override global timeouts.
Singleton attribute
The Singleton attribute ensures that only one instance of a function runs, even when there are multiple
instances of the host web app. The Singleton attribute uses distributed locking to ensure that one instance runs.
In this example, only a single instance of the ProcessImage function runs at any given time:
[Singleton]
public static async Task ProcessImage([BlobTrigger("images")] Stream image)
{
// Process the image.
}
SingletonMode.Listener
Some triggers have built-in support for concurrency management:
QueueTrigger . Set JobHostConfiguration.Queues.BatchSize to 1 .
Ser viceBusTrigger . Set ServiceBusConfiguration.MessageOptions.MaxConcurrentCalls to 1 .
FileTrigger . Set FileProcessor.MaxDegreeOfParallelism to 1 .
You can use these settings to ensure that your function runs as a singleton on a single instance. To ensure that
only a single instance of the function is running when the web app scales out to multiple instances, apply a
listener-level singleton lock on the function ( [Singleton(Mode = SingletonMode.Listener)] ). Listener locks are
acquired when the JobHost starts. If three scaled-out instances all start at the same time, only one of the
instances acquires the lock and only one listener starts.
NOTE
See this GitHub Repo to learn more about how the SingletonMode.Function works.
Scope values
You can specify a scope expression/value on a singleton. The expression/value ensures that all executions of the
function at a specific scope will be serialized. Implementing more granular locking in this way can allow for
some level of parallelism for your function while serializing other invocations as dictated by your requirements.
For example, in the following code, the scope expression binds to the Region value of the incoming message.
When the queue contains three messages in regions East, East, and West, the messages that have region East
are run serially. The message with region West is run in parallel with those in region East.
[Singleton("{Region}")]
public static async Task ProcessWorkItem([QueueTrigger("workitems")] WorkItem workItem)
{
// Process the work item.
}
SingletonScope.Host
The default scope for a lock is SingletonScope.Function , meaning the lock scope (the blob lease path) is tied to
the fully qualified function name. To lock across functions, specify SingletonScope.Host and use a scope ID name
that's the same across all functions that you don't want to run simultaneously. In the following example, only
one instance of AddItem or RemoveItem runs at a time:
[Singleton("ItemsLock", SingletonScope.Host)]
public static void AddItem([QueueTrigger("add-item")] string message)
{
// Perform the add operation.
}
[Singleton("ItemsLock", SingletonScope.Host)]
public static void RemoveItem([QueueTrigger("remove-item")] string message)
{
// Perform the remove operation.
}
Async functions
For information about how to code async functions, see the Azure Functions documentation.
Cancellation tokens
For information about how to handle cancellation tokens, see the Azure Functions documentation on
cancellation tokens and graceful shutdown.
Multiple instances
If your web app runs on multiple instances, a continuous WebJob runs on each instance, listening for triggers
and calling functions. The various trigger bindings are designed to efficiently share work collaboratively across
instances, so that scaling out to more instances allows you to handle more load.
While some triggers may result in double-processing, queue and blob storage triggers automatically prevent a
function from processing a queue message or blob more than once. For more information, see Designing for
identical input in the Azure Functions documentation.
The timer trigger automatically ensures that only one instance of the timer runs, so you don't get more than one
function instance running at a given scheduled time.
If you want to ensure that only one instance of a function runs even when there are multiple instances of the
host web app, you can use the Singleton attribute.
Filters
Function Filters (preview) provide a way to customize the WebJobs execution pipeline with your own logic.
Filters are similar to ASP.NET Core filters. You can implement them as declarative attributes that are applied to
your functions or classes. For more information, see Function Filters.
LO GL EVEL C O DE
Trace 0
Debug 1
Information 2
Warning 3
Error 4
Critical 5
None 6
You can independently filter each category to a particular LogLevel . For example, you might want to see all logs
for blob trigger processing but only Error and higher for everything else.
Version 3.x
Version 3.x of the SDK relies on the filtering built into .NET Core. The LogCategories class lets you define
categories for specific functions, triggers, or users. It also defines filters for specific host states, like Startup and
Results . This enables you to fine-tune the logging output. If no match is found within the defined categories,
the filter falls back to the Default value when deciding whether to filter the message.
LogCategories requires the following using statement:
using Microsoft.Azure.WebJobs.Logging;
The following example constructs a filter that, by default, filters all logs at the Warning level. The Function and
results categories (equivalent to Host.Results in version 2.x) are filtered at the Error level. The filter
compares the current category to all registered levels in the LogCategories instance and chooses the longest
match. This means that the Debug level registered for Host.Triggers matches Host.Triggers.Queue or
Host.Triggers.Blob . This allows you to control broader categories without needing to add each one.
static async Task Main(string[] args)
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
});
builder.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Warning);
logging.AddFilter("Function", LogLevel.Error);
logging.AddFilter(LogCategories.CreateFunctionCategory("MySpecificFunctionName"),
LogLevel.Debug);
logging.AddFilter(LogCategories.Results, LogLevel.Error);
logging.AddFilter("Host.Triggers", LogLevel.Debug);
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Version 2.x
In version 2.x of the SDK, you use the LogCategoryFilter class to control filtering. The LogCategoryFilter has a
Default property with an initial value of Information , meaning that any messages at the Information ,
Warning , Error , or Critical levels are logged, but any messages at the Debug or Trace levels are filtered
away.
As with LogCategories in version 3.x, the CategoryLevels property allows you to specify log levels for specific
categories so you can fine-tune the logging output. If no match is found within the CategoryLevels dictionary,
the filter falls back to the Default value when deciding whether to filter the message.
The following example constructs a filter that by default filters all logs at the Warning level. The Function and
Host.Results categories are filtered at the Error level. The LogCategoryFilter compares the current category
to all registered CategoryLevels and chooses the longest match. So the Debug level registered for
Host.Triggers will match Host.Triggers.Queue or Host.Triggers.Blob . This allows you to control broader
categories without needing to add each one.
The following custom implementation of ITelemetryInitializer lets you add your own ITelemetry to the
default TelemetryConfiguration .
Call ConfigureServices in the builder to add your custom ITelemetryInitializer to the pipeline.
When the TelemetryConfiguration is constructed, all registered types of ITelemetryInitializer are included. To
learn more, see Application Insights API for custom events and metrics.
In version 3.x, you no longer have to flush the TelemetryClient when the host stops. The .NET Core dependency
injection system automatically disposes of the registered ApplicationInsightsLoggerProvider , which flushes the
TelemetryClient .
Version 2.x
In version 2.x, the TelemetryClient created internally by the Application Insights provider for the WebJobs SDK
uses ServerTelemetryChannel . When the Application Insights endpoint is unavailable or throttling incoming
requests, this channel saves requests in the web app's file system and resubmits them later.
The TelemetryClient is created by a class that implements ITelemetryClientFactory . By default, this is the
DefaultTelemetryClientFactory .
If you want to modify any part of the Application Insights pipeline, you can supply your own
ITelemetryClientFactory , and the host will use your class to construct a TelemetryClient . For example, this code
overrides DefaultTelemetryClientFactory to modify a property of ServerTelemetryChannel :
return channel;
}
}
The SamplingPercentageEstimatorSettings object configures adaptive sampling. This means that in certain high-
volume scenarios, Applications Insights sends a selected subset of telemetry data to the server.
After you create the telemetry factory, you pass it in to the Application Insights logging provider:
Next steps
This article has provided code snippets that show how to handle common scenarios for working with the
WebJobs SDK. For complete samples, see azure-webjobs-sdk-samples.
Availability Zone support for public multi-tenant
App Service
5/18/2022 • 5 minutes to read • Edit Online
Microsoft Azure App Service can be deployed into Availability Zones (AZ) to help you achieve resiliency and
reliability for your business-critical workloads. This architecture is also known as zone redundancy.
An app lives in an App Service plan (ASP), and the App Service plan exists in a single scale unit. When an App
Service is configured to be zone redundant, the platform automatically spreads the VM instances in the App
Service plan across all three zones in the selected region. If a capacity larger than three is specified and the
number of instances is divisible by three, the instances will be spread evenly. Otherwise, instance counts beyond
3*N will get spread across the remaining one or two zones. For App Services that aren't configured to be zone
redundant, the VM instances are placed in a single zone in the selected region.
Requirements
Zone redundancy is a property of the App Service plan. The following are the current requirements/limitations
for enabling zone redundancy:
Both Windows and Linux are supported
Requires either Premium v2 or Premium v3 App Service plans
Minimum instance count of three
The platform will enforce this minimum count behind the scenes if you specify an instance count
fewer than three
Can be enabled in any of the following regions:
West US 2
West US 3
Central US
East US
East US 2
Canada Central
Brazil South
North Europe
West Europe
Germany West Central
France Central
UK South
Japan East
Southeast Asia
Australia East
Zone redundancy can only be specified when creating a new App Service plan
Currently you can't convert a pre-existing App Service plan. See next bullet for details on how to
create a new App Service plan that supports zone redundancy.
Zone redundancy is only supported in the newer portion of the App Service footprint
Currently if you're running on Pv3, then it's possible that you're already on a footprint that supports
zone redundancy. In this scenario, you can create a new App Service plan and specify zone
redundancy when creating the new App Service plan.
If you aren't using Pv3 or a scale unit that supports zone redundancy, are in an unsupported region, or
are unsure, follow the steps below:
Create a new resource group in a region that is supported
This ensures the App Service control plane can find a scale unit in the selected region
that supports zone redundancy
Create a new App Service plan (and app) in a region of your choice using the new resource
group
Ensure the zoneRedundant property (described below) is set to true when creating the new App
Service plan
Traffic is routed to all of your available App Service instances. In the case when a zone goes down, the App
Service platform will detect lost instances and automatically attempt to find new replacement instances and
spread traffic as needed. If you have autoscale configured, and if it decides more instances are needed, autoscale
will also issue a request to App Service to add more instances. Note that autoscale behavior is independent of
App Service platform behavior and that your autoscale instance count specification doesn't need to be a
multiple of three. It's also important to note there's no guarantee that requests for additional instances in a
zone-down scenario will succeed since back filling lost instances occurs on a best-effort basis. The
recommended solution is to create and configure your App Service plans to account for losing a zone as
described in the next section of this article.
Applications that are deployed in an App Service plan that has zone redundancy enabled will continue to run
and serve traffic even if other zones in the same region suffer an outage. However it's possible that non-runtime
behaviors including App Service plan scaling, application creation, application configuration, and application
publishing may still be impacted from an outage in other Availability Zones. Zone redundancy for App Service
plans only ensures continued uptime for deployed applications.
When the App Service platform allocates instances to a zone redundant App Service plan, it uses best effort
zone balancing offered by the underlying Azure Virtual Machine Scale Sets. An App Service plan will be
"balanced" if each zone has either the same number of VMs, or +/- one VM in all of the other zones used by the
App Service plan.
TIP
To decide instance capacity, you can use the following calculation:
Since the platform spreads VMs across three zones and you need to account for at least the failure of one zone, multiply
peak workload instance count by a factor of zones/(zones-1), or 3/2. For example, if your typical peak workload requires
four instances, you should provision six instances: (2/3 * 6 instances) = 4 instances.
To create a zone redundant App Service using the Azure portal, enable the zone redundancy option during the
"Create Web App" or "Create App Service Plan" experiences.
The capacity/number of workers/instance count can be changed once the App Service Plan is created by
navigating to the Scale out (App Ser vice plan) settings.
The only changes needed in an Azure Resource Manager template to specify a zone redundant App Service are
the zoneRedundant property (required) and optionally the App Service plan instance count (capacity ) on the
Microsoft.Web/serverfarms resource. The zoneRedundant property should be set to true and capacity
should be set based on the same conditions described previously.
The Azure Resource Manager template snippet below shows the new zoneRedundant property and capacity
specification.
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "your-appserviceplan-name-here",
"location": "West US 3",
"sku": {
"name": "P1v3",
"tier": "PremiumV3",
"size": "P1v3",
"family": "Pv3",
"capacity": 3
},
"kind": "app",
"properties": {
"zoneRedundant": true
}
}
]
Pricing
There's no additional cost associated with enabling the zone redundancy feature. Pricing for a zone redundant
App Service is the same as a single zone App Service. You'll be charged based on your App Service plan SKU, the
capacity you specify, and any instances you scale to based on your autoscale criteria. If you enable zone
redundancy but specify a capacity less than three, the platform will enforce a minimum instance count of three
and charge you for those three instances.
Next steps
Learn how to create and deploy ARM templates
ARM Quickstart Templates
Learn how to scale up an app in Azure App Service
Overview of autoscale in Microsoft Azure
Manage disaster recovery
Create App Service app using Bicep
5/18/2022 • 3 minutes to read • Edit Online
Get started with Azure App Service by deploying an app to the cloud using a Bicep file and Azure CLI in Cloud
Shell. Because you use a free App Service tier, you incur no costs to complete this quickstart.
Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources. It provides
concise syntax, reliable type safety, and support for code reuse. You can use Bicep instead of JSON to develop
your Azure Resource Manager templates (ARM templates). The JSON syntax to create an ARM template can be
verbose and require complicated expressions. Bicep syntax reduces that complexity and improves the
development experience. Bicep is a transparent abstraction over ARM template JSON and doesn't lose any of the
JSON template capabilities. During deployment, Bicep CLI transpiles a Bicep file into ARM template JSON.
Prerequisites
If you don't have an Azure subscription, create an Azure free account before you begin.
To effectively create resources with Bicep, you'll need to set up a Bicep development environment. The Bicep
extension for Visual Studio Code provides language support and resource autocompletion. The extension helps
you create and validate Bicep files and is recommended for those developers that will create resources using
Bicep after completing this quickstart.
To deploy a different language stack, update linuxFxVersion with appropriate values. Samples are shown below.
To show current versions, run the following command in the Cloud Shell:
az webapp config show --resource-group myResourceGroup --name <app-name> --query linuxFxVersion
L A N GUA GE EXA M P L E
.NET linuxFxVersion="DOTNETCORE|3.0"
PHP linuxFxVersion="PHP|7.4"
Node.js linuxFxVersion="NODE|10.15"
Python linuxFxVersion="PYTHON|3.7"
Ruby linuxFxVersion="RUBY|2.6"
Clean up resources
When no longer needed, delete the resource group.
Next steps
Bicep documentation
Bicep samples for Azure App Service
Create App Service app using a Terraform template
5/18/2022 • 3 minutes to read • Edit Online
Get started with Azure App Service by deploying an app to the cloud using Terraform. Because you use a free
App Service tier, you incur no costs to complete this quickstart.
Terraform allows you to define and create complete infrastructure deployments in Azure. You build Terraform
templates in a human-readable format that create and configure Azure resources in a consistent, reproducible
manner. This article shows you how to create a Windows app with Terraform.
Prerequisites
Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
Configure Terraform: If you haven't already done so, configure Terraform using one of the following options:
Configure Terraform in Azure Cloud Shell with Bash
Configure Terraform in Azure Cloud Shell with PowerShell
Configure Terraform in Windows with Bash
Configure Terraform in Windows with PowerShell
The Azure Terraform Visual Studio Code extension enables you to work with Terraform from the editor. With this
extension, you can author, test, and run Terraform configurations. The extension also supports resource graph
visualization. See this guide for configuring the Azure Terraform Visual Studio Code extension.
Three Azure resources and one subresource are defined in the template. Links to the Azure Provider Terraform
Registry are given below for further details and usage information:
Microsoft.Resources/resourcegroups : create a Resource Group if one doesn't already exist.
azurerm_resource_group
Microsoft.Web/ser verfarms : create an App Service plan.
azurerm_app_service_plan
Microsoft.Web/sites : create an App Service app.
azurerm_app_service
Microsoft.Web/sites/sourcecontrols : create an external git deployment configuration.
source_control
For further information on how to construct Terraform templates, have a look at the Terraform Learn
documentation.
Implement the Terraform code
Terraform provides many features for managing, building, deploying, and updating infrastructure. The steps
below will just guide you through deploying and destroying your resources. The Terraform Learn
documentation and Terraform on Azure documentation go into more detail and should be reviewed if Terraform
is part of your Azure infrastructure strategy.
1. Create a directory in which to test and run the sample Terraform code and make it the current directory.
mkdir appservice_tf_quickstart
cd appservice_tf_quickstart
code main.tf
3. Initialize Terraform.
terraform init
terraform plan
5. Provision the resources that are defined in the main.tf configuration file (Confirm the action by entering
yes at the prompt).
terraform apply
Clean up resources
When no longer needed, either delete the resource group or head back to your terminal/command line and
execute terraform destroy to delete all resources associated with this quickstart.
NOTE
You can find more Azure App Service Terraform samples here. You can find even more Terraform samples across all of the
Azure services here.
Next steps
Learn more about using Terraform in Azure
Terraform samples for Azure App Service
Monitoring App Service data reference
5/18/2022 • 2 minutes to read • Edit Online
This reference applies to the use of Azure Monitor for monitoring App Service. See Monitoring App Service for
details on collecting and analyzing monitoring data for App Service.
Metrics
This section lists all the automatically collected platform metrics collected for App Service.
For more information, see a list of all platform metrics supported in Azure Monitor.
Metric Dimensions
For more information on what metric dimensions are, see Multi-dimensional metrics.
App Service doesn't have any metrics that contain dimensions.
Resource logs
This section lists the types of resource logs you can collect for App Service.
W IN DO W S L IN UX
LO G T Y P E W IN DO W S C O N TA IN ER L IN UX C O N TA IN ER DESC RIP T IO N
AppServiceAppL ASP.NET ASP.NET Java SE & Java SE & Tomcat Application logs
ogs Tomcat Images 1 Blessed Images 1
1 For Java SE apps, add "$WEBSITE_AZMON_PREVIEW_ENABLED" to the app settings and set it to 1 or to true.
For reference, see a list of all resource logs category types supported in Azure Monitor.
Activity log
The following table lists common operations related to App Service that may be created in the Activity log. This
is not an exhaustive list.
Get Zipped Container Logs for Web App Get container logs
Restore Web App From Backup Blob App restored from backup
For more information on the schema of Activity Log entries, see Activity Log schema.
See Also
See Monitoring Azure App Service for a description of monitoring Azure App Service.
See Monitoring Azure resources with Azure Monitor for details on monitoring Azure resources.
Environment variables and app settings in Azure
App Service
5/18/2022 • 33 minutes to read • Edit Online
In Azure App Service, certain settings are available to the deployment or runtime environment as environment
variables. Some of these settings can be customized when you set them manually as app settings. This reference
shows the variables you can use or customize.
App environment
The following environment variables are related to the app environment in general.
WEBSITE_TIME_ZONE By default, the time zone for the app is Atlantic Standard Time
always UTC. You can change it to any
of the valid values that are listed in
TimeZone. If the specified value isn't
recognized, UTC is used.
Variable prefixes
The following table shows environment variables prefixes that App Service uses for various purposes.
Deployment
The following environment variables are related to app deployment. For variables related to App Service build
automation, see Build automation.
DEPLOYMENT_BRANCH For local Git or cloud Git deployment (such as GitHub), set
to the branch in Azure you want to deploy to. By default, it
is master .
WEBSITE_RUN_FROM_PACKAGE Set to 1 to run the app from a local ZIP package, or set to
the URL of an external URL to run the app from a remote
ZIP package. For more information, see Run your app in
Azure App Service directly from a ZIP package.
WEBSITE_DISABLE_SCM_SEPARATION By default, the main app and the Kudu app run in different
sandboxes. When you stop the app, the Kudu app is still
running, and you can continue to use Git deploy and
MSDeploy. Each app has its own local files. Turning off this
separation (setting to true ) is a legacy mode that's no
longer fully supported.
SET T IN G N A M E DESC RIP T IO N
WEBSITE_ENABLE_SYNC_UPDATE_SITE Set to 1 ensure that REST API calls to update site and
siteconfig are completely applied to all instances before
returning. The default is 1 if deploying with an ARM
template, to avoid race conditions with subsequent ARM
calls.
WEBSITE_START_SCM_WITH_PRELOAD For Linux apps, set to true to force preloading the Kudu
app when Always On is enabled by pinging its URL. The
default is false . For Windows apps, the Kudu app is
always preloaded.
Build automation
Kudu (Windows)
Oryx (Linux)
Kudu build configuration applies to native Windows apps and is used to control the behavior of Git-based (or
ZIP-based) deployments.
Language-specific settings
This section shows the configurable runtime settings for each supported language framework. Additional
settings are available during build automation at deployment time.
.NET
Java
Node.js
Python
PHP
Ruby
PORT Read-only. For Linux apps, port that the .NET runtime listens
to in the container.
WordPress
A P P L IC AT IO N
SET T IN G SC O P E VA L UE MAX DESC RIP T IO N
TLS/SSL
For more information, see Use a TLS/SSL certificate in your code in Azure App Service.
Deployment slots
For more information on deployment slots, see Set up staging environments in Azure App Service.
SET T IN G N A M E DESC RIP T IO N EXA M P L E
Set to true
WEBSITE_SKIP_ALL_BINDINGS_IN_APPHOST_CONFIG or 1 to skip all bindings
in applicationHost.config . The
default is false . If your app triggers
a restart because
applicationHost.config is updated
with the swapped hostnames of th
slots, set this variable to true to
avoid a restart of this kind. If you are
running a Windows Communication
Foundation (WCF) app, do not set this
variable.
Custom containers
For more information on custom containers, see Run a custom container in Azure.
SET T IN G N A M E DESC RIP T IO N EXA M P L E
Scaling
SET T IN G N A M E DESC RIP T IO N
Logging
SET T IN G N A M E DESC RIP T IO N EXA M P L E
Performance counters
The following are 'fake' environment variables that don't exist if you enumerate them, but return their value if
you look them up individually. The value is dynamic and can change on every lookup.
Caching
SET T IN G N A M E DESC RIP T IO N
WEBSITE_READONLY_APP When using dynamic cache, you can disable write access to
the app root ( D:\home\site\wwwroot or
/home/site/wwwroot ) by setting this variable to 1 . Except
for the App_Data directory, no exclusive locks are allowed,
so that deployments don't get blocked by locked files.
Networking
The following environment variables are related to hybrid connections and VNET integration.
WEBSITE_SKIP_CONTENTSHARE_VALIDATION If you set the shared storage connection of your app (using
WEBSITE_CONTENTAZUREFILECONNECTIONSTRING ) to a Key
Vault reference, the app cannot resolve the key vault
reference at app creation or update if one of the following
conditions is true:
- The app accesses the key vault with a system-assigned
identity.
- The app accesses the key vault with a user-assigned
identity, and the key vault is locked with a VNet.
To avoid errors at create or update time, set this variable to
1 .
WEBSITE_DELAY_CERT_DELETION This env var can be set to 1 by users in order to ensure that
a certificate that a worker process is dependent upon is not
deleted until it exits.
CORS
The following environment variables are related to Cross-Origin Resource Sharing (CORS) configuration.
WEBSITE_AUTH_PRESERVE_URL_FRAGMENT When set to true and users click on app links that contain
URL fragments, the login process will ensure that the URL
fragment part of your URL does not get lost in the login
redirect process. For more information, see Customize sign-
in and sign-out in Azure App Service authentication.
WEBSITE_AUTH_STATE_DIRECTORY A local file system directory path where tokens are stored
when the file-based token store is enabled. The default value
is %HOME%\Data\.auth . This application setting is intended
for use with the V1 (classic) configuration experience. If using
the V2 authentication configuration schema, you should
instead use the login.tokenStore.fileSystem.directory
configuration value.
Managed identity
The following environment variables are related to managed identities.
IDENTITY_ENDPOINT Read-only. The URL to retrieve the token for the app's
managed identity.
Health check
The following environment variables are related to health checks.
Push notifications
The following environment variables are related to the push notifications feature.
NOTE
This article contains references to the term whitelist, a term that Microsoft no longer uses. When the term is removed
from the software, we’ll remove it from this article.
Webjobs
The following environment variables are related to WebJobs.
WEBJOBS_IDLE_TIMEOUT For triggered jobs, timeout in seconds, after which the job is
aborted if it's in idle, has no CPU time or output.
WEBJOBS_STOPPED Set to 1 to disable running any job, and stop all currently
running jobs.
WEBJOBS_DISABLE_SCHEDULE Set to 1 to turn off all scheduled triggering. Jobs can still
be manually invoked.
Functions
SET T IN G N A M E DESC RIP T IO N
This page is an index of Azure Policy built-in policy definitions for Azure App Service. For additional Azure Policy
built-ins for other services, see Azure Policy built-in definitions.
The name of each built-in policy definition links to the policy definition in the Azure portal. Use the link in the
Version column to view the source on the Azure Policy GitHub repo.
API App should only be Use of HTTPS ensures Audit, Disabled 1.0.0
accessible over HTTPS server/service
authentication and protects
data in transit from network
layer eavesdropping
attacks.
API apps should use an The content directory of an Audit, Disabled 1.0.0
Azure file share for its API app should be located
content directory on an Azure file share. The
storage account
information for the file
share must be provided
before any publishing
activity. To learn more about
using Azure Files for
hosting app service content
refer to
https://go.microsoft.com/fwl
ink/?linkid=2151594.
App Service Apps should be Injecting App Service Apps Audit, Deny, Disabled 1.0.0
injected into a virtual in a virtual network unlocks
network advanced App Service
networking and security
features and provides you
with greater control over
your network security
configuration. Learn more
at:
https://docs.microsoft.com/
azure/app-service/web-
sites-integrate-with-vnet.
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
App Service apps should By default, if one uses AuditIfNotExists, Disabled 1.0.0
enable outbound non-RFC regional Azure Virtual
1918 traffic to Azure Virtual Network (VNET) integration,
Network the app only routes
RFC1918 traffic into that
respective virtual network.
Using the API to set
'vnetRouteAllEnabled' to
true enables all outbound
traffic into the Azure Virtual
Network. This setting allows
features like network
security groups and user
defined routes to be used
for all outbound traffic from
the App Service app.
App Service apps should With supported SKUs, Audit, Deny, Disabled 2.0.0
use a SKU that supports Azure Private Link lets you
private link connect your virtual
network to Azure services
without a public IP address
at the source or destination.
The Private Link platform
handles the connectivity
between the consumer and
services over the Azure
backbone network. By
mapping private endpoints
to apps, you can reduce
data leakage risks. Learn
more about private links at:
https://aka.ms/private-link.
App Service Environment To ensure apps deployed in Audit, Deny, Disabled 2.0.0
apps should not be an App Service
reachable over public Environment are not
internet accessible over public
internet, one should deploy
App Service Environment
with an IP address in virtual
network. To set the IP
address to a virtual network
IP, the App Service
Environment must be
deployed with an internal
load balancer.
App Service Environment The two most minimal and Audit, Disabled 1.0.0
should be configured with strongest cipher suites
strongest TLS Cipher suites required for App Service
Environment to function
correctly are :
TLS_ECDHE_RSA_WITH_AES
_256_GCM_SHA384 and
TLS_ECDHE_RSA_WITH_AES
_128_GCM_SHA256.
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
App Service Environment Only allow App Service Audit, Deny, Disabled 1.0.0
should be provisioned with Environment version 2 or
latest versions version 3 to be provisioned.
Older versions of App
Service Environment require
manual management of
Azure resources and have
greater scaling limitations.
App Service Environment TLS 1.0 and 1.1 are out-of- Audit, Deny, Disabled 2.0.0
should disable TLS 1.0 and date protocols that do not
1.1 support modern
cryptographic algorithms.
Disabling inbound TLS 1.0
and 1.1 traffic helps secure
apps in an App Service
Environment.
App Service should use a This policy audits any App AuditIfNotExists, Disabled 1.0.0
virtual network service Service not configured to
endpoint use a virtual network
service endpoint.
App Service should use Azure Private Link lets you AuditIfNotExists, Disabled 1.0.0
private link connect your virtual
networks to Azure services
without a public IP address
at the source or destination.
The Private Link platform
handles the connectivity
between the consumer and
services over the Azure
backbone network. By
mapping private endpoints
to App Service, you can
reduce data leakage risks.
Learn more about private
links at:
https://aka.ms/private-link.
App Services should disable Disabling public network AuditIfNotExists, Disabled 1.0.0
public network access access improves security by
ensuring that the App
Service is not exposed on
the public internet. Creating
private endpoints can limit
exposure of an App Service.
Learn more at:
https://aka.ms/app-service-
private-endpoint.
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
Configure App Service slots Disable local authentication DeployIfNotExists, Disabled 1.0.0
to disable local methods for FTP
authentication for FTP deployments so that your
deployments. App Services slots
exclusively require Azure
Active Directory identities
for authentication. Learn
more at:
https://aka.ms/app-service-
disable-basic-auth.
Configure App Service slots Disable local authentication DeployIfNotExists, Disabled 1.0.0
to disable local methods for SCM sites so
authentication for SCM that your App Services slots
sites. exclusively require Azure
Active Directory identities
for authentication. Learn
more at:
https://aka.ms/app-service-
disable-basic-auth.
Ensure API app has 'Client Client certificates allow for Audit, Disabled 1.0.0
Certificates (Incoming client the app to request a
certificates)' set to 'On' certificate for incoming
requests. Only clients that
have a valid certificate will
be able to reach the app.
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
Ensure that 'HTTP Version' Periodically, newer versions AuditIfNotExists, Disabled 2.0.0
is the latest, if used to run are released for HTTP either
the API app due to security flaws or to
include additional
functionality. Using the
latest HTTP version for web
apps to take advantage of
security fixes, if any, and/or
new functionalities of the
newer version. Currently,
this policy only applies to
Linux web apps.
Ensure that 'HTTP Version' Periodically, newer versions AuditIfNotExists, Disabled 2.0.0
is the latest, if used to run are released for HTTP either
the Function app due to security flaws or to
include additional
functionality. Using the
latest HTTP version for web
apps to take advantage of
security fixes, if any, and/or
new functionalities of the
newer version. Currently,
this policy only applies to
Linux web apps.
Ensure that 'HTTP Version' Periodically, newer versions AuditIfNotExists, Disabled 2.0.0
is the latest, if used to run are released for HTTP either
the Web app due to security flaws or to
include additional
functionality. Using the
latest HTTP version for web
apps to take advantage of
security fixes, if any, and/or
new functionalities of the
newer version. Currently,
this policy only applies to
Linux web apps.
Ensure that 'Java version' is Periodically, newer versions AuditIfNotExists, Disabled 2.0.0
the latest, if used as a part are released for Java either
of the API app due to security flaws or to
include additional
functionality. Using the
latest Python version for
API apps is recommended
in order to take advantage
of security fixes, if any,
and/or new functionalities
of the latest version.
Currently, this policy only
applies to Linux web apps.
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
Ensure that 'Java version' is Periodically, newer versions AuditIfNotExists, Disabled 2.0.0
the latest, if used as a part are released for Java
of the Function app software either due to
security flaws or to include
additional functionality.
Using the latest Java
version for Function apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
Ensure that 'Java version' is Periodically, newer versions AuditIfNotExists, Disabled 2.0.0
the latest, if used as a part are released for Java
of the Web app software either due to
security flaws or to include
additional functionality.
Using the latest Java
version for web apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
Ensure that 'PHP version' is Periodically, newer versions AuditIfNotExists, Disabled 2.1.0
the latest, if used as a part are released for PHP
of the API app software either due to
security flaws or to include
additional functionality.
Using the latest PHP
version for API apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
Ensure that 'PHP version' is Periodically, newer versions AuditIfNotExists, Disabled 2.2.0
the latest, if used as a part are released for PHP
of the WEB app software either due to
security flaws or to include
additional functionality.
Using the latest PHP
version for web apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
Ensure that 'Python version' Periodically, newer versions AuditIfNotExists, Disabled 3.0.0
is the latest, if used as a are released for Python
part of the API app software either due to
security flaws or to include
additional functionality.
Using the latest Python
version for API apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
Ensure that 'Python version' Periodically, newer versions AuditIfNotExists, Disabled 3.0.0
is the latest, if used as a are released for Python
part of the Function app software either due to
security flaws or to include
additional functionality.
Using the latest Python
version for Function apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
Ensure that 'Python version' Periodically, newer versions AuditIfNotExists, Disabled 3.0.0
is the latest, if used as a are released for Python
part of the Web app software either due to
security flaws or to include
additional functionality.
Using the latest Python
version for web apps is
recommended in order to
take advantage of security
fixes, if any, and/or new
functionalities of the latest
version. Currently, this
policy only applies to Linux
web apps.
Ensure WEB app has 'Client Client certificates allow for Audit, Disabled 1.0.0
Certificates (Incoming client the app to request a
certificates)' set to 'On' certificate for incoming
requests. Only clients that
have a valid certificate will
be able to reach the app.
Function App should only Use of HTTPS ensures Audit, Disabled 1.0.0
be accessible over HTTPS server/service
authentication and protects
data in transit from network
layer eavesdropping
attacks.
Function apps should have Client certificates allow for Audit, Disabled 1.0.1
'Client Certificates the app to request a
(Incoming client certificate for incoming
certificates)' enabled requests. Only clients with
valid certificates will be able
to reach the app.
Function apps should use The content directory of a Audit, Disabled 1.0.0
an Azure file share for its function app should be
content directory located on an Azure file
share. The storage account
information for the file
share must be provided
before any publishing
activity. To learn more about
using Azure Files for
hosting app service content
refer to
https://go.microsoft.com/fwl
ink/?linkid=2151594.
Latest TLS version should Upgrade to the latest TLS AuditIfNotExists, Disabled 1.0.0
be used in your API App version
Latest TLS version should Upgrade to the latest TLS AuditIfNotExists, Disabled 1.0.0
be used in your Function version
App
Latest TLS version should Upgrade to the latest TLS AuditIfNotExists, Disabled 1.0.0
be used in your Web App version
Managed identity should be Use a managed identity for AuditIfNotExists, Disabled 2.0.0
used in your API App enhanced authentication
security
Managed identity should be Use a managed identity for AuditIfNotExists, Disabled 2.0.0
used in your Function App enhanced authentication
security
Managed identity should be Use a managed identity for AuditIfNotExists, Disabled 2.0.0
used in your Web App enhanced authentication
security
NAME VERSIO N
DESC RIP T IO N EF F EC T ( S)
Web apps should use an The content directory of a Audit, Disabled 1.0.0
Azure file share for its web app should be located
content directory on an Azure file share. The
storage account
information for the file
share must be provided
before any publishing
activity. To learn more about
using Azure Files for
hosting app service content
refer to
https://go.microsoft.com/fwl
ink/?linkid=2151594.
Next steps
See the built-ins on the Azure Policy GitHub repo.
Review the Azure Policy definition structure.
Review Understanding policy effects.
Azure subscription and service limits, quotas, and
constraints
5/18/2022 • 130 minutes to read • Edit Online
This document lists some of the most common Microsoft Azure limits, which are also sometimes called quotas.
To learn more about Azure pricing, see Azure pricing overview. There, you can estimate your costs by using the
pricing calculator. You also can go to the pricing details page for a particular service, for example, Windows VMs.
For tips to help manage your costs, see Prevent unexpected costs with Azure billing and cost management.
Managing limits
NOTE
Some services have adjustable limits.
When a service doesn't have adjustable limits, the following tables use the header Limit . In those cases, the default and
the maximum limits are the same.
When the limit can be adjusted, the tables include Default limit and Maximum limit headers. The limit can be raised
above the default limit but not above the maximum limit.
If you want to raise the limit or quota above the default limit, open an online customer support request at no charge.
The terms soft limit and hard limit often are used informally to describe the current, adjustable limit (soft limit) and the
maximum limit (hard limit). If a limit isn't adjustable, there won't be a soft limit, only a hard limit.
Free Trial subscriptions aren't eligible for limit or quota increases. If you have a Free Trial subscription, you can
upgrade to a Pay-As-You-Go subscription. For more information, see Upgrade your Azure Free Trial subscription
to a Pay-As-You-Go subscription and the Free Trial subscription FAQ.
Some limits are managed at a regional level.
Let's use vCPU quotas as an example. To request a quota increase with support for vCPUs, you must decide how
many vCPUs you want to use in which regions. You then request an increase in vCPU quotas for the amounts
and regions that you want. If you need to use 30 vCPUs in West Europe to run your application there, you
specifically request 30 vCPUs in West Europe. Your vCPU quota isn't increased in any other region--only West
Europe has the 30-vCPU quota.
As a result, decide what your quotas must be for your workload in any one region. Then request that amount in
each region into which you want to deploy. For help in how to determine your current quotas for specific
regions, see Resolve errors for resource quotas.
General limits
For limits on resource names, see Naming rules and restrictions for Azure resources.
For information about Resource Manager API read and write limits, see Throttling Resource Manager requests.
Management group limits
The following limits apply to management groups.
RESO URC E L IM IT
RESO URC E L IM IT
1You can apply up to 50 tags directly to a subscription. However, the subscription can contain an unlimited
number of tags that are applied to resource groups and resources within the subscription. The number of tags
per resource or resource group is limited to 50.
2Resource Manager returns a list of tag name and values in the subscription only when the number of unique
tags is 80,000 or less. A unique tag is defined by the combination of resource ID, tag name, and tag value. For
example, two resources with the same tag name and value would be calculated as two unique tags. You still can
find a resource by tag when the number exceeds 80,000.
3Deployments are automatically deleted from the history as you near the limit. For more information, see
Automatic deletions from deployment history.
Resource group limits
RESO URC E L IM IT
Resources per resource group Resources aren't limited by resource group. Instead, they're
limited by resource type in a resource group. See next row.
Resources per resource group, per resource type 800 - Some resource types can exceed the 800 limit. See
Resources not limited to 800 instances per resource group.
1Deployments are automatically deleted from the history as you near the limit. Deleting an entry from the
deployment history doesn't affect the deployed resources. For more information, see Automatic deletions from
deployment history.
Template limits
VA L UE L IM IT
Parameters 256
Variables 256
Outputs 64
Template size 4 MB
You can exceed some template limits by using a nested template. For more information, see Use linked
templates when you deploy Azure resources. To reduce the number of parameters, variables, or outputs, you can
combine several values into an object. For more information, see Objects as parameters.
You may get an error with a template or parameter file of less than 4 MB, if the total size of the request is too
large. For more information about how to simplify your template to avoid a large request, see Resolve errors for
job size exceeded.
C AT EGO RY L IM IT
Access Panel There's no limit to the number of applications per user that
can be displayed in the Access Panel, regardless of the
number of assigned licenses.
Azure AD roles and permissions A maximum of 100 Azure AD custom roles can be
created in an Azure AD organization.
A maximum of 150 Azure AD custom role
assignments for a single principal at any scope.
A maximum of 100 Azure AD built-in role
assignments for a single principal at non-tenant
scope (such as an administrative unit or Azure AD
object). There is no limit to Azure AD built-in role
assignments at tenant scope.
A group can't be added as a group owner.
A user's ability to read other users' tenant
information can be restricted only by the Azure AD
organization-wide switch to disable all non-admin
users' access to all tenant information (not
recommended). For more information, see To restrict
the default permissions for member users.
It might take up to 15 minutes or you might have to
sign out and sign back in before admin role
membership additions and revocations take effect.
1 Scaling limits depend on the pricing tier. For details on the pricing tiers and their scaling limits, see API
Management pricing.
2 Per unit cache size depends on the pricing tier. To see the pricing tiers and their scaling limits, see API
Management pricing.
3 Connections are pooled and reused unless explicitly closed by the back end.
4 This limit is per unit of the Basic, Standard, and Premium tiers. The Developer tier is limited to 1,024. This limit
limited to 16 KiB.
6 Multiple custom domains are supported in the Developer and Premium tiers only.
7 CA certificates are not supported in the Consumption tier.
8 This limit applies to the Consumption tier only. There are no limits in these categories for other tiers.
9 Applies to the Consumption tier only. Includes an up to 2048-bytes long query string.
10 To increase this limit, contact support.
11 Self-hosted gateways are supported in the Developer and Premium tiers only. The limit applies to the number
of self-hosted gateway resources. To raise this limit contact support. Note, that the number of nodes (or replicas)
associated with a self-hosted gateway resource is unlimited in the Premium tier and capped at a single node in
the Developer tier.
App Service 10 per region 10 per 100 per 100 per 100 per 100 per
plan resource resource resource resource resource
group group group group group
P REM IUM
RESO URC E F REE SH A RED B A SIC STA N DA RD ( V1- V3) ISO L AT ED
The available
storage quota
is 999 GB.
Concurrent 1 1 1 5 5 5
debugger
connections
per
application
Custom Not Not Unlimited SNI Unlimited SNI Unlimited SNI Unlimited SNI
domain SSL supported, supported, SSL SSL and 1 IP SSL and 1 IP SSL and 1 IP
support wildcard wildcard connections SSL SSL SSL
certificate for certificate for connections connections connections
*.azurewebsit *.azurewebsit included included included
es.net es.net
available by available by
default default
Hybrid 5 per plan 25 per plan 220 per app 220 per app
connections
Virtual X X X
Network
Integration
Integrated X X X X X9
load balancer
Access 512 rules per 512 rules per 512 rules per 512 rules per 512 rules per 512 rules per
restrictions app app app app app app
Always On X X X X
Autoscale X X X
WebJobs10 X X X X X X
Endpoint X X X X
monitoring
Staging slots 5 20 20
per app
Testing in X X X
Production
P REM IUM
RESO URC E F REE SH A RED B A SIC STA N DA RD ( V1- V3) ISO L AT ED
Diagnostic X X X X X X
Logs
Kudu X X X X X X
Authenticatio X X X X X X
n and
Authorization
App Service X X X X
Managed
Certificates11
1 Apps and storage quotas are per App Service plan unless noted otherwise.
2 The actual number of apps that you can host on these machines depends on the activity of the apps, the size of
the machine instances, and the corresponding resource utilization.
3 Dedicated instances can be of different sizes. For more information, see App Service pricing.
4 More are allowed upon request.
5 The storage limit is the total content size across all apps in the same App service plan. The total content size of
all apps across all App service plans in a single resource group and region cannot exceed 500 GB. The file
system quota for App Service hosted apps is determined by the aggregate of App Service plans created in a
region and resource group.
6 These resources are constrained by physical resources on the dedicated instances (the instance size and the
number of instances).
7 If you scale an app in the Basic tier
to two instances, you have 350 concurrent connections for each of the two
instances. For Standard tier and above, there are no theoretical limits to web sockets, but other factors can limit
the number of web sockets. For example, maximum concurrent requests allowed (defined by
maxConcurrentRequestsPerCpu ) are: 7,500 per small VM, 15,000 per medium VM (7,500 x 2 cores), and 75,000
per large VM (18,750 x 4 cores).
8 The maximum IP connections are per instance and depend on the instance size: 1,920 per B1/S1/P1V3
instance, 3,968 per B2/S2/P2V3 instance, 8,064 per B3/S3/P3V3 instance.
9 App Service Isolated SKUs can be internally load balanced (ILB) with Azure Load Balancer, so there's no public
connectivity from the internet. As a result, some features of an ILB Isolated App Service must be used from
machines that have direct access to the ILB network endpoint.
10 Run custom executables and/or scripts on demand, on a schedule, or continuously as a background task
within your App Service instance. Always On is required for continuous WebJobs execution. There's no
predefined limit on the number of WebJobs that can run in an App Service instance. There are practical limits
that depend on what the application code is trying to do.
11 Only issuing standard certificates (wildcard certificates aren't available). Limited to only one free certificate
RESO URC E L IM IT N OT ES
Maximum number of new jobs that 100 When this limit is reached, the
can be submitted every 30 seconds subsequent requests to create a job
per Azure Automation account fail. The client receives an error
(nonscheduled jobs) response.
Maximum storage size of job metadata 10 GB (approximately 4 million jobs) When this limit is reached, the
for a 30-day rolling period subsequent requests to create a job
fail.
Maximum job stream limit 1 MiB A single stream cannot be larger than
1 MiB.
Job run time, Free tier 500 minutes per subscription per
calendar month
1A sandbox is a shared environment that can be used by multiple jobs. Jobs that use the same sandbox are
RESO URC E L IM IT N OT ES
File 500
File size 5 MB
Registry 250
Services 250
Daemon 250
Update Management
The following table shows the limits for Update Management.
RESO URC E L IM IT N OT ES
Configuration store requests for Free 1,000 requests per day Once the quota is exhausted, HTTP
tier status code 429 will be returned for all
requests until the end of the day
Configuration store requests for 30,000 per hour Once the quota is exhausted, requests
Standard tier may return HTTP status code 429
indicating Too Many Requests - until
the end of the hour
Databases 64
Azure Cache for Redis limits and sizes are different for each pricing tier. To see the pricing tiers and their
associated sizes, see Azure Cache for Redis pricing.
For more information on Azure Cache for Redis configuration limits, see Default Redis server configuration.
Because configuration and management of Azure Cache for Redis instances is done by Microsoft, not all Redis
commands are supported in Azure Cache for Redis. For more information, see Redis commands not supported
in Azure Cache for Redis.
1Each Azure Cloud Service with web or worker roles can have two deployments, one for production and one for
staging. This limit refers to the number of distinct roles, that is, configuration. This limit doesn't refer to the
number of instances per role, that is, scaling.
RESO URC
E F REE 1 B A SIC S1 S2 S3 S3 H D L1 L2
Maximu 1 16 16 8 6 6 6 6
m
services
Maximu N/A 3 SU 36 SU 36 SU 36 SU 36 SU 36 SU 36 SU
m scale in
search
units
(SU)2
1 Free is based on infrastructure that's shared with other customers. Because the hardware isn't dedicated, scale-
up isn't supported on the free tier.
2 Search units are billing units, allocated as either
a replica or a partition. You need both resources for storage,
indexing, and query operations. To learn more about SU computations, see Scale resource levels for query and
index workloads.
Limits per search ser vice
A search service is constrained by disk space or by a hard limit on the maximum number of indexes or indexers,
whichever comes first. The following table documents storage limits. For maximum object limits, see Limits by
resource.
RESO URC
E F REE B A SIC 1 S1 S2 S3 S3 H D L1 L2
Partitions N/A 1 12 12 12 3 12 12
per
service
Replicas N/A 3 12 12 12 12 12 12
1 Basic has one fixed partition. Additional search units can be used to add replicas for larger query volumes.
2 Service level agreements are in effect forbillable services on dedicated resources. Free services and preview
features have no SLA. For billable services, SLAs take effect when you provision sufficient redundancy for your
service. Two or more replicas are required for query (read) SLAs. Three or more replicas are required for query
and indexing (read-write) SLAs. The number of partitions isn't an SLA consideration.
To learn more about limits on a more granular level, such as document size, queries per second, keys, requests,
and responses, see Service limits in Azure Cognitive Search.
TYPE L IM IT EXA M P L E
A mixture of Cognitive Services Maximum of 200 total Cognitive 100 Computer Vision resources in
resources Services resources per region. West US, 50 Speech Service resources
in West US, and 50 Text Analytics
resources in West US.
A single type of Cognitive Services Maximum of 100 resources per region 100 Computer Vision resources in
resources. West US 2, and 100 Computer Vision
resources in East US.
RESO URC E L IM IT
The following table describes the limits on management operations performed on Azure Data Explorer clusters.
SC O P E O P ERAT IO N L IM IT
App Service 100 per region 100 per resource 100 per resource - -
plans group group
Custom domain unbounded SNI unbounded SNI unbounded SNI unbounded SNI n/a
SSL support SSL connection SSL and 1 IP SSL SSL and 1 IP SSL SSL and 1 IP SSL
included connections connections connections
included included included
1 By default, the timeout for the Functions 1.x runtime in an App Service plan is unbounded.
2 Requires the App Service plan be set to Always On. Pay at standard rates.
3 These limits are set in the host.
4 The actual number of function apps that you can host depends on the activity of the apps, the size of the
machine instances, and the corresponding resource utilization.
5 The storage limit is the total content size in temporary storage across all apps in the same App Service plan.
apps in a Premium plan or an App Service plan, you can map a custom domain using either a CNAME or an A
record.
7 Guaranteed for up to 60 minutes.
8 Workers are roles that host customer apps. Workers are available in three fixed sizes: One vCPU/3.5 GB RAM;
Request Units (RUs) 10,000 RUs Contact support Maximum You need a minimum of
available is 1,000,000. 400 RUs or 40 RUs/GB,
whichever is larger.
Maximum nodes per cluster with Virtual Machine Scale Sets 1000 (across all node pools)
and Standard Load Balancer SKU
Maximum pods per node: Basic networking with Kubenet Maximum: 250
Azure CLI default: 110
Azure Resource Manager template default: 110
Azure portal deployment default: 30
RESO URC E L IM IT
Maximum pods per node: Advanced networking with Azure Maximum: 250
Container Networking Interface Default: 30
Open Service Mesh (OSM) AKS addon Kubernetes Cluster Version: 1.19+
OSM controllers per cluster: 1
Pods per OSM controller: 500
Kubernetes service accounts managed by OSM: 50
K UB ERN ET ES C O N T RO L P L A N E T IER L IM IT
The following table shows the cumulative data size limit for Azure Maps accounts in an Azure subscription. The
Azure Maps Data service is available only at the S1 pricing tier.
RESO URC E L IM IT
For more information on the Azure Maps pricing tiers, see Azure Maps pricing.
Metric alerts (classic) 100 active alert rules per subscription. Call support
RESO URC E DEFA ULT L IM IT M A XIM UM L IM IT
Activity log alerts 100 active alert rules per subscription Same as default
(cannot be increased).
Alert processing rules 1000 active rules per subscription. Call support
Alert rules and alert processing rules Log search alerts 4096 characters Same as default
description length All other 2048 characters
Alerts API
Azure Monitor Alerts have several throttling limits to protect against users making an excessive number of calls.
Such behavior can potentially overload the system backend resources and jeopardize service responsiveness.
The following limits are designed to protect customers from interruptions and ensure consistent service level.
The user throttling and limits are designed to impact only extreme usage scenario and should not be relevant
for typical usage.
Alerts - Get Summary 50 calls per minute per subscription Same as default
Alerts - Get All (not "Get By Id") 100 calls per minute per subscription Same as default
All other alerts calls 1000 calls per minute per subscription Same as default
Action groups
You may have an unlimited number of action groups in a subscription.
Azure app push 10 Azure app actions per action group. Same as Default
Email ARM role 10 Email ARM role actions per action Same as Default
group.
Autoscale
RESO URC E DEFA ULT L IM IT M A XIM UM L IM IT
Query language Azure Monitor uses the same Kusto query language as
Azure Data Explorer. See Azure Monitor log query language
differences for KQL language elements not supported in
Azure Monitor.
Azure regions Log queries can experience excessive overhead when data
spans Log Analytics workspaces in multiple Azure regions.
See Query limits for details.
L IM IT DESC RIP T IO N
Cross resource queries Maximum number of Application Insights resources and Log
Analytics workspaces in a single query limited to 100.
Cross-resource query is not supported in View Designer.
Cross-resource query in log alerts is supported in the new
scheduledQueryRules API.
See Cross-resource query limits for details.
Time in concurrency queue 3 minutes If a query sits in the queue for more
than 3 minutes without being started,
it will be terminated with an HTTP
error response with code 429.
Total queries in concurrency queue 200 Once the number of queries in the
queue reach 200, the next query will
be rejected with an HTTP error code
429. This number is in addition to the
five queries that can be running
simultaneously.
Query rate 200 queries per 30 seconds Overall rate of queries that can be
submitted by a single user to all
workspaces. This limit applies to
programmatic queries or queries
initiated by visualization parts such as
Azure dashboards and the Log
Analytics workspace summary page.
Current Per GB pricing tier No limit 30 - 730 days Data retention beyond 31
(introduced April 2018) days is available for
additional charges. Learn
more about Azure Monitor
pricing.
Legacy Per Node (OMS) No limit 30 to 730 days Data retention beyond 31
(introduced April 2016) days is available for
additional charges. Learn
more about Azure Monitor
pricing.
C AT EGO RY L IM IT C O M M EN T S
Maximum records returned by a log 30,000 Reduce results using query scope, time
query range, and filters in the query.
Maximum size for a single post 30 MB Split larger volumes into multiple
posts.
Maximum size for field values 32 KB Fields longer than 32 KB are truncated.
Quer y API
C AT EGO RY L IM IT C O M M EN T S
Maximum size of data returned ~104 MB (~100 MiB) The API returns up to 64 MB of
compressed data, which translates to
up to 100 MB of raw data.
Maximum request rate 200 requests per 30 seconds per See Log queries and language.
Azure AD user or client IP address
C AT EGO RY L IM IT C O M M EN T S
Max size of data ~16.7 MB (~16 MiB) The connector infrastructure dictates
that limit is set lower than query API
limit
C AT EGO RY L IM IT C O M M EN T S
NOTE
Depending on how long you've been using Log Analytics, you might have access to legacy pricing tiers. Learn more about
Log Analytics legacy pricing tiers.
Application Insights
There are some limits on the number of metrics and events per application, that is, per instrumentation key.
Limits depend on the pricing plan that you choose.
Total data per day 100 GB Contact support You can reduce data by
setting a cap. If you need
more data, you can increase
the limit in the portal, up to
1,000 GB. For capacities
greater than 1,000 GB,
send email to
[email protected].
Data retention Logs 30 - 730 days 730 days This resource is for Logs.
Snapshot data sent per day 30 snapshots per day per No limit The number of snapshots
monitored app collected per application can
be modified through
configuration.
For more information, see About pricing and quotas in Application Insights.
Concurrent Data Integration Units1 Region group 12 : 6,000 Region group 12 : 6,000
consumption per subscription per Region group 22 : 3,000 Region group 22 : 3,000
Azure Integration Runtime region Region group 32 : 1,500 Region group 32 : 1,500
Managed virtual network2 : 2,400 Managed virtual network: Contact
support.
ForEach parallelism 20 50
1 The data integration unit (DIU) is used in a cloud-to-cloud copy operation, learn more from Data integration
units (version 2). For information on billing, see Azure Data Factory pricing.
2 Azure Integration Runtime is globally available to ensure data compliance, efficiency, and reduced network
egress costs.
Region group 1 Central US, East US, East US 2, North Europe, West Europe,
West US, West US 2
If managed virtual network is enabled, the data integration unit (DIU) in all region groups are 2,400.
3 Pipeline, data set, and linked service objects represent a logical grouping of your workload. Limits for these
objects don't relate to the amount of data you can move and process with Azure Data Factory. Data Factory is
designed to scale to handle petabytes of data.
4 The payload for each activity run includes the activity configuration, the associated dataset(s) and linked
service(s) configurations if any, and a small portion of system properties generated per activity type. Limit for
this payload size doesn't relate to the amount of data you can move and process with Azure Data Factory. Learn
about the symptoms and recommendation if you hit this limit.
Version 1
RESO URC E DEFA ULT L IM IT M A XIM UM L IM IT
Retry count for pipeline activity runs 1,000 MaxInt (32 bit)
1 Pipeline, data set, and linked service objects represent a logical grouping of your
workload. Limits for these
objects don't relate to the amount of data you can move and process with Azure Data Factory. Data Factory is
designed to scale to handle petabytes of data.
2 On-demand HDInsight cores are allocated out of the subscription that contains the data factory. As a result, the
previous limit is the Data Factory-enforced core limit for on-demand HDInsight cores. It's different from the core
limit that's associated with your Azure subscription.
3 The cloud data movement unit (DMU) for version 1 is used in a cloud-to-cloud copy operation, learn more
from Cloud data movement units (version 1). For information on billing, see Azure Data Factory pricing.
W H ERE W H AT M A XIM UM C O UN T
Policy rules have additional limits to the number of conditions and their complexity. See Policy rule limits for
more details.
While on the Learn & Develop SKU, you cannot request an increase on your quota limits. Instead you should
switch to the Performance at Scale SKU.
Performance at Scale SKU
Solver hours 1,000 hours per month up to 50,000 hours per month
RESO URC E L IM IT
1If you require over 500 Application groups then please raise a support ticket via the Azure portal.
All other Azure resources used in Azure Virtual Desktop such as Virtual Machines, Storage, Networking etc. are
all subject to their own resource limitations documented in the relevant sections of this article. To visualise the
relationship between all the Azure Virtual Desktop objects, review this article Relationships between Azure
Virtual Desktop logical components.
To get started with Azure Virtual Desktop, use the getting started guide. For deeper architectural content for
Azure Virtual Desktop, use the Azure Virtual Desktop section of the Cloud Adoption Framework. For pricing
information for Azure Virtual Desktop, add "Azure Virtual Desktop" within the Compute section of the Azure
Pricing Calculator.
RESO URC E L IM IT
vSAN capacity limits 75% of total usable (keep 25% available for SLA)
For other VMware-specific limits, use the VMware configuration maximum tool!.
Backup limits
For a summary of Azure Backup support settings and limitations, see Azure Backup Support Matrices.
Batch limits
RESO URC E DEFA ULT L IM IT M A XIM UM L IM IT
NOTE
Default limits vary depending on the type of subscription you use to create a Batch account. Cores quotas shown are for
Batch accounts in Batch service mode. View the quotas in your Batch account.
IMPORTANT
To help us better manage capacity during the global health pandemic, the default core quotas for new Batch accounts in
some regions and for some types of subscription have been reduced from the above range of values, in some cases to
zero cores. When you create a new Batch account, check your core quota and request a core quota increase, if required.
Alternatively, consider reusing Batch accounts that already have sufficient quota.
1Extra small instances count as one vCPU toward the vCPU limit despite using a partial CPU core.
2The storage account limit includes both Standard and Premium storage accounts.
Standard sku cores (CPUs) for K80 GPU per region per 181,2
subscription
Standard sku cores (CPUs) for P100 or V100 GPU per region 01,2
per subscription
Ports per IP 5
1To request a limit increase, create an Azure Support request. Free subscriptions including Azure Free Account
and Azure for Students aren't eligible for limit or quota increases. If you have a free subscription, you can
upgrade to a Pay-As-You-Go subscription.
2Default limit for Pay-As-You-Go subscription. Limit may differ for other category types.
Container Registry limits
The following table details the features and limits of the Basic, Standard, and Premium service tiers.
Webhooks 2 10 500
1 Storage included in the daily rate for each tier. Additional storage may be used, up to the registry storage limit,
at an additional daily rate per GiB. For rate information, see Azure Container Registry pricing. If you need
storage beyond the registry storage limit, please contact Azure Support.
2ReadOps, WriteOps, and Bandwidth are minimum estimates. Azure Container Registry strives to improve
performance as usage requires.
3A docker pull translates to multiple read operations based on the number of layers in the image, plus the
manifest retrieval.
4A docker push translates to multiple write operations, based on the number of layers that must be pushed. A
docker push includes ReadOps to retrieve a manifest for an existing image.
A Content Delivery Network subscription can contain one or more Content Delivery Network profiles. A Content
Delivery Network profile can contain one or more Content Delivery Network endpoints. You might want to use
multiple profiles to organize your Content Delivery Network endpoints by internet domain, web application, or
some other criteria.
Concurrent Data Integration Units1 Region group 12 : 6,000 Region group 12 : 6,000
consumption per subscription per Region group 22 : 3,000 Region group 22 : 3,000
Azure Integration Runtime region Region group 32 : 1,500 Region group 32 : 1,500
Managed virtual network2 : 2,400 Managed virtual network: Contact
support.
ForEach parallelism 20 50
1 The data integration unit (DIU) is used in a cloud-to-cloud copy operation, learn more from Data integration
units (version 2). For information on billing, see Azure Data Factory pricing.
2 Azure Integration Runtime is globally available to ensure data compliance, efficiency, and reduced network
egress costs.
Region group 1 Central US, East US, East US 2, North Europe, West Europe,
West US, West US 2
If managed virtual network is enabled, the data integration unit (DIU) in all region groups are 2,400.
3 Pipeline, data set, and linked service objects represent a logical grouping of your
workload. Limits for these
objects don't relate to the amount of data you can move and process with Azure Data Factory. Data Factory is
designed to scale to handle petabytes of data.
4 The payload for each activity run includes the activity configuration, the associated dataset(s) and linked
service(s) configurations if any, and a small portion of system properties generated per activity type. Limit for
this payload size doesn't relate to the amount of data you can move and process with Azure Data Factory. Learn
about the symptoms and recommendation if you hit this limit.
Version 1
RESO URC E DEFA ULT L IM IT M A XIM UM L IM IT
Retry count for pipeline activity runs 1,000 MaxInt (32 bit)
1 Pipeline, data set, and linked service objects represent a logical grouping of your
workload. Limits for these
objects don't relate to the amount of data you can move and process with Azure Data Factory. Data Factory is
designed to scale to handle petabytes of data.
2 On-demand HDInsight cores are allocated out of the subscription that contains the data factory. As a result, the
previous limit is the Data Factory-enforced core limit for on-demand HDInsight cores. It's different from the core
limit that's associated with your Azure subscription.
3 The cloud data movement unit (DMU) for version 1 is used in a cloud-to-cloud copy operation, learn more
from Cloud data movement units (version 1). For information on billing, see Azure Data Factory pricing.
RESO URC E L IM IT C O M M EN T S
Maximum number of access ACLs, per 32 This is a hard limit. Use groups to
file or folder manage access with fewer entries.
Maximum number of default ACLs, per 32 This is a hard limit. Use groups to
file or folder manage access with fewer entries.
RESO URC E L IM IT
RESO URC E L IM IT C O M M EN T S
This table provides the limits for the Device Update for IoT Hub resource in Azure Resource Manager:
This table provides the various limits associated with the operations within Device Update for IoT Hub:
Number of update 25 25 No
providers per instance
Functional limits
The following table lists the functional limits of Azure Digital Twins.
TIP
For modeling recommendations to operate within these functional limits, see Modeling best practices.
Rate limits
The following table reflects the rate limits of different APIs.
Other limits
Limits on data types and fields within DTDL documents for Azure Digital Twins models can be found within its
spec documentation in GitHub: Digital Twins Definition Language (DTDL) - version 2.
Query latency details are described in Query language. Limitations of particular query language features can be
found in the query reference documentation.
NOTE
These limits are per region.
RESO URC E L IM IT
Publish rate for a custom or a partner topic (ingress) 5,000 events/sec or 5 MB/sec (whichever is met first)
Event size 1 MB
This limit can't be increased.
RESO URC E L IM IT
Publish rate for an event domain (ingress) 5,000 events/sec or 5 MB/sec (whichever is met first)
L IM IT N OT ES VA L UE
Size of a consumer group name Kafka protocol doesn't require the Kafka: 256 characters
creation of a consumer group.
AMQP: 50 characters
NOTE
In the table, CU is capacity unit, PU is processing unit, and TU is throughput unit.
You can configure TUs for a basic or standard tier namespace or PUs for a premium tier namespace.
When you create a dedicated cluster, 1 CU is assigned to the cluster. To have more CUs for the cluster, submit a ticket.
Number of partitions 32 32 100 per event hub, 1024 per event hub
per event hub but there is a limit of 2000 per CU
200 per PU at the
namespace level.
For example, if a
namespace is
assigned 2 PUs, the
limit for total number
of partitions in all
event hubs in the
namespace is 2 * 200
= 400.
L IM IT B A SIC STA N DA RD P REM IUM DEDIC AT ED
Throughput per unit Ingress - 1 MB/s or Ingress - 1 MB/s or No limits per PU * No limits per CU *
1000 events per 1000 events per
second second
Egress – 2 MB/s or Egress – 2 MB/s or
4096 events per 4096 events per
second second
* Depends on various factors such as resource allocation, number of partitions, storage, and so on.
NOTE
You can publish events individually or batched. The publication limit (according to SKU) applies regardless of whether it is
a single event or a batch. Publishing events larger than the maximum threshold will be rejected.
The following table lists the limits that apply to IoT Hub resources.
RESO URC E L IM IT
Maximum size of device-to-cloud batch AMQP and HTTP: 256 KB for the entire batch
MQTT: 256 KB for each message
Maximum size of device twin 8 KB for tags section, and 32 KB for desired and reported
properties sections each
Maximum additional endpoints (beyond built-in endpoints) 10 (for S1, S2, and S3)
Maximum message routing rules 100 (for S1, S2, and S3)
Maximum number of concurrently connected device streams 50 (for S1, S2, S3, and F1 only)
Maximum device stream data transfer 300 MB per day (for S1, S2, S3, and F1 only)
NOTE
If you need more than 50 paid IoT hubs in an Azure subscription, contact Microsoft Support.
NOTE
Currently, the total number of devices plus modules that can be registered to a single IoT hub is capped at 1,000,000. If
you want to increase this limit, contact Microsoft Support.
IoT Hub throttles requests when the following quotas are exceeded.
T H ROT T L E P ER- H UB VA L UE
Device connections 6,000/sec/unit (for S3), 120/sec/unit (for S2), 12/sec/unit (for
S1).
Minimum of 100/sec.
Device-to-cloud sends 6,000/sec/unit (for S3), 120/sec/unit (for S2), 12/sec/unit (for
S1).
Minimum of 100/sec.
Direct methods 24 MB/sec/unit (for S3), 480 KB/sec/unit (for S2), 160
KB/sec/unit (for S1).
Based on 8-KB throttling meter size.
T H ROT T L E P ER- H UB VA L UE
Device twin updates 250/sec/unit (for S3), Maximum of 50/sec or 5/sec/unit (for
S2), 50/sec (for S1)
Jobs per-device operation throughput 50/sec/unit (for S3), maximum of 10/sec or 1/sec/unit (for
S2), 10/sec (for S1).
Device stream initiation rate 5 new streams/sec (for S1, S2, S3, and F1 only).
The following table lists the limits that apply to Azure IoT Hub Device Provisioning Service resources.
TIP
If the hard limit on symmetric key enrollment groups is a blocking issue, it is recommended to use individual enrollments
as a workaround.
H SM K EY SO F T WA RE K EY
H SM K EY A L L OT H ER SO F T WA RE K EY A L L OT H ER
K EY T Y P E C REAT E K EY T RA N SA C T IO N S C REAT E K EY T RA N SA C T IO N S
For information on how to handle throttling when these limits are exceeded, see Azure Key Vault throttling
guidance.
1 A subscription-wide limit forall transaction types is five times per key vault limit. For example, HSM-other
transactions per subscription are limited to 10,000 transactions in 10 seconds per subscription.
Backup keys, secrets, certificates
When you back up a key vault object, such as a secret, key, or certificate, the backup operation will download the
object as an encrypted blob. This blob cannot be decrypted outside of Azure. To get usable data from this blob,
you must restore the blob into a key vault within the same Azure subscription and Azure geography
NOTE
Attempting to backup a key, secret, or certificate object with more versions than above limit will result in an error. It is not
possible to delete previous versions of a key, secret, or certificate.
Transaction limits for administrative operations (number of operations per second per HSM instance)
Transaction limits for cryptographic operations (number of operations per second per HSM instance)
Each Managed HSM instance constitutes three load balanced HSM partitions. The throughput limits are a
function of underlying hardware capacity allocated for each partition. The tables below show maximum
throughput with at least one partition available. Actual throughput may be up to 3x higher if all three
partitions are available.
Throughput limits noted assume that one single key is being used to achieve maximum throughput. For
example, if a single RSA-2048 key is used the maximum throughput will be 1100 sign operations. If you use
1100 different keys with one transaction per second each, they will not be able to achieve the same
throughput.
R SA k e y o p e r a t i o n s (n u m b e r o f o p e r a t i o n s p e r se c o n d p e r H SM i n st a n c e )
Create Key 1 1 1
Purge Key 10 10 10
Backup Key 10 10 10
Restore Key 10 10 10
E C k e y o p e r a t i o n s (n u m b e r o f o p e r a t i o n s p e r se c o n d p e r H SM i n st a n c e )
This table describes number of operations per second for each curve type.
Create Key 1 1 1 1
Purge Key 10 10 10 10
Backup Key 10 10 10 10
Restore Key 10 10 10 10
A E S k e y o p e r a t i o n s (n u m b e r o f o p e r a t i o n s p e r se c o n d p e r H SM i n st a n c e )
Create Key 1 1 1
Purge Key 10 10 10
Backup Key 10 10 10
Restore Key 10 10 10
O P ERAT IO N 128- B IT 192- B IT 256- B IT
Account limits
RESO URC E DEFA ULT L IM IT
Asset limits
RESO URC E DEFA ULT L IM IT
File size In some scenarios, there is a limit on the maximum file size
supported for processing in Media Services. (1)
1
1 The maximum size supported for a single blob is currently up to 5 TB in Azure Blob Storage. Additional limits
apply in Media Services based on the VM sizes that are used by the service. The size limit applies to the files that
you upload and also the files that get generated as a result of Media Services processing (encoding or
analyzing). If your source file is larger than 260-GB, your Job will likely fail.
2 The storage accounts must be from the same Azure subscription.
Jobs (encoding & analyzing) limits
RESO URC E DEFA ULT L IM IT
3 This number includes queued, finished, active, and canceled Jobs. It does not include deleted Jobs.
Any Job record in your account older than 90 days will be automatically deleted, even if the total number of
records is below the maximum quota.
Live streaming limits
RESO URC E DEFA ULT L IM IT
4 For detailed information about Live Event limitations, see Live Event types comparison and limitations.
5 Live Outputs start on creation and stop when deleted.
6 When using a custom Streaming Policy, you should design a limited set of such policies for your Media Service
account, and re-use them for your StreamingLocators whenever the same encryption options and protocols are
needed. You should not be creating a new Streaming Policy for each Streaming Locator.
7 Streaming Locators are not designed for managing per-user access control. To give different access rights to
individual users, use Digital Rights Management (DRM) solutions.
Protection limits
RESO URC E DEFA ULT L IM IT
Licenses per month for each of the DRM types on Media 1,000,000
Services key delivery service per account
Support ticket
For resources that are not fixed, you may ask for the quotas to be raised, by opening a support ticket. Include
detailed information in the request on the desired quota changes, use-case scenarios, and regions required.
Do not create additional Azure Media Services accounts in an attempt to obtain higher limits.
Media Services v2 (legacy)
For limits specific to Media Services v2 (legacy), see Media Services v2 (legacy)
API calls 500,000 1.5 million per unit 15 million per unit
Push notifications Azure Notification Hubs Notification Hubs Basic tier Notification Hubs Standard
Free tier included, up to 1 included, up to 10 million tier included, up to 10
million pushes pushes million pushes
For more information on limits and pricing, see Azure Mobile Services pricing.
Multi-Factor Authentication limits
RESO URC E DEFA ULT L IM IT M A XIM UM L IM IT
Networking limits
Networking limits - Azure Resource Manager
The following limits apply only for networking resources managed through Azure Resource Manager per
region per subscription. Learn how to view your current resource usage against your subscription limits.
NOTE
We recently increased all default limits to their maximum limits. If there's no maximum limit column, the resource doesn't
have adjustable limits. If you had these limits increased by support in the past and don't see updated limits in the
following tables, open an online customer support request at no charge
RESO URC E L IM IT
RESO URC E L IM IT
Concurrent TCP or UDP flows per NIC 500,000, up to 1,000,000 for two or 500,000, up to 1,000,000 for two or
of a virtual machine or role instance more NICs. more NICs.
ExpressRoute limits
RESO URC E L IM IT
Maximum number of ExpressRoute circuits linked to the 16 (For more information, see Gateway SKU.)
same virtual network in different peering locations
Number of virtual network links allowed per ExpressRoute See the Number of virtual networks per ExpressRoute circuit
circuit table.
RESO URC E L IM IT
N UM B ER O F VIRT UA L N ET W O RK L IN K S N UM B ER O F VIRT UA L N ET W O RK L IN K S
C IRC UIT SIZ E F O R STA N DA RD W IT H P REM IUM A DD- O N
50 Mbps 10 20
100 Mbps 10 25
200 Mbps 10 25
500 Mbps 10 40
1 Gbps 10 50
2 Gbps 10 60
5 Gbps 10 75
10 Gbps 10 100
40 Gbps* 10 100
NOTE
Global Reach connections count against the limit of virtual network connections per ExpressRoute Circuit. For example, a
10 Gbps Premium Circuit would allow for 5 Global Reach connections and 95 connections to the ExpressRoute Gateways
or 95 Global Reach connections and 5 connections to the ExpressRoute Gateways or any other combination up to the
limit of 100 connections for the circuit.
Local Network Gateway address prefixes 1000 per local network gateway
RESO URC E L IM IT
RESO URC E L IM IT
Throughput per Virtual WAN VPN connection (2 tunnels) 2 Gbps with 1 Gbps/IPsec tunnel
Aggregate throughput per Virtual WAN User VPN (Point-to- 200 Gbps
site) gateway
VNet connections per hub 500 minus total number of hubs in Virtual WAN
Aggregate throughput per Virtual WAN Hub Router 50 Gbps for VNet to VNet transit
VM workload across all VNets connected to a single Virtual 2000 (If you want to raise the limit or quota above the
WAN hub default limit, open an online customer support request.)
WAF body size limit (without files) V1 or V2 (with CRS 3.1 and older) -
128 KB
V2 (with CRS 3.2 or newer) - 2 MB3
1 In case of WAF-enabled SKUs, you must limit the number of resources to 40.
2 Limit is per Application Gateway instance not per Application Gateway resource.
3 Must define the value via WAF Policy for Application Gateway
Network Watcher limits
RESO URC E L IM IT N OT E
RESO URC E L IM IT N OT E
Packet capture sessions 10,000 per region Number of sessions only, not saved
captures.
RESO URC E L IM IT
Number of IP Configurations on a private link service 8 (This number is for the NAT IP addresses used per PLS)
Light 50
Medium 25
Heavy 2
RESO URC E L IM IT
RESO URC E L IM IT
Virtual Networks Links per private DNS zones with auto- 100
registration enabled
1
1These limits are applied to every individual virtual machine and not at the virtual network level. DNS queries
exceeding these limits are dropped.
Azure Firewall limits
RESO URC E L IM IT
Maximum DNAT rules 298 (for firewalls configured with a single Public IP address)
Public IP addresses 250 maximum. All public IP addresses can be used in DNAT
rules and they all contribute to available SNAT ports.
FQDNs in network rules For good performance, do not exceed more than 1000
FQDNs across all network rules per firewall.
Timeout values
Cl i en t t o Fr o n t Do o r
After the HTTP request gets forwarded to the back end, Azure Front Door waits for 60 seconds (Standard
and Premium) or 30 seconds (classic) for the first packet from the back end. Then it returns a 503 error to
the client, or 504 for a cached request. You can configure this value using the
originResponseTimeoutSeconds field in Azure Front Door Standard and Premium API, or the
sendRecvTimeoutSeconds field in the Azure Front Door (classic) API.
After the back end receives the first packet, if the origin pauses for any reason in the middle of the
response body beyond the originResponseTimeoutSeconds or sendRecvTimeoutSeconds, the response
will be canceled.
Front Door takes advantage of HTTP keep-alive to keep connections open for reuse from previous
requests. These connections have an idle timeout of 90 seconds. Azure Front Door would disconnect idle
connections after reaching the 90-second idle timeout. This timeout value can't be configured.
Upload and download data limit
W IT H C H UN K ED T RA N SF ER
EN C O DIN G ( C T E) W IT H O UT H T T P C H UN K IN G
Download There's no limit on the download size. There's no limit on the download size.
Upload There's no limit as long as each CTE The size can't be larger than 2 GB.
upload is less than 2 GB.
Other limits
Maximum URL size - 8,192 bytes - Specifies maximum length of the raw URL (scheme + hostname + port +
path + query string of the URL)
Maximum Query String size - 4,096 bytes - Specifies the maximum length of the query string, in bytes.
Maximum HTTP response header size from health probe URL - 4,096 bytes - Specified the maximum length
of all the response headers of health probes.
Maximum rules engine action header value character: 640 characters.
Maximum rules engine condition header value character: 256 characters.
Maximum ETag header size: 128 bytes
Maximum endhpoint name for Standard and Premium: 46 characters.
For more information about limits that apply to Rules Engine configurations, see Rules Engine terminology
For more information on limits and pricing, see Notification Hubs pricing.
Incident limits
The following limits apply to incidents in Microsoft Sentinel.
Investigation experience availability 90 days from the incident last update None
time
Number of anomalies published per Top 3000 ranked by anomaly score None
anomaly type
Notebook limits
The following limits apply to notebooks in Microsoft Sentinel. The limits are related to the dependencies on
other services used by notebooks.
Total count of these assets per 10 million assets Azure Machine Learning
machine learning workspace: datasets,
runs, models, and artifacts
DESC RIP T IO N L IM IT DEP EN DEN C Y
Default limit for total compute clusters 200 compute clusters per region Azure Machine Learning
per region. Limit is shared between a
training cluster and a compute
instance. A compute instance is
considered a single-node cluster for
quota purposes.
Storage accounts per region per 250 storage accounts Azure Storage
subscription
Indicators per call that use Graph 100 indicators Microsoft Graph security API
security API
Watchlist limits
The following limits apply to watchlists in Microsoft Sentinel. The limits are related to the dependencies on other
services used by watchlists.
Upload size for local file 3.8 MB per file Azure Resource Manager
Line entry in the CSV file 10,240 characters per line Azure Resource Manager
Upload size for files in Azure Storage 500 MB per file Azure Storage
Total number of active watchlist items 10 million active watchlist items Log Analytics
per workspace. When the max count is
reached, delete some existing items to
add a new watchlist.
Number of large watchlist uploads per One large watchlist Azure Cosmos DB
workspace at a time
Q UOTA N A M E SC O P E VA L UE N OT ES
Number of topics or queues Namespace 10,000 for the Basic or Subsequent requests for
per namespace Standard tier. The total creation of a new topic or
number of topics and queue on the namespace
queues in a namespace are rejected. As a result, if
must be less than or equal configured through the
to 10,000. Azure portal, an error
message is generated. If
For the Premium tier, 1,000 called from the
per messaging unit (MU). management API, an
exception is received by the
calling code.
Number of partitioned Namespace Basic and Standard tiers: Subsequent requests for
topics or queues per 100. creation of a new
namespace partitioned topic or queue
Partitioned entities aren't in the namespace are
supported in the Premium rejected. As a result, if
tier. configured through the
Azure portal, an error
Each partitioned queue or message is generated. If
topic counts toward the called from the
quota of 1,000 entities per management API, the
namespace. exception
QuotaExceededExceptio
n is received by the calling
code.
If you want to have
more partitioned
entities in a basic or a
standard tier
namespace, create
additional namespaces.
Message size for a queue, Entity Incoming messages that 256 KB for Standard tier
topic, or subscription entity exceed these quotas are 100 MB for Premium tier.
rejected, and an exception is
received by the calling code. The message size includes
the size of properties
(system and user) and the
size of payload. The size of
system properties varies
depending on your
scenario.
Number of subscriptions Entity Subsequent requests for 2,000 per-topic for the
per topic creating additional Standard tier and Premium
subscriptions for the topic tier.
are rejected. As a result, if
configured through the
portal, an error message is
shown. If called from the
management API, an
exception is received by the
calling code.
Size of SQL filters or actions Namespace Subsequent requests for Maximum length of filter
creation of additional filters condition string: 1,024 (1
are rejected, and an K).
exception is received by the
calling code. Maximum length of rule
action string: 1,024 (1 K).
Maximum number of
expressions per rule action:
32.
Number of shared access Entity, namespace Subsequent requests for Maximum number of rules
authorization rules per creation of additional rules per entity type: 12.
namespace, queue, or topic are rejected, and an
exception is received by the Rules that are configured
calling code. on a Service Bus namespace
apply to all types: queues,
topics.
L IM IT IDEN T IF IER L IM IT
Concurrent Data Integration Units1 Region group 12 : 6,000 Region group 12 : 6,000
consumption per workspace per Azure Region group 22 : 3,000 Region group 22 : 3,000
Integration Runtime region Region group 32 : 1,500 Region group 32 : 1,500
Managed virtual network2 : 2,400 Managed virtual network: Contact
support.
ForEach parallelism 20 50
1 The data integration unit (DIU) is used in a cloud-to-cloud copy operation, learn more from Data integration
units (version 2). For information on billing, see Azure Synapse Analytics Pricing.
2 Azure Integration Runtime is globally available to ensure data compliance, efficiency, and reduced network
egress costs.
Region group 1 Central US, East US, East US 2, North Europe, West Europe,
West US, West US 2
If managed virtual network is enabled, the data integration unit (DIU) in all region groups are 2,400.
3 Pipeline, data set, and linked service objects represent a logical grouping of your
workload. Limits for these
objects don't relate to the amount of data you can move and process with Azure Synapse Analytics. Synapse
Analytics is designed to scale to handle petabytes of data.
4 The payload for each activity run includes the activity configuration, the associated dataset(s) and linked
service(s) configurations if any, and a small portion of system properties generated per activity type. Limit for
this payload size doesn't relate to the amount of data you can move and process with Azure Synapse Analytics.
Learn about the symptoms and recommendation if you hit this limit.
Dedicated SQL pool limits
For details of capacity limits for dedicated SQL pools in Azure Synapse Analytics, see dedicated SQL pool
resource limits.
Web service call limits
Azure Resource Manager has limits for API calls. You can make API calls at a rate within the Azure Resource
Manager API limits.
Storage limits
The following table describes default limits for Azure general-purpose v2 (GPv2), general-purpose v1 (GPv1),
and Blob storage accounts. The ingress limit refers to all data that is sent to a storage account. The egress limit
refers to all data that is received from a storage account.
Microsoft recommends that you use a GPv2 storage account for most scenarios. You can easily upgrade a GPv1
or a Blob storage account to a GPv2 account with no downtime and without the need to copy data. For more
information, see Upgrade to a GPv2 storage account.
NOTE
You can request higher capacity and ingress limits. To request an increase, contact Azure Support.
RESO URC E L IM IT
Default maximum request rate per storage account 20,000 requests per second1
1 Azure Storage standard accounts support higher capacity limits and higher limits for ingress and egress by
request. To request an increase in account limits, contact Azure Support.
For more information on limits for standard storage accounts, see Scalability targets for standard storage
accounts.
Storage resource provider limits
The following limits apply only when you perform management operations by using Azure Resource Manager
with Azure Storage.
RESO URC E L IM IT
Storage account management operations (write) 10 per second / 1200 per hour
Maximum size of single blob container Same as maximum storage account capacity
Maximum size of a block blob 50,000 X 4000 MiB (approximately 190.7 TiB)
Target request rate for a single blob Up to 500 requests per second
Target throughput for a single block blob Up to storage account ingress/egress limits1
1 Throughput for a single blob depends on several factors, including, but not limited to: concurrency, request
size, performance tier, speed of source for uploads, and destination for downloads. To take advantage of the
performance enhancements of high-throughput block blobs, upload larger blobs or blocks. Specifically, call the
Put Blob or Put Block operation with a blob or block size that is greater than 4 MiB for standard storage
accounts. For premium block blob or for Data Lake Storage Gen2 storage accounts, use a block or blob size that
is greater than 256 KiB.
2 Page blobs are not yet supported in accounts that have the Hierarchical namespace setting on them.
The following table describes the maximum block and blob sizes permitted by service version.
Version 2019-12-12 and 4000 MiB Approximately 190.7 TiB 5000 MiB (preview)
later (4000 MiB X 50,000 blocks)
Maximum request rate per storage account 20,000 messages per second, which assumes a 1-KiB
message size
Target throughput for a single queue (1-KiB messages) Up to 2,000 messages per second
Number of tables in an Azure storage account Limited only by the capacity of the storage account
Number of partitions in a table Limited only by the capacity of the storage account
Number of entities in a partition Limited only by the capacity of the storage account
RESO URC E TA RGET
Maximum number of properties in a table entity 255 (including the three system properties, Par titionKey ,
RowKey , and Timestamp )
Maximum total size of an individual property in an entity Varies by property type. For more information, see
Proper ty Types in Understanding the Table Service Data
Model.
Size of an entity group transaction A transaction can include at most 100 entities and the
payload must be less than 4 MiB in size. An entity group
transaction can include an update to an entity only once.
Maximum request rate per storage account 20,000 transactions per second, which assumes a 1-KiB
entity size
Target throughput for a single table partition (1 KiB-entities) Up to 2,000 entities per second
IMPORTANT
For optimal performance, limit the number of highly utilized disks attached to the virtual machine to avoid possible
throttling. If all attached disks aren't highly utilized at the same time, the virtual machine can support a larger number of
disks.
RESO URC E L IM IT
Disk 32 64 128 256 512 1,024 2,048 4,096 8,192 16,38 32,76
size in 4 7
GiB
IOPS Up to Up to Up to Up to Up to Up to Up to Up to Up to Up to Up to
per 500 500 500 500 500 500 500 500 1,300 2,000 2,000
disk
Throu Up to Up to Up to Up to Up to Up to Up to Up to Up to Up to Up to
ghput 60 60 60 60 60 60 60 60 300 500 500
per MB/s MB/s MB/s MB/se MB/se MB/se MB/se MB/se MB/se MB/se MB/se
disk ec ec ec c c c c c c c c
Dis 4 8 16 32 64 128 256 512 1,0 2,0 4,0 8,1 16, 32,
k 24 48 96 92 384 767
size
in
GiB
IOP Up Up Up Up Up Up Up Up Up Up Up Up Up Up
S to to to to to to to to to to to to to to
per 500 500 500 500 500 500 500 500 500 500 500 2,0 4,0 6,0
disk 00 00 00
Thr Up Up Up Up Up Up Up Up Up Up Up Up Up Up
oug to to to to to to to to to to to to to to
hpu 60 60 60 60 60 60 60 60 60 60 60 400 600 750
t MB MB MB MB MB MB MB MB MB MB/ MB/ MB/ MB/ MB/
per /sec /sec /sec /sec /sec /sec /sec /sec /sec sec sec sec sec sec
disk
Ma 30 30 30 30 30 30 30 30 30
x min min min min min min min min min
bur
st
dur
atio
n
Dis 4 8 16 32 64 128 256 512 1,0 2,0 4,0 8,1 16, 32,
k 24 48 96 92 384 767
size
in
GiB
Pro 120 120 120 120 240 500 1,1 2,3 5,0 7,5 7,5 16, 18, 20,
visi 00 00 00 00 00 000 000 000
one
d
IOP
S
per
disk
Pro 25 25 25 25 50 100 125 150 200 250 250 500 750 900
visi MB MB MB MB MB MB MB MB MB MB/ MB/ MB/ MB/ MB/
one /sec /sec /sec /sec /sec /sec /sec /sec /sec sec sec sec sec sec
d
Thr
oug
hpu
t
per
disk
Ma 3,5 3,5 3,5 3,5 3,5 3,5 3,5 3,5 30, 30, 30, 30, 30, 30,
x 00 00 00 00 00 00 00 00 000 000 000 000 000 000
bur * * * * * *
st
IOP
S
per
disk
Ma 170 170 170 170 170 170 170 170 1,0 1,0 1,0 1,0 1,0 1,0
x MB MB MB MB MB MB MB MB 00 00 00 00 00 00
bur /sec /sec /sec /sec /sec /sec /sec /sec MB MB/ MB/ MB/ MB/ MB/
st /sec sec* sec* sec* sec* sec*
thr *
oug
hpu
t
per
disk
RESO URC E L IM IT
P REM IUM
STO RA GE DISK
TYPE P 10 P 20 P 30 P 40 P 50
Disk size 128 GiB 512 GiB 1,024 GiB (1 TB) 2,048 GiB (2 TB) 4,095 GiB (4 TB)
P REM IUM
STO RA GE DISK
TYPE P 10 P 20 P 30 P 40 P 50
Maximum 100 MB/sec 150 MB/sec 200 MB/sec 250 MB/sec 250 MB/sec
throughput per
disk
Maximum 280 70 35 17 8
number of disks
per storage
account
RESO URC E L IM IT
Maximum number of schedules per 168 A schedule for every hour, every day
bandwidth template of the week.
Maximum size of a tiered volume on 64 TB for StorSimple 8100 and StorSimple 8100 and StorSimple 8600
physical devices StorSimple 8600 are physical devices.
Maximum size of a tiered volume on 30 TB for StorSimple 8010 StorSimple 8010 and StorSimple 8020
virtual devices in Azure are virtual devices in Azure that use
64 TB for StorSimple 8020 Standard storage and Premium
storage, respectively.
Maximum size of a locally pinned 9 TB for StorSimple 8100 StorSimple 8100 and StorSimple 8600
volume on physical devices are physical devices.
24 TB for StorSimple 8600
Maximum number of snapshots of any 256 This amount includes local snapshots
type that can be retained per volume and cloud snapshots.
Restore and clone recover time for <2 minutes The volume is made available
tiered volumes within 2 minutes of a restore or
clone operation, regardless of
the volume size.
The volume performance might
initially be slower than normal
as most of the data and
metadata still resides in the
cloud. Performance might
increase as data flows from the
cloud to the StorSimple device.
The total time to download
metadata depends on the
allocated volume size.
Metadata is automatically
brought into the device in the
background at the rate of 5
minutes per TB of allocated
volume data. This rate might be
affected by Internet bandwidth
to the cloud.
The restore or clone operation
is complete when all the
metadata is on the device.
Backup operations can't be
performed until the restore or
clone operation is fully
complete.
L IM IT IDEN T IF IER L IM IT C O M M EN T S
Restore recover time for locally pinned <2 minutes The volume is made available
volumes within 2 minutes of the restore
operation, regardless of the
volume size.
The volume performance might
initially be slower than normal
as most of the data and
metadata still resides in the
cloud. Performance might
increase as data flows from the
cloud to the StorSimple device.
The total time to download
metadata depends on the
allocated volume size.
Metadata is automatically
brought into the device in the
background at the rate of 5
minutes per TB of allocated
volume data. This rate might be
affected by Internet bandwidth
to the cloud.
Unlike tiered volumes, if there
are locally pinned volumes, the
volume data is also
downloaded locally on the
device. The restore operation is
complete when all the volume
data has been brought to the
device.
The restore operations might
be long and the total time to
complete the restore will
depend on the size of the
provisioned local volume, your
Internet bandwidth, and the
existing data on the device.
Backup operations on the
locally pinned volume are
allowed while the restore
operation is in progress.
Maximum client read/write 920/720 MB/sec with a single 10- Up to two times with MPIO and two
throughput, when served from the gigabit Ethernet network interface network interfaces.
SSD tier*
*Maximum throughput per I/O type was measured with 100 percent read and 100 percent write scenarios.
Actual throughput might be lower and depends on I/O mix and network conditions.
Stream Analytics limits
L IM IT IDEN T IF IER L IM IT C O M M EN T S
Maximum number of inputs per job 60 There's a hard limit of 60 inputs per
Azure Stream Analytics job.
Maximum number of outputs per job 60 There's a hard limit of 60 outputs per
Stream Analytics job.
Maximum number of functions per job 60 There's a hard limit of 60 functions per
Stream Analytics job.
Maximum number of streaming units 192 There's a hard limit of 192 streaming
per job units per Stream Analytics job.
Maximum number of jobs per region 1,500 Each subscription can have up to
1,500 jobs per geographical region.
1 Virtual machines created by using the classic deployment model instead of Azure Resource Manager are
automatically stored in a cloud service. You can add more virtual machines to that cloud service for load
balancing and availability.
2 Input endpoints allow communications to a virtual machine from outside the virtual machine's cloud service.
Virtual machines in the same cloud service or virtual network can automatically communicate with each other.
Virtual Machines limits - Azure Resource Manager
The following limits apply when you use Azure Resource Manager and Azure resource groups.
RESO URC E L IM IT
VM total cores per subscription 201 per region. Contact support to increase limit.
RESO URC E L IM IT
Azure Spot VM total cores per subscription 201 per region. Contact support to increase limit.
VM per series, such as Dv2 and F, cores per subscription 201 per region. Contact support to increase limit.
1 Default limits vary by offercategory type, such as Free Trial and Pay-As-You-Go, and by series, such as Dv2, F,
and G. For example, the default for Enterprise Agreement subscriptions is 350. For security, subscriptions default
to 20 cores to prevent large core deployments. If you need more cores, submit a support ticket.
2 Properties such as SSH public keys are also pushed as certificates and count towards this limit. To bypass this
limit, use the Azure Key Vault extension for Windows or the Azure Key Vault extension for Linux to install
certificates.
3 With Azure Resource Manager, certificates are stored in the Azure Key Vault. The number of certificates is
unlimited for a subscription. There's a 1-MB limit of certificates per deployment, which consists of either a single
VM or an availability set.
NOTE
Virtual machine cores have a regional total limit. They also have a limit for regional per-size series, such as Dv2 and F.
These limits are separately enforced. For example, consider a subscription with a US East total VM core limit of 30, an A
series core limit of 30, and a D series core limit of 30. This subscription can deploy 30 A1 VMs, or 30 D1 VMs, or a
combination of the two not to exceed a total of 30 cores. An example of a combination is 10 A1 VMs and 20 D1 VMs.
See also
Understand Azure limits and increases
Virtual machine and cloud service sizes for Azure
Sizes for Azure Cloud Services
Naming rules and restrictions for Azure resources
Kudu service overview
5/18/2022 • 2 minutes to read • Edit Online
Kudu is the engine behind a number of features in Azure App Service related to source control based
deployment, and other deployment methods like Dropbox and OneDrive sync.
Kudu features
Kudu gives you helpful information about your App Service app, such as:
App settings
Connection strings
Environment variables
Server variables
HTTP headers
It also provides other features, such as:
Run commands in the Kudu console.
Download IIS diagnostic dumps or Docker logs.
Manage IIS processes and site extensions.
Add deployment webhooks for Windows apps.
Allow ZIP deployment UI with /ZipDeploy .
Generates custom deployment scripts.
Allows access with REST API.
More Resources
Kudu is an open source project, and has its documentation at Kudu Wiki.
Best Practices for Azure App Service
5/18/2022 • 7 minutes to read • Edit Online
This article summarizes best practices for using Azure App Service.
Colocation
When Azure resources composing a solution such as a web app and a database are located in different regions,
it can have the following effects:
Increased latency in communication between resources
Monetary charges for outbound data transfer cross-region as noted on the Azure pricing page.
Colocation in the same region is best for Azure resources composing a solution such as a web app and a
database or storage account used to hold content or data. When creating resources, make sure they are in the
same Azure region unless you have specific business or design reason for them not to be. You can move an App
Service app to the same region as your database by using the App Service cloning feature currently available for
Premium App Service Plan apps.
Certificate Pinning
Applications should never have a hard dependency or pin to the default *.azurewebsites.net TLS certificate
because the *.azurewebsites.net TLS certificate could be rotated anytime given the nature of App Service as a
Platform as a Service (PaaS). Certificate pinning is a practice where an application only allows a specific list of
acceptable Certificate Authorities (CAs), public keys, thumbprints, or any part of the certificate hierarchy. In the
event that the service rotates the App Service default wildcard TLS certificate, certificate pinned applications will
break and disrupt the connectivity for applications that are hardcoded to a specific set of certificate attributes.
The periodicity with which the *.azurewebsites.net TLS certificate is rotated is also not guaranteed since the
rotation frequency can change at any time.
Note that applications which rely on certificate pinning should also not have a hard dependency on an App
Service Managed Certificate. App Service Managed Certificates could be rotated anytime, leading to similar
problems for applications that rely on stable certificate properties. It is best practice to provide a custom TLS
certificate for applications that rely on certificate pinning.
If an application needs to rely on certificate pinning behavior, it is recommended to add a custom domain to a
web app and provide a custom TLS certificate for the domain which can then be relied on for certificate pinning.
If you are running on App Service on Linux on a machine with multiple cores, another best practice is to use
PM2 to start multiple Node.js processes to execute your application. You can do it by specifying a startup
command to your container.
For example, to start four instances:
pm2 start /home/site/wwwroot/app.js --no-daemon -i 4
Next Steps
For more information on best practices, visit App Service Diagnostics to find out actionable best practices
specific to your resource.
Navigate to your Web App in the Azure portal.
Click on Diagnose and solve problems in the left navigation, which opens App Service Diagnostics.
Choose Best Practices homepage tile.
Click Best Practices for Availability & Performance or Best Practices for Optimal Configuration to
view the current state of your app in regards to these best practices.
You can also use this link to directly open App Service Diagnostics for your resource:
https://portal.azure.com/?
websitesextension_ext=asd.featurePath%3Ddetectors%2FParentAvailabilityAndPerformance#@microsoft.onmicrosoft.com/resource/subscriptions/{subscriptionId}/resourceGroups/{re
.
.NET migration cases for Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
Azure App Service provides easy-to-use tools to quickly discover on-premise .NET web apps, assess for
readiness, and migrate both the content & supported configurations to App Service.
These tools are developed to support different kinds of scenarios, focused on discovery, assessment, and
migration. Following is list of .NET migration tools and use cases.
Blog
FAQ
Azure App Service assessments in Azure Migrate Discovery and assessment tool
Best practices
Video
At scale discovery and assessment for ASP.NET app migration with Azure Migrate
Next steps
Migrate an on-premise web application to Azure App Service
ASP.NET app containerization and migration to
Azure App Service
5/18/2022 • 13 minutes to read • Edit Online
In this article, you'll learn how to containerize ASP.NET applications and migrate them to Azure App Service by
using the Azure Migrate App Containerization tool. The containerization process doesn't require access to your
codebase and provides an easy way to containerize existing applications. The tool works by using the running
state of the applications on a server to determine the application components. It then helps you package them in
a container image. You can then deploy the containerized application on Azure App Service.
The Azure Migrate App Containerization tool currently supports:
Containerizing ASP.NET apps and deploying them on Windows containers on App Service.
Containerizing ASP.NET apps and deploying them on Windows containers on Azure Kubernetes Service
(AKS). Learn more about this containerization scenario.
Containerizing Java web apps on Apache Tomcat (on Linux servers) and deploying them on Linux containers
on AKS. Learn more about this containerization scenario.
Containerizing Java web apps on Apache Tomcat (on Linux servers) and deploying them on Linux containers
on App Service. Learn more about this containerization scenario.
The App Containerization tool helps you:
Discover your application components. The tool remotely connects to the application servers that run
your ASP.NET application and discovers the application components. It creates a Dockerfile that you can use
to create a container image for the application.
Build the container image. You can inspect and further customize the Dockerfile based on your
application requirements and use it to build your application container image. The application container
image is pushed to an Azure container registry that you specify.
Deploy to Azure App Ser vice. The tool then generates the deployment files needed to deploy the
containerized application to Azure App Service.
NOTE
The Azure Migrate App Containerization tool helps you discover specific application types (ASP.NET and Java web apps on
Apache Tomcat) and their components on an application server. To discover servers and the inventory of apps, roles, and
features running on on-premises computers, use the Azure Migrate Discovery and assessment tool.
Not all applications will benefit from a straight shift to containers without significant rearchitecting. But some of
the benefits of moving existing apps to containers without rewriting include:
Improved infrastructure utilization. When you use containers, multiple applications can share resources
and be hosted on the same infrastructure. This can help you consolidate infrastructure and improve
utilization.
Simplified management. By hosting your applications on modern managed platforms like AKS and App
Service, you can simplify your management practices. You can achieve this simplification by retiring or
reducing the infrastructure maintenance and management processes that you'd traditionally perform with
owned infrastructure.
Application por tability. With increased adoption and standardization of container specification formats
and platforms, application portability is no longer a concern.
Adopt modern management by using DevOps. Using containers helps you adopt and standardize on
modern practices for management and security and transition to DevOps.
In this tutorial, you'll learn how to:
Set up an Azure account.
Install the Azure Migrate App Containerization tool.
Discover your ASP.NET application.
Build the container image.
Deploy the containerized application on App Service.
NOTE
Tutorials provide the simplest deployment path for a scenario so that you can quickly set up a proof of concept. Tutorials
use default options when possible and don't show all settings and paths.
Prerequisites
Before you start this tutorial, you should:
Identify a machine on which to install the tool You need a Windows machine on which to install and run
the Azure Migrate App Containerization tool. The Windows
machine could run a server (Windows Server 2016 or later)
or client (Windows 10) operating system. (The tool can run
on your desktop.)
Application ser vers Enable PowerShell remoting on the application servers: sign
in to the application server and follow these instructions to
turn on PowerShell remoting.
2. On the Subscriptions page, select the subscription in which you want to create an Azure Migrate
project.
3. In the subscription, on the left pane, select Access control (IAM) .
4. On the Check access tab, search for the relevant user account.
5. Under Add a role assignment , select Add :
6. On the Add role assignment page, select the Owner role, and then select the account (azmigrateuser
in our example). Then select Save .
Your Azure account also needs permissions to register Azure Active Directory apps.
7. In the Azure portal, go to Azure Active Director y > Users > User Settings .
8. In User settings , verify that Azure AD users can register applications. (This option is set to Yes by
default.)
9. If the App registrations option is set to No , ask the tenant/global admin to assign the required
permission. Alternatively, the tenant/global admin can assign the Application developer role to an
account to allow the registration of Azure Active Directory apps. For more information, see Assign roles
to users.
.\AppContainerizationInstaller.ps1
Sign in to Azure
1. Select Sign in to sign in to your Azure account.
You need a device code to authenticate with Azure. Selecting Sign in should open a window that contains
the device code. If the window doesn't appear, make sure you've disabled the pop-up blocker in the
browser.
2. Select Copy code and Sign in to copy the device code and open an Azure sign-in prompt in a new
browser tab:
3. On the new tab, paste in the device code and complete sign-in by using your Azure account credentials.
After you're signed in, you can close the browser tab and return to the App Containerization tool's web
interface.
4. Select the Azure tenant that you want to use.
5. Specify the Azure subscription that you want to use.
NOTE
Only Azure container registries with the admin user account enabled are displayed. The admin user account is
currently required for deploying an image from an Azure container registry to Azure App Service. For more
information, see Authenticate with an Azure container registry.
2. The Dockerfiles needed to build the container images for each selected application are generated at the
beginning of the build step. Select Review to review the Dockerfile. You can also add any necessary
customizations to the Dockerfile in the review step and save the changes before you start the build
process.
3. Select the applications that you want to build images for, and then select Build . Selecting Build will start
the container image build for each application. The tool monitors the build status and will let you
continue to the next step when the build finishes.
4. You can monitor the progress of the build by selecting Build in Progress under the status column. The
link will become active a couple minutes after you trigger the build process.
5. After the build is complete, select Continue to specify deployment settings:
6. After you save the deployment configuration for the application, the tool will generate the Kubernetes
deployment YAML for the application.
Select Review to review the deployment configuration for the applications.
Select the applications that you want to deploy.
Select Deploy to start deployment for the selected applications.
After the application is deployed, you can select the Deployment status column to track the
resources that were deployed for the application.
Troubleshoot problems
To troubleshoot problems with the App Containerization tool, you can look at the log files on the Windows
machine that's running the tool. Log files for the tool are located at C:\ProgramData\Microsoft Azure Migrate
App Containerization\Logs.
Next steps
Containerizing ASP.NET web apps and deploying them on Windows containers on AKS
Containerizing Java web apps on Apache Tomcat (on Linux servers) and deploying them on Linux containers
on AKS
Containerizing Java web apps on Apache Tomcat (on Linux servers) and deploying them on Linux containers
on App Service
Java migration resources for Azure App Service
5/18/2022 • 2 minutes to read • Edit Online
Azure App Service provides tools to discover web apps deployed to on-premise web servers. You can assess
these apps for readiness, then migrate them to App Service. Both the web app content and supported
configuration can be migrated to App Service. These tools are developed to support a wide variety of scenarios
focused on discovery, assessment, and migration.
RESO URC ES
How-tos
Azure/App-Service-Migration-Assistant Wiki
Videos
Point and Migrate Java Apps to Azure App Service Using the Migration System
Next steps
Migrate Tomcat applications to Tomcat on Azure App Service
Use existing runbooks and modules
5/18/2022 • 6 minutes to read • Edit Online
Rather than creating your own runbooks and modules in Azure Automation, you can access scenarios that have
already been built by Microsoft and the community. You can get Azure-related PowerShell and Python runbooks
from the Runbook Gallery in the Azure portal, and modules and runbooks (which may or may not be specific to
Azure) from the PowerShell Gallery. You can also contribute to the community by sharing scenarios that you
develop.
NOTE
The TechNet Script Center is retiring. All of the runbooks from Script Center in the Runbook gallery have been moved to
our Automation GitHub organization For more information, see Azure Automation Runbooks moving to GitHub.
4. In the Impor t a runbook page, you can either import a file stored on your local machine or from
GitHub using Browse for file or Browse from galler y respectively.
5. Select the file.
6. Enter the Name , Runtime version , and Description .
7. Click Impor t .
8. Alternatively, Select Browse Galler y in the Runbooks page to browse the available runbooks.
9. You can use the filters above the list to narrow the display by publisher, type, and sort. Locate the gallery
item you want and select it to view its details.
10. Click Select to select a chosen runbook.
11. In the Impor t a runbook page, enter the Name and select the Runtime versions .
12. The Runbook type and Description are auto populated.
13. Click Impor t .
14. The runbook appears on the Runbooks tab for the Automation account.
NOTE
Graphical runbooks are not supported in PowerShell Gallery.
You can only import directly from the PowerShell Gallery using the Azure portal. You cannot perform this
function using PowerShell. The procedure is the same as shown in Import runbooks from GitHub with the Azure
portal, except that the Source will be PowerShell Galler y .
IMPORTANT
Do not include the keyword "AzureRm" in any script designed to be executed with the Az module. Inclusion of the
keyword, even in a comment, may cause the AzureRm to load and then conflict with the Az module.
NOTE
Check out existing runbooks in the gallery for things like formatting, headers, and existing tags that you might
use (like Azure Automation or Linux Azure Virtual Machines ).
NOTE
Please allow at least 12 hours for synchronization between GitHub and the Automation Runbook Gallery, for both
updated and new runbooks.
NOTE
Modules that only support PowerShell core are not supported in Azure Automation and are unable to be imported in the
Azure portal, or deployed directly from the PowerShell Gallery.
Next steps
To get started with PowerShell runbooks, see Tutorial: Create a PowerShell runbook.
To work with runbooks, see Manage runbooks in Azure Automation.
For more info on PowerShell scripting, see PowerShell Docs.
For a PowerShell cmdlet reference, see Az.Automation.
Troubleshooting intermittent outbound connection
errors in Azure App Service
5/18/2022 • 8 minutes to read • Edit Online
This article helps you troubleshoot intermittent connection errors and related performance issues in Azure App
Service. This topic will provide more information on, and troubleshooting methodologies for, exhaustion of
source network address translation (SNAT) ports. If you require more help at any point in this article, contact the
Azure experts at the MSDN Azure and the Stack Overflow forums. Alternatively, file an Azure support incident.
Go to the Azure Support site and select Get Suppor t .
Symptoms
Applications and Functions hosted on Azure App service may exhibit one or more of the following symptoms:
Slow response times on all or some of the instances in a service plan.
Intermittent 5xx or Bad Gateway errors
Timeout error messages
Could not connect to external endpoints (like SQLDB, Service Fabric, other App services etc.)
Cause
The major cause for intermittent connection issues is hitting a limit while making new outbound connections.
The limits you can hit include:
TCP Connections: There is a limit on the number of outbound connections that can be made. The limit on
outbound connections is associated with the size of the worker used.
SNAT ports: Outbound connections in Azure describes SNAT port restrictions and how they affect outbound
connections. Azure uses source network address translation (SNAT) and Load Balancers (not exposed to
customers) to communicate with public IP addresses. Each instance on Azure App service is initially given a
pre-allocated number of 128 SNAT ports. The SNAT port limit affects opening connections to the same
address and port combination. If your app creates connections to a mix of address and port combinations,
you will not use up your SNAT ports. The SNAT ports are used up when you have repeated calls to the same
address and port combination. Once a port has been released, the port is available for reuse as needed. The
Azure Network load balancer reclaims SNAT port from closed connections only after waiting for 4 minutes.
When applications or functions rapidly open a new connection, they can quickly exhaust their pre-allocated
quota of the 128 ports. They are then blocked until a new SNAT port becomes available, either through
dynamically allocating additional SNAT ports, or through reuse of a reclaimed SNAT port. If your app runs out of
SNAT ports, it will have intermittent outbound connectivity issues.
ISO L AT ED T IER
L IM IT N A M E DESC RIP T IO N SM A L L ( A 1) M EDIUM ( A 2) L A RGE ( A 3) ( A SE)
To avoid outbound TCP limits, you can either increase the size of your workers, or scale out horizontally.
Troubleshooting
Knowing the two types of outbound connection limits, and what your app does, should make it easier to
troubleshoot. If you know that your app makes many calls to the same storage account, you might suspect a
SNAT limit. If your app creates a great many calls to endpoints all over the internet, you would suspect you are
reaching the VM limit.
If you do not know the application behavior enough to determine the cause quickly, there are some tools and
techniques available in App Service to help with that determination.
Find SNAT port allocation information
You can use App Service Diagnostics to find SNAT port allocation information, and observe the SNAT ports
allocation metric of an App Service site. To find SNAT port allocation information, follow the following steps:
1. To access App Service diagnostics, navigate to your App Service web app or App Service Environment in the
Azure portal. In the left navigation, select Diagnose and solve problems .
2. Select Availability and Performance Category
3. Select SNAT Port Exhaustion tile in the list of available tiles under the category. The practice is to keep it
below 128. If you do need it, you can still open a support ticket and the support engineer will get the metric
from back-end for you.
Since SNAT port usage is not available as a metric, it is not possible to either autoscale based on SNAT port
usage, or to configure auto scale based on SNAT ports allocation metric.
TCP Connections and SNAT Ports
TCP connections and SNAT ports are not directly related. A TCP connections usage detector is included in the
Diagnose and Solve Problems blade of any App Service site. Search for the phrase "TCP connections" to find it.
The SNAT Ports are only used for external network flows, while the total TCP Connections includes local
loopback connections.
A SNAT port can be shared by different flows, if the flows are different in either protocol, IP address or port.
The TCP Connections metric counts every TCP connection.
The TCP connections limit happens at the worker instance level. The Azure Network outbound load balancing
doesn't use the TCP Connections metric for SNAT port limiting.
The TCP connections limits are described in Sandbox Cross VM Numerical Limits - TCP Connections
Existing TCP sessions will fail when new outbound TCP sessions from Azure App Service source port. You can
either use a single IP or reconfigure backend pool members to avoid conflicts
ISO L AT ED T IER
L IM IT N A M E DESC RIP T IO N SM A L L ( A 1) M EDIUM ( A 2) L A RGE ( A 3) ( A SE)
Additional information
SNAT with App Service
Troubleshoot slow app performance issues in Azure App Service
Troubleshoot an app in Azure App Service using
Visual Studio
5/18/2022 • 25 minutes to read • Edit Online
Overview
This tutorial shows how to use Visual Studio tools to help debug an app in App Service, by running in debug
mode remotely or by viewing application logs and web server logs.
You'll learn:
Which app management functions are available in Visual Studio.
How to use Visual Studio remote view to make quick changes in a remote app.
How to run debug mode remotely while a project is running in Azure, both for an app and for a WebJob.
How to create application trace logs and view them while the application is creating them.
How to view web server logs, including detailed error messages and failed request tracing.
How to send diagnostic logs to an Azure Storage account and view them there.
If you have Visual Studio Ultimate, you can also use IntelliTrace for debugging. IntelliTrace is not covered in this
tutorial.
Prerequisites
This tutorial works with the development environment, web project, and App Service app that you set up in
Create an ASP.NET app in Azure App Service. For the WebJobs sections, you'll need the application that you
create in Get Started with the Azure WebJobs SDK.
The code samples shown in this tutorial are for a C# MVC web application, but the troubleshooting procedures
are the same for Visual Basic and Web Forms applications.
The tutorial assumes you're using Visual Studio 2019.
The streaming logs feature only works for applications that target .NET Framework 4 or later.
For more information about connecting to Azure resources from Visual Studio, see Assign Azure roles
using the Azure portal.
2. In Ser ver Explorer , expand Azure and expand App Ser vice .
3. Expand the resource group that includes the app that you created in Create an ASP.NET app in Azure App
Service, and then right-click the app node and click View Settings .
The Azure Web App tab appears, and you can see there the app management and configuration tasks
that are available in Visual Studio.
In this tutorial, you'll use the logging and tracing drop-downs. You'll also use remote debugging but you'll
use a different method to enable it.
For information about the App Settings and Connection Strings boxes in this window, see Azure App
Service: How Application Strings and Connection Strings Work.
If you want to perform an app management task that can't be done in this window, click Open in
Management Por tal to open a browser window to the Azure portal.
Visual Studio opens the Web.config file from the remote app and shows [Remote] next to the file name in
the title bar.
3. Add the following line to the system.web element:
<customErrors mode="Off"></customErrors>
4. Refresh the browser that is showing the unhelpful error message, and now you get a detailed error
message, such as the following example:
(The error shown was created by adding the line shown in red to Views\Home\Index.cshtml.)
Editing the Web.config file is only one example of scenarios in which the ability to read and edit files on your
App Service app make troubleshooting easier.
8. Click Publish . After deployment finishes and your browser opens to the Azure URL of your app, close the
browser.
9. In Ser ver Explorer , right-click your app, and then click Attach Debugger .
The browser automatically opens to your home page running in Azure. You might have to wait 20
seconds or so while Azure sets up the server for debugging. This delay only happens the first time you
run in debug mode on an app in a 48-hour period. When you start debugging again in the same period,
there isn't a delay.
NOTE
If you have any trouble starting the debugger, try to do it by using Cloud Explorer instead of Ser ver Explorer .
The time you see is the Azure server time, which may be in a different time zone than your local
computer.
12. Enter a new value for the currentTime variable, such as "Now running in Azure".
13. Press F5 to continue running.
The About page running in Azure displays the new value that you entered into the currentTime variable.
Remote debugging WebJobs
This section shows how to debug remotely using the project and app you create in Get Started with the Azure
WebJobs SDK.
The features shown in this section are available only in Visual Studio 2013 with Update 4 or later.
Remote debugging only works with continuous WebJobs. Scheduled and on-demand WebJobs don't support
debugging.
1. Open the web project that you created in Get Started with the Azure WebJobs SDK.
2. In the ContosoAdsWebJob project, open Functions.cs.
3. Set a breakpoint on the first statement in the GnerateThumbnail method.
4. In Solution Explorer , right-click the web project (not the WebJob project), and click Publish .
5. In the Profile drop-down list, select the same profile that you used in Get Started with the Azure
WebJobs SDK.
6. Click the Settings tab, and change Configuration to Debug , and then click Publish .
Visual Studio deploys the web and WebJob projects, and your browser opens to the Azure URL of your
app.
7. In Ser ver Explorer , expand Azure > App Ser vice > your resource group > your app > WebJobs
> Continuous , and then right-click ContosoAdsWebJob .
8. Click Attach Debugger .
The browser automatically opens to your home page running in Azure. You might have to wait 20
seconds or so while Azure sets up the server for debugging. This delay only happens the first time you
run in debug mode on an app in a 48-hour period. When you start debugging again in the same period,
there isn't a delay.
9. In the web browser that is opened to the Contoso Ads home page, create a new ad.
Creating an ad causes a queue message to be created, which is picked up by the WebJob and processed.
When the WebJobs SDK calls the function to process the queue message, the code hits your breakpoint.
10. When the debugger breaks at your breakpoint, you can examine and change variable values while the
program is running the cloud. In the following illustration, the debugger shows the contents of the
blobInfo object that was passed to the GenerateThumbnail method.
If your function wrote logs, you could click ToggleOutput to see them.
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
If you find that the debugger doesn't step into the code that you want to debug, you might have to
change the Just My Code setting. For more information, see Specify whether to debug only user code
using Just My Code in Visual Studio.
A timer starts on the server when you enable the remote debugging feature, and after 48 hours the
feature is automatically turned off. This 48-hour limit is done for security and performance reasons. You
can easily turn the feature back on as many times as you like. We recommend leaving it disabled when
you are not actively debugging.
You can manually attach the debugger to any process, not only the app process (w3wp.exe). For more
information about how to use debug mode in Visual Studio, see Debugging in Visual Studio.
The following steps show how to view trace output in a web page, without compiling in debug mode.
2. Open the application Web.config file (the one located in the project folder) and add a
<system.diagnostics> element at the end of the file just before the closing </configuration> element:
<system.diagnostics>
<trace>
<listeners>
<add name="WebPageTraceListener"
type="System.Web.WebPageTraceListener,
System.Web,
Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</listeners>
</trace>
</system.diagnostics>
The Request Details page appears, and in the Trace Information section you see the output from the
trace statements that you added to the Index method.
By default, trace.axd is only available locally. If you wanted to make it available from a remote app, you
could add localOnly="false" to the trace element in the Web.config file, as shown in the following
example:
However, enabling trace.axd in a production app is not recommended for security reasons. In the
following sections, you'll see an easier way to read tracing logs in an App Service app.
View the tracing output in Azure
1. In Solution Explorer , right-click the web project and click Publish .
2. In the Publish Web dialog box, click Publish .
After Visual Studio publishes your update, it opens a browser window to your home page (assuming you
didn't clear Destination URL on the Connection tab).
3. In Ser ver Explorer , right-click your app and select View Streaming Logs .
The Output window shows that you are connected to the log-streaming service, and adds a notification
line each minute that goes by without a log to display.
4. In the browser window that shows your application home page, click Contact .
Within a few seconds, the output from the error-level trace you added to the Contact method appears in
the Output window.
Visual Studio is only showing error-level traces because that is the default setting when you enable the
log monitoring service. When you create a new App Service app, all logging is disabled by default, as you
saw when you opened the settings page earlier:
However, when you selected View Streaming Logs , Visual Studio automatically changed Application
Logging(File System) to Error , which means error-level logs get reported. In order to see all of your
tracing logs, you can change this setting to Verbose . When you select a severity level lower than error, all
logs for higher severity levels are also reported. So when you select verbose, you also see information,
warning, and error logs.
5. In Ser ver Explorer , right-click the app, and then click View Settings as you did earlier.
6. Change Application Logging (File System) to Verbose , and then click Save .
7. In the browser window that is now showing your Contact page, click Home , then click About , and then
click Contact .
Within a few seconds, the Output window shows all of your tracing output.
In this section, you enabled and disabled logging by using app settings. You can also enable and disable
trace listeners by modifying the Web.config file. However, modifying the Web.config file causes the app
domain to recycle, while enabling logging via the app configuration doesn't do that. If the problem takes
a long time to reproduce, or is intermittent, recycling the app domain might "fix" it and force you to wait
until it happens again. Enabling diagnostics in Azure lets you start capturing error information
immediately without recycling the app domain.
Output window features
The Microsoft Azure Logs tab of the Output Window has several buttons and a text box:
3. In the Microsoft Azure Logging Options dialog box, select Web ser ver logs , and then click OK .
4. In the browser window that shows the app, click Home , then click About , and then click Contact .
The application logs generally appear first, followed by the web server logs. You might have to wait a
while for the logs to appear.
By default, when you first enable web server logs by using Visual Studio, Azure writes the logs to the file system.
As an alternative, you can use the Azure portal to specify that web server logs should be written to a blob
container in a storage account.
If you use the portal to enable web server logging to an Azure storage account, and then disable logging in
Visual Studio, when you re-enable logging in Visual Studio your storage account settings are restored.
4. In the address bar of the browser window, add an extra character to the URL to cause a 404 error (for
example, http://localhost:53370/Home/Contactx ), and press Enter.
After several seconds, the detailed error log appears in the Visual Studio Output window.
File Explorer opens to your Downloads folder with the downloaded file selected.
2. Extract the .zip file, and you see the following folder structure:
2. In the address bar of the browser window that shows the app, add an extra character to the URL and click
Enter to cause a 404 error.
This causes a failed request tracing log to be created, and the following steps show how to view or
download the log.
3. In Visual Studio, in the Configuration tab of the Azure Web App window, click Open in
Management Por tal .
4. In the Azure portal Settings page for your app, click Deployment credentials , and then enter a new
user name and password.
NOTE
When you log in, you have to use the full user name with the app name prefixed to it. For example, if you enter
"myid" as a user name and the site is "myexample", you log in as "myexample\myid".
5. In a new browser window, go to the URL that is shown under FTP hostname or FTPS hostname in the
Over view page for your app.
6. Sign in using the FTP credentials that you created earlier (including the app name prefix for the user
name).
The browser shows the root folder of the app.
7. Open the LogFiles folder.
9. Click the XML file for the failed request that you want to see tracing information for.
The following illustration shows part of the tracing information for a sample error.
Next Steps
You've seen how Visual Studio makes it easy to view logs created by an App Service app. The following sections
provide links to more resources on related topics:
App Service troubleshooting
Debugging in Visual Studio
Remote debugging in Azure
Tracing in ASP.NET applications
Analyzing web server logs
Analyzing failed request tracing logs
Debugging Cloud Services
App Service troubleshooting
For more information about troubleshooting apps in Azure App Service, see the following resources:
How to monitor apps
Investigating Memory Leaks in Azure App Service with Visual Studio 2013. Microsoft ALM blog post about
Visual Studio features for analyzing managed memory issues.
Azure App Service online tools you should know about. Blog post by Amit Apple.
For help with a specific troubleshooting question, start a thread in one of the following forums:
The Azure forum on the ASP.NET site.
The Azure forum on Microsoft Q&A.
StackOverflow.com.
Debugging in Visual Studio
For more information about how to use debug mode in Visual Studio, see Debugging in Visual Studio and
Debugging Tips with Visual Studio 2010.
Remote debugging in Azure
For more information about remote debugging for App Service apps and WebJobs, see the following resources:
Introduction to Remote Debugging Azure App Service.
Introduction to Remote Debugging Azure App Service part 2 - Inside Remote debugging
Introduction to Remote Debugging on Azure App Service part 3 - Multi-Instance environment and GIT
WebJobs Debugging (video)
If your app uses an Azure Web API or Mobile Services back-end and you need to debug that, see Debugging
.NET Backend in Visual Studio.
Tracing in ASP.NET applications
There are no thorough and up-to-date introductions to ASP.NET tracing available on the Internet. The best you
can do is get started with old introductory materials written for Web Forms because MVC didn't exist yet, and
supplement that with newer blog posts that focus on specific issues. Some good places to start are the following
resources:
Monitoring and Telemetry (Building Real-World Cloud Apps with Azure).
E-book chapter with recommendations for tracing in Azure cloud applications.
ASP.NET Tracing
Old but still a good resource for a basic introduction to the subject.
Trace Listeners
Information about trace listeners but doesn't mention the WebPageTraceListener.
Walkthrough: Integrating ASP.NET Tracing with System.Diagnostics Tracing
This article is also old, but includes some additional information that the introductory article doesn't
cover.
Tracing in ASP.NET MVC Razor Views
Besides tracing in Razor views, the post also explains how to create an error filter in order to log all
unhandled exceptions in an MVC application. For information about how to log all unhandled exceptions
in a Web Forms application, see the Global.asax example in Complete Example for Error Handlers on
MSDN. In either MVC or Web Forms, if you want to log certain exceptions but let the default framework
handling take effect for them, you can catch and rethrow as in the following example:
try
{
// Your code that might cause an exception to be thrown.
}
catch (Exception ex)
{
Trace.TraceError("Exception: " + ex.ToString());
throw;
}
Streaming Diagnostics Trace Logging from the Azure Command Line (plus Glimpse!)
How to use the command line to do what this tutorial shows how to do in Visual Studio. Glimpse is a tool
for debugging ASP.NET applications.
Using Web Apps Logging and Diagnostics - with David Ebbo and Streaming Logs from Web Apps - with
David Ebbo
Videos by Scott Hanselman and David Ebbo.
For error logging, an alternative to writing your own tracing code is to use an open-source logging framework
such as ELMAH. For more information, see Scott Hanselman's blog posts about ELMAH.
Also, you don't need to use ASP.NET or System.Diagnostics tracing to get streaming logs from Azure. The App
Service app streaming log service streams any .txt, .html, or .log file that it finds in the LogFiles folder. Therefore,
you could create your own logging system that writes to the file system of the app, and your file is automatically
streamed and downloaded. All you have to do is write application code that creates files in the d:\home\logfiles
folder.
Analyzing web server logs
For more information about analyzing web server logs, see the following resources:
LogParser
A tool for viewing data in web server logs (.log files).
Troubleshooting IIS Performance Issues or Application Errors using LogParser
An introduction to the Log Parser tool that you can use to analyze web server logs.
Blog posts by Robert McMurray on using LogParser
The HTTP status code in IIS 7.0, IIS 7.5, and IIS 8.0
Analyzing failed request tracing logs
The Microsoft TechNet website includes a Using Failed Request Tracing section, which may be helpful for
understanding how to use these logs. However, this documentation focuses mainly on configuring failed request
tracing in IIS, which you can't do in Azure App Service.
Best practices and troubleshooting guide for node
applications on Azure App Service Windows
5/18/2022 • 12 minutes to read • Edit Online
In this article, you learn best practices and troubleshooting steps for Windows Node.js applications running on
Azure App Service (with iisnode).
WARNING
Use caution when using troubleshooting steps on your production site. Recommendation is to troubleshoot your app on
a non-production setup for example your staging slot and when the issue is fixed, swap your staging slot with your
production slot.
IISNODE configuration
This schema file shows all the settings that you can configure for iisnode. Some of the settings that are useful for
your application:
nodeProcessCountPerApplication
This setting controls the number of node processes that are launched per IIS application. The default value is 1.
You can launch as many node.exes as your VM vCPU count by changing the value to 0. The recommended value
is 0 for most applications so you can use all of the vCPUs on your machine. Node.exe is single-threaded so one
node.exe consumes a maximum of 1 vCPU. To get maximum performance out of your node application, you
want to use all vCPUs.
nodeProcessCommandLine
This setting controls the path to the node.exe. You can set this value to point to your node.exe version.
maxConcurrentRequestsPerProcess
This setting controls the maximum number of concurrent requests sent by iisnode to each node.exe. On Azure
App Service, the default value is Infinite. You can configure the value depending on how many requests your
application receives and how fast your application processes each request.
maxNamedPipeConnectionRetry
This setting controls the maximum number of times iisnode retries making the connection on the named pipe to
send the requests to node.exe. This setting in combination with namedPipeConnectionRetryDelay determines
the total timeout of each request within iisnode. The default value is 200 on Azure App Service. Total Timeout in
seconds = (maxNamedPipeConnectionRetry * namedPipeConnectionRetryDelay) / 1000
namedPipeConnectionRetryDelay
This setting controls the amount of time (in ms) iisnode waits between each retry to send the request to
node.exe over the named pipe. The default value is 250 ms. Total Timeout in seconds =
(maxNamedPipeConnectionRetry * namedPipeConnectionRetryDelay) / 1000
By default, the total timeout in iisnode on Azure App Service is 200 * 250 ms = 50 seconds.
logDirectory
This setting controls the directory where iisnode logs stdout/stderr. The default value is iisnode, which is relative
to the main script directory (directory where main server.js is present)
debuggerExtensionDll
This setting controls what version of node-inspector iisnode uses when debugging your node application.
Currently, iisnode-inspector-0.7.3.dll and iisnode-inspector.dll are the only two valid values for this setting. The
default value is iisnode-inspector-0.7.3.dll. The iisnode-inspector-0.7.3.dll version uses node-inspector-0.7.3 and
uses web sockets. Enable web sockets on your Azure webapp to use this version.
flushResponse
The default behavior of IIS is that it buffers response data up to 4 MB before flushing, or until the end of the
response, whichever comes first. iisnode offers a configuration setting to override this behavior: to flush a
fragment of the response entity body as soon as iisnode receives it from node.exe, you need to set the
iisnode/@flushResponse attribute in web.config to 'true':
<configuration>
<system.webServer>
<!-- ... -->
<iisnode flushResponse="true" />
</system.webServer>
</configuration>
Enable the flushing of every fragment of the response entity body adds performance overhead that reduces the
throughput of the system by ~5% (as of v0.1.13). The best to scope this setting only to endpoints that require
response streaming (for example, using the <location> element in the web.config)
In addition to this, for streaming applications, you must also set responseBufferLimit of your iisnode handler to
0.
<handlers>
<add name="iisnode" path="app.js" verb="\*" modules="iisnode" responseBufferLimit="0"/>
</handlers>
watchedFiles
A semi-colon separated list of files that are watched for changes. Any change to a file causes the application to
recycle. Each entry consists of an optional directory name as well as a required file name, which are relative to
the directory where the main application entry point is located. Wild cards are allowed in the file name portion
only. The default value is *.js;iisnode.yml
recycleSignalEnabled
The default value is false. If enabled, your node application can connect to a named pipe (environment variable
IISNODE_CONTROL_PIPE) and send a “recycle” message. This causes the w3wp to recycle gracefully.
idlePageOutTimePeriod
The default value is 0, which means this feature is disabled. When set to some value greater than 0, iisnode will
page out all its child processes every ‘idlePageOutTimePeriod’ in milliseconds. See documentation to
understand what page out means. This setting is useful for applications that consume a high amount of memory
and want to page out memory to disk occasionally to free up RAM.
WARNING
Use caution when enabling the following configuration settings on production applications. The recommendation is to not
enable them on live production applications.
debugHeaderEnabled
The default value is false. If set to true, iisnode adds an HTTP response header iisnode-debug to every HTTP
response it sends the iisnode-debug header value is a URL. Individual pieces of diagnostic information can be
obtained by looking at the URL fragment, however, a visualization is available by opening the URL in a browser.
loggingEnabled
This setting controls the logging of stdout and stderr by iisnode. Iisnode captures stdout/stderr from node
processes it launches and writes to the directory specified in the ‘logDirectory’ setting. Once this is enabled,
your application writes logs to the file system and depending on the amount of logging done by the application,
there could be performance implications.
devErrorsEnabled
The default value is false. When set to true, iisnode displays the HTTP status code and Win32 error code on your
browser. The win32 code is helpful in debugging certain types of issues.
debuggingEnabled (do not enable on live production site )
This setting controls debugging feature. Iisnode is integrated with node-inspector. By enabling this setting, you
enable debugging of your node application. Upon enabling this setting, iisnode creates node-inspector files in
‘debuggerVirtualDir’ directory on the first debug request to your node application. You can load the node-
inspector by sending a request to http://yoursite/server.js/debug . You can control the debug URL segment
with ‘debuggerPathSegment’ setting. By default, debuggerPathSegment=’debug’. You can set
debuggerPathSegment to a GUID, for example, so that it is more difficult to be discovered by others.
IMPORTANT
This example assumes you have 4 node.exe running on your VM. If you have a different number of node.exe running on
the VM, you must modify the maxSockets setting accordingly.
function HandleRequest() {
WriteConsoleLog();
}
Go into your site/wwwroot directory. You see a command prompt as shown in the following example:
function WriteConsoleLog() {
for(let i=0;i<99999;++i) {
console.log('hello world');
}
}
function HandleRequest() {
profiler.startProfiling('HandleRequest');
WriteConsoleLog();
fs.writeFileSync('profile.cpuprofile', JSON.stringify(profiler.stopProfiling('HandleRequest')));
}
The preceding code profiles the WriteConsoleLog function and then writes the profile output to the
‘profile.cpuprofile’ file under your site wwwroot. Send a request to your application. You see a ‘profile.cpuprofile’
file created under your site wwwroot.
Download this file and open it with Chrome F12 Tools. Press F12 on Chrome, then choose the Profiles tab.
Choose the Load button. Select your profile.cpuprofile file that you downloaded. Click on the profile you just
loaded.
You can see that 95% of the time was consumed by the WriteConsoleLog function. The output also shows you
the exact line numbers and source files that caused the issue.
My node application is consuming too much memory
If your application is consuming too much memory, you see a notice from Azure App Service on your portal
about high memory consumption. You can set up monitors to watch for certain metrics. When checking the
memory usage on the Azure portal Dashboard, be sure to check the MAX values for memory so you don’t miss
the peak values.
Leak detection and Heap Diff for Node.js
You could use node-memwatch to help you identify memory leaks. You can install memwatch just like v8-profiler
and edit your code to capture and diff heaps to identify the memory leaks in your application.
My node.exe’s are getting killed randomly
There are a few reasons why node.exe is shut down randomly:
1. Your application is throwing uncaught exceptions – Check d:\home\LogFiles\Application\logging-errors.txt
file for the details on the exception thrown. This file has the stack trace to help debug and fix your application.
2. Your application is consuming too much memory, which is affecting other processes from getting started. If
the total VM memory is close to 100%, your node.exe’s could be killed by the process manager. Process
manager kills some processes to let other processes get a chance to do some work. To fix this issue, profile
your application for memory leaks. If your application requires large amounts of memory, scale up to a
larger VM (which increases the RAM available to the VM).
My node application does not start
If your application is returning 500 Errors when it starts, there could be a few reasons:
1. Node.exe is not present at the correct location. Check nodeProcessCommandLine setting.
2. Main script file is not present at the correct location. Check web.config and make sure the name of the main
script file in the handlers section matches the main script file.
3. Web.config configuration is not correct – check the settings names/values.
4. Cold Start – Your application is taking too long to start. If your application takes longer than
(maxNamedPipeConnectionRetry * namedPipeConnectionRetryDelay) / 1000 seconds, iisnode returns a 500
error. Increase the values of these settings to match your application start time to prevent iisnode from
timing out and returning the 500 error.
My node application crashed
Your application is throwing uncaught exceptions – Check d:\\home\\LogFiles\\Application\\logging-errors.txt
file for the details on the exception thrown. This file has the stack trace to help diagnose and fix your application.
My node application takes too much time to start (Cold Start)
The common cause for long application start times is a high number of files in the node_modules. The
application tries to load most of these files when starting. By default, since your files are stored on the network
share on Azure App Service, loading many files can take time. Some solutions to make this process faster are:
1. Try to lazy load your node_modules and not load all of the modules at application start. To Lazy load
modules, the call to require(‘module’) should be made when you actually need the module within the
function before the first execution of module code.
2. Azure App Service offers a feature called local cache. This feature copies your content from the network
share to the local disk on the VM. Since the files are local, the load time of node_modules is much faster.
NODE.exe has a setting called NODE_PENDING_PIPE_INSTANCES . On Azure App Service, this value is set to 5000.
Meaning that node.exe can accept 5000 requests at a time on the named pipe. This value should be good
enough for most node applications running on Azure App Service. You should not see 503.1003 on Azure App
Service because of the high value for the NODE_PENDING_PIPE_INSTANCES
More resources
Follow these links to learn more about Node.js applications on Azure App Service.
Get started with Node.js web apps in Azure App Service
How to debug a Node.js web app in Azure App Service
Using Node.js Modules with Azure applications
Azure App Service Web Apps: Node.js
Node.js Developer Center
Exploring the Super Secret Kudu Debug Console
Troubleshoot HTTP errors of "502 bad gateway" and
"503 service unavailable" in Azure App Service
5/18/2022 • 4 minutes to read • Edit Online
"502 bad gateway" and "503 service unavailable" are common errors in your app hosted in Azure App Service.
This article helps you troubleshoot these errors.
If you need more help at any point in this article, you can contact the Azure experts on the MSDN Azure and the
Stack Overflow forums. Alternatively, you can also file an Azure support incident. Go to the Azure Support site
and click on Get Suppor t .
Symptom
When you browse to the app, it returns a HTTP "502 Bad Gateway" error or a HTTP "503 Service Unavailable"
error.
Cause
This problem is often caused by application level issues, such as:
requests taking a long time
application using high memory/CPU
application crashing due to an exception.
2. Collect data
Use the diagnostics tool
App Service provides an intelligent and interactive experience to help you troubleshoot your app with no
configuration required. When you do run into issues with your app, the diagnostics tool will point out what’s
wrong to guide you to the right information to more easily and quickly troubleshoot and resolve the issue.
To access App Service diagnostics, navigate to your App Service app or App Service Environment in the Azure
portal. In the left navigation, click on Diagnose and solve problems .
Use the Kudu Debug Console
App Service comes with a debug console that you can use for debugging, exploring, uploading files, as well as
JSON endpoints for getting information about your environment. This is called the Kudu Console or the SCM
Dashboard for your app.
You can access this dashboard by going to the link https://<Your app name>.scm.azurewebsites.net/ .
Some of the things that Kudu provides are:
environment settings for your application
log stream
diagnostic dump
debug console in which you can run PowerShell cmdlets and basic DOS commands.
Another useful feature of Kudu is that, in case your application is throwing first-chance exceptions, you can use
Kudu and the SysInternals tool Procdump to create memory dumps. These memory dumps are snapshots of the
process and can often help you troubleshoot more complicated issues with your app.
For more information on features available in Kudu, see Azure Websites online tools you should know about.
You can also manage your app using Azure PowerShell. For more information, see Using Azure PowerShell with
Azure Resource Manager.
Troubleshoot slow app performance issues in Azure
App Service
5/18/2022 • 8 minutes to read • Edit Online
This article helps you troubleshoot slow app performance issues in Azure App Service.
If you need more help at any point in this article, you can contact the Azure experts on the MSDN Azure and the
Stack Overflow forums. Alternatively, you can also file an Azure support incident. Go to the Azure Support site
and click on Get Suppor t .
Symptom
When you browse the app, the pages load slowly and sometimes timeout.
Cause
This problem is often caused by application level issues, such as:
network requests taking a long time
application code or database queries being inefficient
application using high memory/CPU
application crashing due to an exception
Troubleshooting steps
Troubleshooting can be divided into three distinct tasks, in sequential order:
1. Observe and monitor application behavior
2. Collect data
3. Mitigate the issue
App Service gives you various options at each step.
2. Collect data
App Service provides diagnostic functionality for logging information from both the web server and the web
application. The information is separated into web server diagnostics and application diagnostics.
Enable web server diagnostics
You can enable or disable the following kinds of logs:
Detailed Error Logging - Detailed error information for HTTP status codes that indicate a failure (status
code 400 or greater). This may contain information that can help determine why the server returned the
error code.
Failed Request Tracing - Detailed information on failed requests, including a trace of the IIS components
used to process the request and the time taken in each component. This can be useful if you are attempting
to improve app performance or isolate what is causing a specific HTTP error.
Web Ser ver Logging - Information about HTTP transactions using the W3C extended log file format. This
is useful when determining overall app metrics, such as the number of requests handled or how many
requests are from a specific IP address.
Enable application diagnostics
There are several options to collect application performance data from App Service, profile your application live
from Visual Studio, or modify your application code to log more information and traces. You can choose the
options based on how much access you have to the application and what you observed from the monitoring
tools.
U se A p p l i c a t i o n I n si g h t s P r o fi l e r
You can enable the Application Insights Profiler to start capturing detailed performance traces. You can access
traces captured up to five days ago when you need to investigate problems happened in the past. You can
choose this option as long as you have access to the app's Application Insights resource on Azure portal.
Application Insights Profiler provides statistics on response time for each web call and traces that indicates
which line of code caused the slow responses. Sometimes the App Service app is slow because certain code is
not written in a performant way. Examples include sequential code that can be run in parallel and undesired
database lock contentions. Removing these bottlenecks in the code increases the app's performance, but they
are hard to detect without setting up elaborate traces and logs. The traces collected by Application Insights
Profiler helps identifying the lines of code that slows down the application and overcome this challenge for App
Service apps.
For more information, see Profiling live apps in Azure App Service with Application Insights.
U se R e m o t e P r o fi l i n g
In Azure App Service, web apps, API apps, mobile back ends, and WebJobs can be remotely profiled. Choose this
option if you have access to the app resource and you know how to reproduce the issue, or if you know the
exact time interval the performance issue happens.
Remote Profiling is useful if the CPU usage of the process is high and your process is running slower than
expected, or the latency of HTTP requests are higher than normal, you can remotely profile your process and get
the CPU sampling call stacks to analyze the process activity and code hot paths.
For more information, see Remote Profiling support in Azure App Service.
Se t u p d i a g n o st i c t r a c e s m a n u a l l y
If you have access to the web application source code, Application diagnostics enables you to capture
information produced by a web application. ASP.NET applications can use the System.Diagnostics.Trace class to
log information to the application diagnostics log. However, you need to change the code and redeploy your
application. This method is recommended if your app is running on a testing environment.
For detailed instructions on how to configure your application for logging, see Enable diagnostics logging for
apps in Azure App Service.
Use the diagnostics tool
App Service provides an intelligent and interactive experience to help you troubleshoot your app with no
configuration required. When you do run into issues with your app, the diagnostics tool will point out what’s
wrong to guide you to the right information to more easily and quickly troubleshoot and resolve the issue.
To access App Service diagnostics, navigate to your App Service app or App Service Environment in the Azure
portal. In the left navigation, click on Diagnose and solve problems .
Use the Kudu Debug Console
App Service comes with a debug console that you can use for debugging, exploring, uploading files, as well as
JSON endpoints for getting information about your environment. This console is called the Kudu Console or the
SCM Dashboard for your app.
You can access this dashboard by going to the link https://<Your app name>.scm.azurewebsites.net/ .
Some of the things that Kudu provides are:
environment settings for your application
log stream
diagnostic dump
debug console in which you can run PowerShell cmdlets and basic DOS commands.
Another useful feature of Kudu is that, in case your application is throwing first-chance exceptions, you can use
Kudu and the SysInternals tool Procdump to create memory dumps. These memory dumps are snapshots of the
process and can often help you troubleshoot more complicated issues with your app.
For more information on features available in Kudu, see Azure DevOps tools you should know about.
You can also manage your app using Azure PowerShell. For more information, see Using Azure PowerShell with
Azure Resource Manager.
More resources
Tutorial: Run a load test to identify performance bottlenecks in a web app
Troubleshoot domain and TLS/SSL certificate
problems in Azure App Service
5/18/2022 • 12 minutes to read • Edit Online
This article lists common problems that you might encounter when you configure a domain or TLS/SSL
certificate for your web apps in Azure App Service. It also describes possible causes and solutions for these
problems.
If you need more help at any point in this article, you can contact the Azure experts on Microsoft Q & A and
Stack Overflow forums. Alternatively, you can file an Azure support incident. Go to the Azure Support site and
select Get Suppor t .
NOTE
This article uses the Azure Az PowerShell module, which is the recommended PowerShell module for interacting with
Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az
PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
Certificate problems
You can't add a TLS/SSL certificate binding to an app
Symptom
When you add a TLS binding, you receive the following error message:
"Failed to add SSL binding. Cannot set certificate for existing VIP because another VIP already uses that
certificate."
Cause
This problem can occur if you have multiple IP-based TLS/SSL bindings for the same IP address across multiple
apps. For example, app A has an IP-based TLS/SSL binding with an old certificate. App B has an IP-based
TLS/SSL binding with a new certificate for the same IP address. When you update the app TLS binding with the
new certificate, it fails with this error because the same IP address is being used for another app.
Solution
To fix this problem, use one of the following methods:
Delete the IP-based TLS/SSL binding on the app that uses the old certificate.
Create a new IP-based TLS/SSL binding that uses the new certificate.
You can't delete a certificate
Symptom
When you try to delete a certificate, you receive the following error message:
"Unable to delete the certificate because it is currently being used in a TLS/SSL binding. The TLS binding must
be removed before you can delete the certificate."
Cause
This problem might occur if another app uses the certificate.
Solution
Remove the TLS binding for that certificate from the apps. Then try to delete the certificate. If you still can't
delete the certificate, clear the internet browser cache and reopen the Azure portal in a new browser window.
Then try to delete the certificate.
You can't purchase an App Service certificate
Symptom
You can't purchase an Azure App Service certificate from the Azure portal.
Cause and solution
This problem can occur for any of the following reasons:
The App Service plan is Free or Shared. These pricing tiers don't support TLS.
Solution : Upgrade the App Service plan for app to Standard.
The subscription doesn't have a valid credit card.
Solution : Add a valid credit card to your subscription.
The subscription offer doesn't support purchasing an App Service certificate such as Microsoft Student.
Solution : Upgrade your subscription.
The subscription reached the limit of purchases that are allowed on a subscription.
Solution : App Service certificates have a limit of 10 certificate purchases for the Pay-As-You-Go and EA
subscription types. For other subscription types, the limit is 3. To increase the limit, contact Azure support.
The App Service certificate was marked as fraud. You received the following error message: "Your
certificate has been flagged for possible fraud. The request is currently under review. If the certificate
does not become usable within 24 hours, contact Azure Support."
Solution : If the certificate is marked as fraud and isn't resolved after 24 hours, follow these steps:
1. Sign in to the Azure portal.
2. Go to App Ser vice Cer tificates , and select the certificate.
3. Select Cer tificate Configuration > Step 2: Verify > Domain Verification . This step sends an
email notice to the Azure certificate provider to resolve the problem.
Domain problems
You purchased a TLS/SSL certificate for the wrong domain
Symptom
You purchased an App Service certificate for the wrong domain. You can't update the certificate to use the
correct domain.
Solution
Delete that certificate and then buy a new certificate.
If the current certificate that uses the wrong domain is in the “Issued” state, you'll also be billed for that
certificate. App Service certificates are not refundable, but you can contact Azure support to see whether there
are other options.
An App Service certificate was renewed, but the app shows the old certificate
Symptom
The App Service certificate was renewed, but the app that uses the App Service certificate is still using the old
certificate. Also, you received a warning that the HTTPS protocol is required.
Cause
App Service automatically syncs your certificate within 48 hours. When you rotate or update a certificate,
sometimes the application is still retrieving the old certificate and not the newly updated certificate. The reason
is that the job to sync the certificate resource hasn't run yet. Click Sync. The sync operation automatically
updates the hostname bindings for the certificate in App Service without causing any downtime to your apps.
Solution
You can force a sync of the certificate:
1. Sign in to the Azure portal. Select App Ser vice Cer tificates , and then select the certificate.
2. Select Rekey and Sync , and then select Sync . The sync takes some time to finish.
3. When the sync is completed, you see the following notification: "Successfully updated all the resources with
the latest certificate."
Domain verification is not working
Symptom
The App Service certificate requires domain verification before the certificate is ready to use. When you select
Verify , the process fails.
Solution
Manually verify your domain by adding a TXT record:
1. Go to the Domain Name Service (DNS) provider that hosts your domain name.
2. Add a TXT record for your domain that uses the value of the domain token that's shown in the Azure portal.
Wait a few minutes for DNS propagation to run, and then select the Refresh button to trigger the verification.
As an alternative, you can use the HTML webpage method to manually verify your domain. This method allows
the certificate authority to confirm the domain ownership of the domain that the certificate is issued for.
1. Create an HTML file that's named {domain verification token}.html. The content of this file should be the
value of domain verification token.
2. Upload this file at the root of the web server that's hosting your domain.
3. Select Refresh to check the certificate status. It might take few minutes for verification to finish.
For example, if you're buying a standard certificate for azure.com with the domain verification token 1234abcd,
a web request made to https://azure.com/1234abcd.html should return 1234abcd.
IMPORTANT
A certificate order has only 15 days to complete the domain verification operation. After 15 days, the certificate authority
denies the certificate, and you are not charged for the certificate. In this situation, delete this certificate and try again.
REC O RD T Y P E H O ST P O IN T TO
TXT @ <app-name>.azurewebsites.net
FAQ
Do I have to configure my custom domain for my website once I buy it?
When you purchase a domain from the Azure portal, the App Service application is automatically configured to
use that custom domain. You don’t have to take any additional steps. For more information, watch Azure App
Service Self Help: Add a Custom Domain Name on Channel9.
Can I use a domain purchased in the Azure por tal to point to an Azure VM instead?
Yes, you can point the domain to a VM. For more information, see Use Azure DNS to provide custom domain
settings for an Azure service.
Is my domain hosted by GoDaddy or Azure DNS?
App Service Domains use GoDaddy for domain registration and Azure DNS to host the domains.
I have auto-renew enabled but still received a renewal notice for my domain via email. What
should I do?
If you have auto-renew enabled, you do not need to take any action. The notice email is provided to inform you
that the domain is close to expiring and to renew manually if auto-renew is not enabled.
Will I be charged for Azure DNS hosting my domain?
The initial cost of domain purchase applies to domain registration only. In addition to the registration cost, there
are incurring charges for Azure DNS based on your usage. For more information, see Azure DNS pricing for
more details.
I purchased my domain earlier from the Azure por tal and want to move from GoDaddy hosting to
Azure DNS hosting. How can I do this?
It is not mandatory to migrate to Azure DNS hosting. If you do want to migrate to Azure DNS, the domain
management experience in the Azure portal about provides information on steps necessary to move to Azure
DNS. If the domain was purchased through App Service, migration from GoDaddy hosting to Azure DNS is
relatively seamless procedure.
I would like to purchase my domain from App Ser vice Domain but can I host my domain on
GoDaddy instead of Azure DNS?
Beginning July 24, 2017, App Service domains purchased in the portal are hosted on Azure DNS. If you prefer to
use a different hosting provider, you must go to their website to obtain a domain hosting solution.
Do I have to pay for privacy protection for my domain?
When you purchase a domain through the Azure portal, you can choose to add privacy at no additional cost.
This is one of the benefits of purchasing your domain through Azure App Service.
If I decide I no longer want my domain, can I get my money back?
When you purchase a domain, you are not charged for a period of five days, during which time you can decide
that you do not want the domain. If you do decide you don’t want the domain within that five-day period, you
are not charged. (.uk domains are an exception to this. If you purchase a .uk domain, you are charged
immediately and you cannot be refunded.)
Can I use the domain in another Azure App Ser vice app in my subscription?
Yes. When you access the Custom Domains and TLS blade in the Azure portal, you see the domains that you
have purchased. You can configure your app to use any of those domains.
Can I transfer a domain from one subscription to another subscription?
You can move a domain to another subscription/resource group using the Move-AzResource PowerShell cmdlet.
How can I manage my custom domain if I don’t currently have an Azure App Ser vice app?
You can manage your domain even if you don’t have an App Service Web App. Domain can be used for Azure
services like Virtual machine, Storage etc. If you intend to use the domain for App Service Web Apps, then you
need to include a Web App that is not on the Free App Service plan in order to bind the domain to your web
app.
Can I move a web app with a custom domain to another subscription or from App Ser vice
Environment v1 to V2?
Yes, you can move your web app across subscriptions. Follow the guidance in How to move resources in Azure.
There are a few limitations when moving the web app. For more information, see Limitations for moving App
Service resources.
After moving the web app, the host name bindings of the domains within the custom domains setting should
remain the same. No additional steps are required to configure the host name bindings.
How to prepare for an inbound IP address change
5/18/2022 • 2 minutes to read • Edit Online
If you received a notification that the inbound IP address of your Azure App Service app is changing, follow the
instructions in this article.
Next steps
This article explained how to prepare for an IP address change that was initiated by Azure. For more information
about IP addresses in Azure App Service, see Inbound and outbound IP addresses in Azure App Service.
How to prepare for an outbound IP address change
5/18/2022 • 2 minutes to read • Edit Online
If you received a notification that the outbound IP addresses of your Azure App Service app are changing, follow
the instructions in this article.
Next steps
This article explained how to prepare for an IP address change that was initiated by Azure. For more information
about IP addresses in Azure App Service, see Inbound and outbound IP addresses in Azure App Service.
How to prepare for a TLS/SSL IP address change
5/18/2022 • 2 minutes to read • Edit Online
If you received a notification that the TLS/SSL IP address of your Azure App Service app is changing, follow the
instructions in this article to release existing TLS/SSL IP address and assign a new one.
NOTE
Service Endpoint is not currently supported when enabling IP Based SSL on App Service TLS/SSL bindings.
Next steps
This article explained how to prepare for an IP address change that was initiated by Azure. For more information
about IP addresses in Azure App Service, see Inbound and outbound IP addresses in Azure App Service.