Service | Microsoft Docs article | Related commit history on GitHub | Change details |
---|---|---|---|
app-service | App Service Web Tutorial Rest Api | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/app-service-web-tutorial-rest-api.md | Title: 'Tutorial: Host RESTful API with CORS' -description: Learn how Azure App Service helps you host your RESTful APIs with CORS support. App Service can host both front-end web apps and back end APIs. + Title: 'Tutorial: Host a RESTful API with CORS' +description: Learn how Azure App Service helps you host your RESTful APIs with CORS support. App Service can host both front-end web apps and back-end APIs. ms.assetid: a820e400-06af-4852-8627-12b3db4a8e70 ms.devlang: csharp Previously updated : 01/31/2023 Last updated : 09/05/2024 -[Azure App Service](overview.md) provides a highly scalable, self-patching web hosting service. In addition, App Service has built-in support for [Cross-Origin Resource Sharing (CORS)](https://wikipedia.org/wiki/Cross-Origin_Resource_Sharing) 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. +[Azure App Service](overview.md) provides a highly scalable self-patching web hosting service. In addition, App Service has built-in support for [cross-origin resource sharing (CORS)](https://wikipedia.org/wiki/Cross-Origin_Resource_Sharing) 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: > [!div class="checklist"]-> * Create App Service resources using Azure CLI -> * Deploy a RESTful API to Azure using Git -> * Enable App Service CORS support +> * 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. +You can complete this tutorial on macOS, Linux, or Windows. [!INCLUDE [quickstarts-free-trial-note](~/reusable-content/ce-skilling/azure/includes/quickstarts-free-trial-note.md)] ## Prerequisites -To complete this tutorial: +* <a href="https://git-scm.com/" target="_blank">Install Git.</a> + * <a href="https://dotnet.microsoft.com/download/dotnet-core/3.1" target="_blank">Install the latest .NET Core 3.1 SDK.</a> -* <a href="https://git-scm.com/" target="_blank">Install Git</a> - * <a href="https://dotnet.microsoft.com/download/dotnet-core/3.1" target="_blank">Install the latest .NET Core 3.1 SDK</a> --## Create local ASP.NET Core app +## Create a local ASP.NET Core app In this step, you set up the local ASP.NET Core project. App Service supports the same workflow for APIs written in other languages. ### Clone the sample application -1. In the terminal window, `cd` to a working directory. +1. In the terminal window, use `cd` to go to a working directory. -1. Clone the sample repository and change to the repository root. +1. Clone the sample repository, and then go to the repository root. ```bash git clone https://github.com/Azure-Samples/dotnet-core-api cd dotnet-core-api ``` - This repository contains an app that's created based on the following tutorial: [ASP.NET Core Web API help pages using Swagger](/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio). It uses a Swagger generator to serve the [Swagger UI](https://swagger.io/swagger-ui/) and the Swagger JSON endpoint. + This repository contains an app that's created based on the tutorial [ASP.NET Core web API documentation with Swagger / OpenAPI](/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio). It uses a Swagger generator to serve the [Swagger UI](https://swagger.io/swagger-ui/) and the Swagger JSON endpoint. 1. Make sure the default branch is `main`. In this step, you set up the local ASP.NET Core project. App Service supports th ``` > [!TIP]- > The branch name change isn't required by App Service. However, since many repositories are changing their default branch to `main` (see [Change deployment branch](deploy-local-git.md#change-deployment-branch)), this tutorial also shows you how to deploy a repository from `main`. + > The branch name change isn't required by App Service. However, since many repositories are changing their default branch to `main` (see [Change deployment branch](deploy-local-git.md#change-deployment-branch)), this tutorial shows you how to deploy a repository from `main`. ### Run the application In this step, you set up the local ASP.NET Core project. App Service supports th dotnet run ``` -1. Navigate to `http://localhost:5000/swagger` in a browser to play with the Swagger UI. +1. Navigate to `http://localhost:5000/swagger` in a browser to try the Swagger UI. - ![ASP.NET Core API running locally](./media/app-service-web-tutorial-rest-api/azure-app-service-local-swagger-ui.png) + ![Screenshot of an ASP.NET Core API running locally.](./media/app-service-web-tutorial-rest-api/azure-app-service-local-swagger-ui.png) -1. Navigate to `http://localhost:5000/api/todo` and see a list of ToDo JSON items. +1. Navigate to `http://localhost:5000/api/todo` to see a list of ToDo JSON items. -1. Navigate to `http://localhost:5000` and play with the browser app. Later, you will point the browser app to a remote API in App Service to test CORS functionality. Code for the browser app is found in the repository's _wwwroot_ directory. +1. Navigate to `http://localhost:5000` and experiment with the browser app. Later, you'll point the browser app to a remote API in App Service to test CORS functionality. Code for the browser app is found in the repository's _wwwroot_ directory. -1. To stop ASP.NET Core at any time, press `Ctrl+C` in the terminal. +1. To stop ASP.NET Core at any time, select **Ctrl+C** in the terminal. [!INCLUDE [cloud-shell-try-it.md](~/reusable-content/ce-skilling/azure/includes/cloud-shell-try-it.md)] -## Deploy app to Azure +## Deploy the app to Azure In this step, you deploy your .NET Core application to App Service. -### Configure local git deployment +### Configure local Git deployment [!INCLUDE [Configure a deployment user](../../includes/configure-deployment-user-no-h.md)] In this step, you deploy your .NET Core application to App Service. [!INCLUDE [app-service-plan-no-h](../../includes/app-service-web-git-push-to-azure-no-h.md)] - <pre> + ``` Enumerating objects: 83, done. Counting objects: 100% (83/83), done. Delta compression using up to 8 threads In this step, you deploy your .NET Core application to App Service. remote: Deployment successful. To https://<app_name>.scm.azurewebsites.net/<app_name>.git * [new branch] master -> master- </pre> + ``` ### Browse to the Azure app -1. Navigate to `http://<app_name>.azurewebsites.net/swagger` in a browser and play with the Swagger UI. +1. Navigate to `http://<app_name>.azurewebsites.net/swagger` in a browser and view the Swagger UI. - ![ASP.NET Core API running in Azure App Service](./media/app-service-web-tutorial-rest-api/azure-app-service-browse-app.png) + ![Screenshot of an ASP.NET Core API running in Azure App Service.](./media/app-service-web-tutorial-rest-api/azure-app-service-browse-app.png) 1. Navigate to `http://<app_name>.azurewebsites.net/swagger/v1/swagger.json` to see the _swagger.json_ for your deployed API. In this step, you deploy your .NET Core application to App Service. Next, you enable the built-in CORS support in App Service for your API. -### Test CORS in sample app +### Test CORS in the sample app 1. In your local repository, open _wwwroot/https://docsupdatetracker.net/index.html_. -1. In Line 51, set the `apiEndpoint` variable to the URL of your deployed API (`http://<app_name>.azurewebsites.net`). Replace _\<appname>_ with your app name in App Service. +1. On line 51, set the `apiEndpoint` variable to the URL of your deployed API (`http://<app_name>.azurewebsites.net`). Replace _\<appname>_ with your app name in App Service. 1. In your local terminal window, run the sample app again. Next, you enable the built-in CORS support in App Service for your API. dotnet run ``` -1. 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`. +1. 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`. - ![CORS error in browser client](./media/app-service-web-tutorial-rest-api/azure-app-service-cors-error.png) + ![Screenshot of the CORS error in the browser client.](./media/app-service-web-tutorial-rest-api/azure-app-service-cors-error.png) - The domain mismatch between the browser app (`http://localhost:5000`) and remote resource (`http://<app_name>.azurewebsites.net`) is recognized by your browser as a cross-origin resource request. Also, the fact that your REST API the App Service app is not sending the `Access-Control-Allow-Origin` header, the browser has prevented cross-domain content from loading. + The domain mismatch between the browser app (`http://localhost:5000`) and remote resource (`http://<app_name>.azurewebsites.net`) is recognized by your browser as a cross-origin resource request. Also, because the App Service app isn't sending the `Access-Control-Allow-Origin` header, the browser has prevented cross-domain content from loading. - 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. + In production, your browser app would have a public URL instead of the localhost URL, but the process for enabling CORS to a localhost URL is the same as the process for a public URL. ### Enable CORS -In the Cloud Shell, enable CORS to your client's URL by using the [`az webapp cors add`](/cli/azure/webapp/cors#az-webapp-cors-add) command. Replace the _<app-name>_ placeholder. +In Cloud Shell, enable CORS to your client's URL by using the [`az webapp cors add`](/cli/azure/webapp/cors#az-webapp-cors-add) command. Replace the _<app-name>_ placeholder. ```azurecli-interactive az webapp cors add --resource-group myResourceGroup --name <app-name> --allowed-origins 'http://localhost:5000' ``` -You can add multiple allowed origins by running the command multiple times or by adding a comma-separate list in `--allowed-origins`. To allow all origins, use `--allowed-origins '*'`. +You can add multiple allowed origins by running the command multiple times or by adding a comma-separated list in `--allowed-origins`. To allow all origins, use `--allowed-origins '*'`. ### 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. -![CORS success in browser client](./media/app-service-web-tutorial-rest-api/azure-app-service-cors-success.png) +![Screenshot that shows CORS support in the browser client.](./media/app-service-web-tutorial-rest-api/azure-app-service-cors-success.png) Congratulations, you're running an API in Azure App Service with CORS support. Congratulations, you're running an API in Azure App Service with CORS support. #### App Service CORS vs. your CORS -You can use your own CORS utilities instead of App Service CORS for more flexibility. For example, you may want to specify different allowed origins for different routes or methods. Since App Service CORS lets you specify one set of accepted origins for all API routes and methods, you would want to use your own CORS code. See how ASP.NET Core does it at [Enabling Cross-Origin Requests (CORS)](/aspnet/core/security/cors). +You can use your own CORS utilities instead of App Service CORS for more flexibility. For example, you might want to specify different allowed origins for different routes or methods. Since App Service CORS lets you specify only one set of accepted origins for all API routes and methods, you would want to use your own CORS code. See how CORS is enabled in ASP.NET Core at [Enable CORS](/aspnet/core/security/cors). -The built-in App Service CORS feature does not have options to allow only specific HTTP methods or verbs for each origin that you specify. It will automatically allow all methods and headers for each origin defined. This behavior is similar to [ASP.NET Core CORS](/aspnet/core/security/cors) policies when you use the options `.AllowAnyHeader()` and `.AllowAnyMethod()` in the code. +The built-in App Service CORS feature doesn't have options to allow only specific HTTP methods or verbs for each origin that you specify. It will automatically allow all methods and headers for each origin defined. This behavior is similar to [ASP.NET Core CORS](/aspnet/core/security/cors) policies when you use the options `.AllowAnyHeader()` and `.AllowAnyMethod()` in the code. > [!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. +> Don't try to use App Service CORS and your own CORS code together. If you try to use them together, App Service CORS takes precedence and your own CORS code has no effect. > > #### How do I set allowed origins to a wildcard subdomain? -A wildcard subdomain like `*.contoso.com` is more restrictive than the wildcard origin `*`. However, the app's CORS management page in the Azure portal doesn't let you set a wildcard subdomain as an allowed origin. However, you can do it using the Azure CLI, like so: +A wildcard subdomain like `*.contoso.com` is more restrictive than the wildcard origin `*`. The app's CORS management page in the Azure portal doesn't let you set a wildcard subdomain as an allowed origin. However, you can do that by using Azure CLI, like so: ```azurecli-interactive az webapp cors add --resource-group <group-name> --name <app-name> --allowed-origins 'https://*.contoso.com' az webapp cors add --resource-group <group-name> --name <app-name> --allowed-ori #### How do I enable the ACCESS-CONTROL-ALLOW-CREDENTIALS header on the response? -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`. +If your app requires credentials such as cookies or authentication tokens to be sent, the browser might require the `ACCESS-CONTROL-ALLOW-CREDENTIALS` header on the response. To enable this in App Service, set `properties.cors.supportCredentials` to `true`: ```azurecli-interactive az resource update --name web --resource-group <group-name> \ az resource update --name web --resource-group <group-name> \ --parent sites/<app-name> --set properties.cors.supportCredentials=true ``` -This operation is not allowed when allowed origins include the wildcard origin `'*'`. Specifying `AllowAnyOrigin` and `AllowCredentials` is an insecure configuration and can result in cross-site request forgery. To allow credentials, try replacing the wildcard origin with [wildcard subdomains](#how-do-i-set-allowed-origins-to-a-wildcard-subdomain). +This operation isn't allowed when allowed origins include the wildcard origin `'*'`. Specifying `AllowAnyOrigin` and `AllowCredentials` isn't secure. Doing so can result in cross-site request forgery. To allow credentials, try replacing the wildcard origin with [wildcard subdomains](#how-do-i-set-allowed-origins-to-a-wildcard-subdomain). [!INCLUDE [cli-samples-clean-up](../../includes/cli-samples-clean-up.md)] This operation is not allowed when allowed origins include the wildcard origin ` What you learned: > [!div class="checklist"]-> * Create App Service resources using Azure CLI -> * Deploy a RESTful API to Azure using Git -> * Enable App Service CORS support +> * Create App Service resources using Azure CLI. +> * Deploy a RESTful API to Azure using Git. +> * Enable App Service CORS support. -Advance to the next tutorial to learn how to authenticate and authorize users. +Go to the next tutorial to learn how to authenticate and authorize users. > [!div class="nextstepaction"] > [Tutorial: Authenticate and authorize users end-to-end](tutorial-auth-aad.md) |
app-service | Monitor Instances Health Check | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/monitor-instances-health-check.md | description: Learn how to monitor the health of App Service instances using Heal keywords: azure app service, web app, health check, route traffic, healthy instances, path, monitoring, remove faulty instances, unhealthy instances, remove workers - Previously updated : 08/26/2022+ Last updated : 09/13/2024 -# Monitor App Service instances using Health check +# Monitor App Service instances by using Health check [!INCLUDE [regionalization-note](./includes/regionalization-note.md)] -This article uses Health check in the Azure portal to monitor App Service instances. Health check increases your application's availability by rerouting requests away from unhealthy instances and replacing instances if they remain unhealthy. It does that by pinging every minute a path of your web application of your choice. +This article describes how to use Health check in the Azure portal to monitor App Service instances. Health check increases your application's availability by rerouting requests away from unhealthy instances and replacing instances if they remain unhealthy. It does that by pinging your web application every minute, via a path that you choose. -![Health check failure][1] +![Diagram that shows how Health check works.][1] -Note that _/api/health_ is just an example added for illustration purposes. We don't create a Health Check path by default. You should make sure that the path you are selecting is a valid path that exists within your application +Note that _/api/health_ is just an example. There is no default Health check path. You should make sure that the path you choose is a valid path that exists within your application. -## What App Service does with Health checks +## How Health check works -- When given a path on your app, Health check pings this path on all instances of your App Service app at 1-minute intervals.-- If a web app that's running on a given instance doesn't respond with a status code between 200-299 (inclusive) after 10 requests, App Service determines it's unhealthy and removes it from the load balancer for this Web App. The required number of failed requests for an instance to be deemed unhealthy is configurable to a minimum of two requests.-- After removal, Health check continues to ping the unhealthy instance. If the instance begins to respond with a healthy status code (200-299), then the instance is returned to the load balancer.+- When given a path on your app, Health check pings the path on all instances of your App Service app at 1-minute intervals. +- If a web app that's running on a given instance doesn't respond with a status code between 200 and 299 (inclusive) after 10 requests, App Service determines the instance is unhealthy and removes it from the load balancer for the web app. The required number of failed requests for an instance to be deemed unhealthy is configurable to a minimum of two requests. +- After the instance is removed, Health check continues to ping it. If the instance begins to respond with a healthy status code (200-299), then the instance is returned to the load balancer. - If the web app that's running on an instance remains unhealthy for one hour, the instance is replaced with a new one. - When scaling out, App Service pings the Health check path to ensure new instances are ready. > [!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. +>- At most, one instance will be replaced per hour, with a maximum of three instances per day per App Service Plan. +>- If Health check is sending 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 -![Health check navigation in Azure portal][3] 1. To enable Health check, browse to the Azure portal and select your App Service app.-2. Under **Monitoring**, select **Health check**. -3. Select **Enable** and provide a valid URL path on your application, such as `/health` or `/api/health`. -4. Select **Save**. +1. Under **Monitoring**, select **Health check**. +1. Select **Enable** and provide a valid URL path for your application, such as `/health` or `/api/health`. +1. Select **Save**. > [!NOTE] > - Your [App Service plan](./overview-hosting-plans.md) 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 can't connect to a critical component, then the path should return a 500-level response code to indicate the app is unhealthy. Also, if the path does not return a response within 1 minute, the health check ping is considered unhealthy. -> - When selecting the Health check path, make sure you're selecting a path that returns a 200 status code, only when the app is fully warmed up. -> - In order to use Health check on your Function App, you must use a [premium or dedicated hosting plan](../azure-functions/functions-scale.md#overview-of-plans). -> - Details about Health check on Function Apps can be found here: [Monitor function apps using Health check](../azure-functions/configure-monitoring.md?#monitor-function-apps-using-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 can't connect to a critical component, then the path should return a 500-level response code to indicate the app is unhealthy. Also, if the path doesn't return a response within one minute, the health check ping is considered unhealthy. +> - When selecting the Health check path, make sure you're selecting a path that returns a 200 status code only when the app is fully warmed up. +> - In order to use Health check on a function app, you must use a [premium or dedicated hosting plan](../azure-functions/functions-scale.md#overview-of-plans). +> - Details about Health check on function apps can be found here: [Monitor function apps using Health check](../azure-functions/configure-monitoring.md?#monitor-function-apps-using-health-check). > [!CAUTION] > Health check configuration changes restart your app. To minimize impact to production apps, we recommend [configuring staging slots](deploy-staging-slots.md) and swapping to production. In addition to configuring the Health check options, you can also configure the | App setting name | Allowed values | Description | |-|-|-|-|`WEBSITE_HEALTHCHECK_MAXPINGFAILURES` | 2 - 10 | The required number of failed requests for an instance to be deemed unhealthy and removed from the load balancer. For example, when set to `2`, your instances are removed after `2` failed pings. (Default value is `10`) | -|`WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT` | 1 - 100 | 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 are excluded. The other two instances (one healthy and one unhealthy) continue to receive requests. In the worst-case scenario where all instances are unhealthy, none are excluded. <br /> To override this behavior, set app setting to a value between `1` and `100`. A higher value means more unhealthy instances are removed (default value is `50`). | +|`WEBSITE_HEALTHCHECK_MAXPINGFAILURES` | 2 - 10 | The required number of failed requests for an instance to be deemed unhealthy and removed from the load balancer. For example, when this is set to `2`, your instances are removed after 2 failed pings. (The default value is `10`.) | +|`WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT` | 1 - 100 | By default, to avoid overwhelming the remaining healthy instances, no more than half of the instances will be excluded from the load balancer at a time. For example, if an App Service plan is scaled to four instances and three are unhealthy, two are excluded. The other two instances (one healthy and one unhealthy) continue to receive requests. In a scenario where all instances are unhealthy, none are excluded. <br /> To override this behavior, set this app setting to a value between `1` and `100`. A higher value means more unhealthy instances are removed. (The default value is `50`.). | #### Authentication and security -Health check integrates with App Service's [authentication and authorization features](overview-authentication-authorization.md). No other settings are required if these security features are enabled. +Health check integrates with the App Service [authentication and authorization features](overview-authentication-authorization.md). No other settings are required if these security features are enabled. -If you're using your own authentication system, the Health check path must allow anonymous access. To secure the Health check endpoint, you should first use features such as [IP restrictions](app-service-ip-restrictions.md#set-an-ip-address-based-rule), [client certificates](app-service-ip-restrictions.md#set-an-ip-address-based-rule), or a Virtual Network to restrict application access. Once you have those features in-place, you can authenticate the health check request by inspecting the header, `x-ms-auth-internal-token`, and validating that it matches the SHA256 hash of the environment variable `WEBSITE_AUTH_ENCRYPTION_KEY`. If they match, then the health check request is valid and originating from App Service. +If you're using your own authentication system, the Health check path must allow anonymous access. To provide security for the Health check endpoint, you should first use features such as [IP restrictions](app-service-ip-restrictions.md#set-an-ip-address-based-rule), [client certificates](tutorial-secure-domain-certificate.md), or a virtual network to restrict application access. Once you have those features in place, you can authenticate the Health check request by inspecting the header `x-ms-auth-internal-token` and validating that it matches the SHA256 hash of the environment variable `WEBSITE_AUTH_ENCRYPTION_KEY`. If they match, then the Health check request is valid and originating from App Service. > [!NOTE]-> Specifically for [Azure Functions authentication](/azure/azure-functions/security-concepts?tabs=v4#function-access-keys), the function that serves as Health check endpoint needs to allow anonymous access. +> For [Azure Functions authentication](/azure/azure-functions/security-concepts?tabs=v4#function-access-keys), the function that serves as the Health check endpoint needs to allow anonymous access. ##### [.NET](#tab/dotnet) function envVarMatchesHeader(headerValue) { > [!NOTE]-> The `x-ms-auth-internal-token` header is only available on Windows App Service. +> The `x-ms-auth-internal-token` header is only available on App Service for Windows. ## Instances -Once Health Check is enabled, you can restart and monitor the status of your application instances through the instances tab. The instances tab shows your instance's name, the status of that application's instance and gives you the option to manually restart the instance. +Once Health check is enabled, you can restart and monitor the status of your application instances from the instances tab. The instances tab shows your instance's name and the status of that application's instance. You can also manually restart the instance from this tab. -If the status of your application instance is unhealthy, you can restart the instance manually using the restart button in the table. Keep in mind that any other applications hosted on the same App Service Plan as the instance will also be affected by the restart. If there are other applications using the same App Service Plan as the instance, they're listed on the opening blade from the restart button. +If the status of your application instance is "unhealthy," you can restart the instance manually by using the restart button in the table. Keep in mind that any other applications hosted on the same App Service plan as the instance will also be affected by the restart. If there are other applications using the same App Service plan as the instance, they're listed on the opening blade from the restart button. -If you restart the instance and the restart process fails, you'll then be given the option to replace the worker (only one instance can be replaced per hour). This will also affect any applications using the same App Service Plan. +If you restart the instance and the restart process fails, you'll be given the option to replace the worker. (Only one instance can be replaced per hour.) This will also affect any applications using the same App Service plan. -Windows applications will also have the option to view processes via the Process Explorer. This gives you further insight on the instance's processes including thread count, private memory, and total CPU time. +For Windows applications, you can also view processes via the Process Explorer. This gives you further insight on the instance's processes, including thread count, private memory, and total CPU time. ## Diagnostic information collection-For Windows applications, you have the option to collect diagnostic information in the Health Check tab. Enabling diagnostic collection adds an auto-heal rule that creates memory dumps for unhealthy instances and saves it to a designated storage account. Enabling this option changes auto-heal configurations. If there are existing auto-heal rules, we recommend setting this up through App Service diagnostics. -Once diagnostic collection is enabled, you can create or choose an existing storage account for your files. You can only select storage accounts in the same region as your application. Keep in mind that saving restarts your application. After saving, if your site instances are found to be unhealthy after continuous pings, you can go to your storage account resource and view the memory dumps. +For Windows applications, you have the option to collect diagnostic information on the Health Check tab. Enabling diagnostic collection adds an auto-heal rule that creates memory dumps for unhealthy instances and saves them to a designated storage account. Enabling this option changes auto-heal configurations. If there are existing auto-heal rules, we recommend setting this up through App Service diagnostics. +Once diagnostic collection is enabled, you can create a storage account or choose an existing one for your files. You can only select storage accounts in the same region as your application. Keep in mind that saving restarts your application. After saving, if your site instances are found to be unhealthy after continuous pings, you can go to your storage account resource and view the memory dumps. ## 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, select the **Metrics** in the top toolbar. This opens a new blade where you can see the site's historical health status and option to create a new alert rule. Health check metrics 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](web-sites-monitor.md). +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, select **Metrics** in the top toolbar. This opens a new blade where you can see the site's health status history and create a new alert rule. Health check metrics aggregate the successful pings and display failures only when the instance was deemed unhealthy based on the Health check configuration. For more information on monitoring your sites, see [Azure App Service quotas and alerts](web-sites-monitor.md). ## Limitations -- Health check can be enabled for **Free** and **Shared** App Service Plans so you can have metrics on the site's health and setup alerts, but because **Free** and **Shared** sites can't scale out, any unhealthy instances won't 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 increases your app's availability and performance.-- The App Service plan can have a maximum of one unhealthy instance replaced per hour and, at most, three instances per day.-- There's a nonconfigurable limit on the total number of instances replaced by Health Check per scale unit. If this limit is reached, no unhealthy instances are replaced. This value gets reset every 12 hours.+- 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. However, because **Free** and **Shared** sites can't scale out, unhealthy instances won't be replaced. You should scale up to the **Basic** tier or higher so you can scale out to two or more instances and get the full benefit of Health check. This is recommended for production-facing applications as it increases your app's availability and performance. +- An App Service plan can have a maximum of one unhealthy instance replaced per hour and, at most, three instances per day. +- There's a nonconfigurable limit on the total number of instances replaced by Health check per scale unit. If this limit is reached, no unhealthy instances are replaced. This value gets reset every 12 hours. -## Frequently Asked Questions +## Frequently asked questions ### What happens if my app is running on a single instance? -If your app is only scaled to one instance and becomes unhealthy, it will not be removed from the load balancer because that would take down your application entirely. However, after one hour of continuous unhealthy pings, the instance is replaced. Scale out to two or more instances to get the rerouting benefit of Health check. If your app is running on a single instance, you can still use Health check's [monitoring](#monitoring) feature to keep track of your application's health. +If your app is only scaled to one instance and becomes unhealthy, it won't be removed from the load balancer because that would take down your application entirely. However, after one hour of continuous unhealthy pings, the instance is replaced. Scale out to two or more instances to get the rerouting benefit of Health check. If your app is running on a single instance, you can still use the Health check [monitoring](#monitoring) feature to keep track of your application's health. ### Why are the Health check requests not showing in my web server logs? The Health check requests are sent to your site internally, so the request won't show in [the web server logs](troubleshoot-diagnostic-logs.md#enable-web-server-logging). You can add log statements in your Health check code to keep logs of when your Health check path is pinged. -### Are the Health check requests sent over HTTP or HTTPS? +### Are Health check requests sent over HTTP or HTTPS? -On Windows and Linux App Service, the Health check requests are sent via HTTPS when [HTTPS Only](configure-ssl-bindings.md#enforce-https) is enabled on the site. Otherwise, they're sent over HTTP. +On App Service for Windows and Linux, the Health check requests are sent via HTTPS when [HTTPS Only](configure-ssl-bindings.md#enforce-https) is enabled on the site. Otherwise, they're sent over HTTP. -### Is Health check following the application code configured redirects between the default domain and the custom domain? +### Does Health check follow the application-code configured redirects between the default domain and the custom domain? -No, the Health check feature is pinging the path of the default domain of the web application. If there's a redirect from the default domain to a custom domain, then the status code that Health check is returning is not going to be a 200 but a redirect (301), which is going to mark the worker unhealthy. +No, the Health check feature pings the path of the default domain of the web application. If there's a redirect from the default domain to a custom domain, then the status code that Health check returns won't be a 200. It will be a redirect (301), which marks the worker unhealthy. +### What if I have multiple apps on the same App Service plan? -### What if I have multiple apps on the same App Service Plan? --Unhealthy instances will always be removed from the load balancer rotation regardless of other apps on the App Service Plan (up to the percentage specified in [`WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT`](#configuration)). When an app on an instance remains unhealthy for over one hour, the instance will only be replaced if all other apps with Health check enabled are also unhealthy. Apps that don't have Health check enabled won't be taken into account. +Unhealthy instances will always be removed from the load balancer rotation regardless of other apps on the App Service plan (up to the percentage specified in [`WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT`](#configuration)). When an app on an instance remains unhealthy for more than one hour, the instance will only be replaced if all other apps on which Health check is enabled are also unhealthy. Apps that don't have Health check enabled won't be taken into account. #### Example -Imagine you have two applications (or one app with a slot) with Health check enabled, called App A and App B. They're on the same App Service Plan and that the Plan is scaled out to four instances. If App A becomes unhealthy on two instances, the load balancer stops sending requests to App A on those two instances. Requests are still routed to App B on those instances assuming App B is healthy. If App A remains unhealthy for over an hour on those two instances, those instances are only replaced if App B is **also** unhealthy on those instances. If App B is healthy, the instance isn't replaced. +Imagine you have two applications (or one app with a slot) with Health check enabled. They're called App A and App B. They're on the same App Service plan, and the plan is scaled out to four instances. If App A becomes unhealthy on two instances, the load balancer stops sending requests to App A on those two instances. Requests are still routed to App B on those instances, assuming App B is healthy. If App A remains unhealthy for more than an hour on those two instances, the instances are only replaced if App B is **also** unhealthy on those instances. If App B is healthy, the instances aren't replaced. -![Visual diagram explaining the example scenario above.][2] +![Diagram of the example scenario.][2] > [!NOTE]-> If there were another site or slot on the Plan (Site C) without Health check enabled, it would not be taken into consideration for the instance replacement. +> If there were another site or slot on the plan (App C) without Health check enabled, it wouldn't be taken into consideration for the instance replacement. ### What if all my instances are unhealthy? -In the scenario where all instances of your application are unhealthy, App Service will not remove instances from the load balancer. In this scenario, taking all unhealthy app instances out of the load balancer rotation would effectively cause an outage for your application; however, the instances replacement will still be honored. +If all instances of your application are unhealthy, App Service won't remove instances from the load balancer. In this scenario, taking all unhealthy app instances out of the load balancer rotation would effectively cause an outage for your application. However, the instance replacement will still occur. ### Does Health check work on App Service Environments? -Yes, health check is available for the App Service Environment v3, but not for versions 1 or 2. If you are using the older versions of the App Service Environment, you can use the [migration feature](environment/migrate.md) to migrate your App Service Environment to version 3. +Yes, health check is available for App Service Environment v3, but not for versions 1 or 2. If you're using the older versions of App Service Environment, you can use the [migration feature](environment/migrate.md) to migrate your App Service Environment to version 3. ## Next steps+ - [Create an Activity Log Alert to monitor all Autoscale engine operations on your subscription](https://github.com/Azure/azure-quickstart-templates/tree/master/demos/monitor-autoscale-alert) - [Create an Activity Log Alert to monitor all failed Autoscale scale-in/scale-out operations on your subscription](https://github.com/Azure/azure-quickstart-templates/tree/master/demos/monitor-autoscale-failed-alert) - [Environment variables and app settings reference](reference-app-settings.md) [1]: ./media/app-service-monitor-instances-health-check/health-check-diagram.png [2]: ./media/app-service-monitor-instances-health-check/health-check-multi-app-diagram.png-[3]: ./media/app-service-monitor-instances-health-check/azure-portal-navigation-health-check.png + |
app-service | Quickstart Python | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/quickstart-python.md | Title: 'Quickstart: Deploy a Python (Django, Flask, or FastAPI) web app to Azure' description: Get started with Azure App Service by deploying your first Python app to Azure App Service. Previously updated : 06/28/2024 Last updated : 09/13/2024 ms.devlang: python To complete this quickstart, you need: > [!NOTE] > This article contains current instructions on deploying a Python web app using Azure App Service. Python on Windows is no longer supported. -## 1 - Sample application +## Sample application This quickstart can be completed using either Flask, Django, or FastAPI. 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. Having issues? [Let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). -## 2 - Create a web app in Azure +## Create a web app in Azure -To host your application in Azure, you need to create Azure App Service web app in Azure. You can create a web app using the Azure CLI, [VS Code](https://code.visualstudio.com/), [Azure Tools extension pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-node-azure-pack), or [Azure portal](https://portal.azure.com/). +To host your application in Azure, you need to create an Azure App Service web app in Azure. You can create a web app using the Azure CLI, [VS Code](https://code.visualstudio.com/), [Azure Tools extension pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-node-azure-pack), or the [Azure portal](https://portal.azure.com/). ### [Azure CLI](#tab/azure-cli) code . | [!INCLUDE [Create app service step 3](./includes/quickstart-python/create-app-service-visual-studio-code-3.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-4-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to select Create a new Web App." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-4.png"::: | | [!INCLUDE [Create app service step 4](./includes/quickstart-python/create-app-service-visual-studio-code-4.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-5-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to enter the globally unique name for the new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-5.png"::: | | [!INCLUDE [Create app service step 5](./includes/quickstart-python/create-app-service-visual-studio-code-5.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-6-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to select the runtime stack for the new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-6.png"::: |-| [!INCLUDE [Create app service step 6](./includes/quickstart-python/create-app-service-visual-studio-code-6.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-7-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to a pricing tier for the new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-7.png"::: | -| [!INCLUDE [Create app service step 7](./includes/quickstart-python/create-app-service-visual-studio-code-7.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-7b-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to start deploy to new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-7b.png"::: | +| [!INCLUDE [Create app service step 6](./includes/quickstart-python/create-app-service-visual-studio-code-6.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-7-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to select a pricing tier for the new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-7.png"::: | +| [!INCLUDE [Create app service step 7](./includes/quickstart-python/create-app-service-visual-studio-code-7.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-7b-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to deploy a new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-7b.png"::: | | [!INCLUDE [Create app service step 8](./includes/quickstart-python/create-app-service-visual-studio-code-8.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-7c-240-px.png" alt-text="A screenshot of the dialog box in VS Code used to select the folder to deploy as the new web app." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-7c.png"::: | | [!INCLUDE [Create app service step 9](./includes/quickstart-python/create-app-service-visual-studio-code-9.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-8-240-px.png" alt-text="A screenshot of a dialog box in VS Code asking if you want to update your workspace to run build commands." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-8.png"::: | | [!INCLUDE [Create app service step 10](./includes/quickstart-python/create-app-service-visual-studio-code-10.md)] | :::image type="content" source="./media/quickstart-python/create-app-service-visual-studio-code-9-240-px.png" alt-text="A screenshot showing the confirmation dialog when the app code has been deployed to Azure." lightbox="./media/quickstart-python/create-app-service-visual-studio-code-9.png"::: | Sign in to the [Azure portal](https://portal.azure.com/) and follow these steps Having issues? [Let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). -## 3 - Deploy your application code to Azure +## Deploy your application code to Azure -Azure App service supports multiple methods to deploy your application code to Azure including support for GitHub Actions and all major CI/CD tools. This article focuses on how to deploy your code from your local workstation to Azure. +Azure App Service supports multiple methods to deploy your application code to Azure, including GitHub Actions and all major CI/CD tools. This article focuses on how to deploy your code from your local workstation to Azure. ### [Deploy using Azure CLI](#tab/azure-cli-deploy) Azure App service supports multiple methods to deploy your application code to A -Having issues? Refer first to the [Troubleshooting guide](./configure-language-python.md#troubleshooting), otherwise, [let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). +Having issues? Refer first to the [Troubleshooting guide](./configure-language-python.md#troubleshooting). If that doesn't help, [let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). -## 4 - Configure startup script +## Configure startup script Based on the presence of certain files in a deployment, App Service automatically detects whether an app is a Django or Flask app and performs default steps to run your app. For apps based on other web frameworks like FastAPI, you need to configure a startup script for App Service to run your app; otherwise, App Service runs a default read-only app located in the *opt/defaultsite* folder. For FastAPI, you must configure a custom startup command for App Service to run -## 5 - Browse to the app +## Browse to the app -Browse to the deployed application in your web browser at the URL `http://<app-name>.azurewebsites.net`. If you see a default app page, wait a minute and refresh the browser. +Browse to the deployed application in your web browser by using the URL `http://<app-name>.azurewebsites.net`. If you see a default app page, wait a minute and refresh the browser. The Python sample code is running a Linux container in App Service using a built-in image. The Python sample code is running a Linux container in App Service using a built **Congratulations!** You've deployed your Python app to App Service. -Having issues? Refer first to the [Troubleshooting guide](./configure-language-python.md#troubleshooting), otherwise, [let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). +Having issues? Refer first to the [Troubleshooting guide](./configure-language-python.md#troubleshooting). If that doesn't help, [let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). -## 6 - Stream logs +## 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. +Azure App Service captures all message output to the console to assist you in diagnosing issues with your application. The sample apps include `print()` statements to demonstrate this capability. ### [Flask](#tab/flask) Azure App Service captures all messages output to the console to assist you in d -The contents of the App Service diagnostic logs can be reviewed using the Azure CLI, VS Code, or Azure portal. +You can review the contents of the App Service diagnostic logs by using the Azure CLI, VS Code, or the Azure portal. ### [Azure CLI](#tab/azure-cli) -First, you need to configure Azure App Service to output logs to the App Service filesystem using the [az webapp log config](/cli/azure/webapp/log#az-webapp-log-config) command. +First, you need to configure Azure App Service to output logs to the App Service filesystem by using the [az webapp log config](/cli/azure/webapp/log#az-webapp-log-config) command. [!INCLUDE [CLI stream logs configure](./includes/quickstart-python/stream-logs-cli-1.md)] Starting Live Log Stream | Instructions | Screenshot | |:-|--:|-| [!INCLUDE [Stream logs from Azure portal 1](./includes/quickstart-python/stream-logs-azure-portal-1.md)] | :::image type="content" source="./media/quickstart-python/stream-logs-azure-portal-1-240px.png" alt-text="A screenshot of the location in the Azure portal where to enable streaming logs." lightbox="./media/quickstart-python/stream-logs-azure-portal-1.png"::: | +| [!INCLUDE [Stream logs from Azure portal 1](./includes/quickstart-python/stream-logs-azure-portal-1.md)] | :::image type="content" source="./media/quickstart-python/stream-logs-azure-portal-1-240px.png" alt-text="A screenshot of the location in the Azure portal where you enable streaming logs." lightbox="./media/quickstart-python/stream-logs-azure-portal-1.png"::: | | [!INCLUDE [Stream logs from Azure portal 2](./includes/quickstart-python/stream-logs-azure-portal-2.md)] | :::image type="content" source="./media/quickstart-python/stream-logs-azure-portal-2-240px.png" alt-text="A screenshot of how to view logs in the Azure portal." lightbox="./media/quickstart-python/stream-logs-azure-portal-2.png"::: | -Having issues? Refer first to the [Troubleshooting guide](./configure-language-python.md#troubleshooting), otherwise, [let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). +Having issues? Refer first to the [Troubleshooting guide](./configure-language-python.md#troubleshooting). If that doesn't help, [let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). ## 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. +When you're finished with the sample app, you can remove all of the resources for the app from Azure. Removing the resource group ensures that you don't incur extra charges and helps 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 CLI](#tab/azure-cli) az group delete \ The `--no-wait` argument allows the command to return before the operation is complete. -### [VS Code](#tab/vscode-aztools) +### [VS Code](#tab/vscode-aztools) | Instructions | Screenshot | |:-|--:| Having issues? [Let us know](https://aka.ms/PythonAppServiceQuickstartFeedback). > [Tutorial: Python (Django or Flask) web app with PostgreSQL](./tutorial-python-postgresql-app.md) > [!div class="nextstepaction"]-> [Configure Python app](./configure-language-python.md) +> [Configure a Python app](./configure-language-python.md) > [!div class="nextstepaction"] > [Add user sign-in to a Python web app](../active-directory/develop/quickstart-v2-python-webapp.md) > [!div class="nextstepaction"]-> [Tutorial: Run Python app in custom container](./tutorial-custom-container.md) +> [Tutorial: Run a Python app in a custom container](./tutorial-custom-container.md) > [!div class="nextstepaction"]-> [Secure with custom domain and certificate](tutorial-secure-domain-certificate.md) +> [Secure an app with a custom domain and certificate](tutorial-secure-domain-certificate.md) |
app-service | Tutorial Custom Container | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/tutorial-custom-container.md | Title: 'Tutorial: Build and run a custom image in Azure App Service' description: A step-by-step guide to build a custom Linux or Windows image, push the image to Azure Container Registry, and then deploy that image to Azure App Service. Learn how to migrate custom software to App Service in a custom container. Previously updated : 11/29/2022 Last updated : 09/04/2024 keywords: azure app service, web app, linux, windows, docker, container zone_pivot_groups: app-service-containers-windows-linux ::: zone pivot="container-windows" -[Azure App Service](overview.md) 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: +[Azure App Service](overview.md) provides pre-defined application stacks, like ASP.NET or Node.js, on Windows. These application stacks run 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](operating-system-functionality.md). -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](../container-registry/index.yml), and then run it in App Service. +You can deploy a custom-configured Windows image from Visual Studio to make OS changes that your app needs. This makes it easy to migrate an on-premises app that requires a 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](../container-registry/index.yml) and then run it in App Service. :::image type="content" source="media/tutorial-custom-container/app-running-newupdate.png" alt-text="Shows the web app running in a Windows container."::: You can deploy a custom-configured Windows image from Visual Studio to make OS c To complete this tutorial: -- <a href="https://hub.docker.com/" target="_blank">Sign up for a Docker Hub account</a>+- <a href="https://hub.docker.com/" target="_blank">Sign up for a Docker Hub account</a>. - <a href="https://docs.docker.com/docker-for-windows/install/" target="_blank">Install Docker for Windows</a>.-- <a href="/virtualization/windowscontainers/quick-start/quick-start-windows-10" target="_blank">Switch Docker to run Windows containers</a>.+- <a href="/virtualization/windowscontainers/quick-start/quick-start-windows-10" target="_blank">Configure Docker to run Windows containers</a>. - <a href="https://www.visualstudio.com/downloads/" target="_blank">Install Visual Studio 2022</a> 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 selecting **Help** > **Check for Updates**. - Add the workloads in Visual Studio by selecting **Tools** > **Get Tools and Features**. In this step, you set up the local .NET project. - [Download the sample project](https://github.com/Azure-Samples/custom-font-win-container/archive/master.zip). - Extract (unzip) the *custom-font-win-container-master.zip* file. -The sample project contains a simple ASP.NET application that uses a custom font that is installed into the Windows font library. It's not necessary to install fonts. However, the sample is an example of an app that is integrated with the underlying OS. To migrate such an app to App Service, you either rearchitect your code to remove the integration, or migrate it as-is in a custom Windows container. +The sample project contains a simple ASP.NET application that uses a custom font that's installed into the Windows font library. It's not necessary to install fonts. However, the sample is an example of an app that's integrated with the underlying OS. To migrate such an app to App Service, you either rearchitect your code to remove the integration, or migrate it as-is in a custom Windows container. ### Install the font This font is publicly available from [Google Fonts](https://fonts.google.com/spe Open the *custom-font-win-container-master/CustomFontSample.sln* file in Visual Studio. -Type `Ctrl+F5` to run the app without debugging. The app is displayed in your default browser. +Select **Ctrl+F5** to run the app without debugging. The app is displayed in your default browser. :::image type="content" source="media/tutorial-custom-container/local-app-in-browser.png" alt-text="Screenshot showing the app displayed in the default browser."::: As the app uses an installed font, the app can't run in the App Service sandbox. In Solution Explorer, right-click the **CustomFontSample** project and select **Add** > **Container Orchestration Support**. Select **Docker Compose** > **OK**. You can find *InstallFont.ps1* in the **CustomFontSample** project. It's a simpl ## Publish to Azure Container Registry -[Azure Container Registry](../container-registry/index.yml) can store your images for container deployments. You can configure App Service to use images hosted in Azure Container Registry. +[Azure Container Registry](../container-registry/index.yml) can store your images for container deployments. You can configure App Service to use images that are hosted in Azure Container Registry. -### Open publish wizard +### Open the publish wizard In the Solution Explorer, right-click the **CustomFontSample** project and select **Publish**. -### Create registry and publish +### Create and publish the registry In the publish wizard, select **Container Registry** > **Create New Azure Container Registry** > **Publish**. -### Sign in with Azure account +### Sign in with an Azure account -In the **Create a new Azure Container Registry** dialog, select **Add an account**, and sign in to your Azure subscription. If you're already signed in, select the account containing the desired subscription from the dropdown. +In the **Create a new Azure Container Registry** dialog, select **Add an account**, and then sign in to your Azure subscription. If you're already signed in, select the account containing the desired subscription from the dropdown. ### Configure the registry -Configure the new container registry based on the suggested values in the following table. When finished, select **Create**. +Configure the new container registry by using the suggested values in the following table as a guide. When finished, select **Create**. -| Setting | Suggested value | For more information | -| -- | | -| -|**DNS Prefix**| Keep the generated registry name, or change it to another unique name. | | -|**Resource Group**| Select **New**, type **myResourceGroup**, and select **OK**. | | -|**SKU**| Basic | [Pricing tiers](https://azure.microsoft.com/pricing/details/container-registry/)| -|**Registry Location**| West Europe | | +| Setting | Suggested value | +| -- | | +|**DNS Prefix**| Keep the generated registry name, or change it to another unique name. | +|**Resource Group**| Select **New**, type **myResourceGroup**, and select **OK**. | +|**SKU**| **Basic**. For more information, see [Pricing tiers](https://azure.microsoft.com/pricing/details/container-registry/). | +|**Registry Location**| **West Europe** | -A terminal window is opened and displays the image deployment progress. Wait for the deployment to complete. +A terminal window opens and displays the image deployment progress. Wait for the deployment to complete. ## Sign in to Azure From the left menu, select **Create a resource** > **Web** > **Web App for Conta ### Configure app basics -In the **Basics** tab, configure the settings according to the following table, then select **Next: Docker**. +On the **Basics** tab, configure the settings according to the following table. Then select **Next: Docker**. -| Setting | Suggested value | For more information | -| -- | | -| -|**Subscription**| Make sure the correct subscription is selected. | | -|**Resource Group**| Select **Create new**, type **myResourceGroup**, and select **OK**. | | -|**Name**| Type a unique name. | The URL of the web app is `https://<app-name>.azurewebsites.net`, where `<app-name>` is your app name. | -|**Publish**| Docker container | | -|**Operating System**| Windows | | -|**Region**| West Europe | | -|**Windows Plan**| Select **Create new**, type **myAppServicePlan**, and select **OK**. | | +| Setting | Suggested value | +| -- | | +|**Subscription**| Make sure the correct subscription is selected. | +|**Resource Group**| Select **Create new**, type **myResourceGroup**, and select **OK**. | +|**Name**| Type a unique name. The URL of the web app is `https://<app-name>.azurewebsites.net`, where `<app-name>` is your app name. | +|**Publish**| **Docker Container** | +|**Operating System**| **Windows** | +|**Region**| **West Europe** | +|**Windows Plan**| Select **Create new**, type **myAppServicePlan**, and select **OK**. | Your **Basics** tab should look like this: -### Configure Windows container +### Configure the Windows container -In the **Docker** tab, configure your custom Windows container as shown in the following table, and select **Review + create**. +On the **Docker** tab, configure your custom Windows container as shown in the following table, and then select **Review + create**. | Setting | Suggested value | | -- | | Select **Create** and wait for Azure to create the required resources. ## Browse to the web app -When the Azure operation is complete, a notification box is displayed. +When the deployment is complete, a notification box is displayed. :::image type="content" source="media/tutorial-custom-container/portal-create-finished.png" alt-text="Shows that the Azure operation is complete."::: A new browser page is opened to the following page: :::image type="content" source="media/tutorial-custom-container/app-starting.png" alt-text="Shows the new browser page for the web app."::: -Wait a few minutes and try again, until you get the homepage with the beautiful font you expect: +Wait a few minutes and try again, until you get the homepage with the font you expect: **Congratulations!** You've migrated an ASP.NET application to Azure App Service in a Windows container. -## See container start-up logs +## View the container start-up logs -It might take some time for the Windows container to load. To see the progress, go to the following URL by replacing *\<app-name>* with the name of your app. +It might take some time for the Windows container to load. To see the progress, go to the following URL. (Replace \<app-name> with the name of your app.) ``` https://<app-name>.scm.azurewebsites.net/api/logstream ``` The streamed logs look like this: 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'](/cli/azure/webapp#az-webapp-list-runtimes). If those images don't satisfy your needs, you can build and deploy a custom image. > [!NOTE]-> Container should target x86-x64 architecture, ARM64 is not supported. +> Your container should target the x86-64 architecture. ARM64 is not supported. > In this tutorial, you learn how to: > [!div class="checklist"] >-> - 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 +> - Push a custom Docker image to Azure Container Registry. +> - Deploy the custom image to App Service. +> - Configure environment variables. +> - Pull the image into App Service by using a managed identity. +> - Access diagnostic logs. +> - Enable CI/CD from Azure Container Registry to App Service. +> - Connect to the container by 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. +Completing this tutorial incurs a small charge in your Azure account for the container registry and can incur more costs if you host the container for longer than a month. ## Set up your initial environment docker --version You can obtain the sample for this tutorial via git clone or download. -### Clone with git +### Clone with Git Clone the sample repository: Clone the sample repository: git clone https://github.com/Azure-Samples/docker-django-webapp-linux.git --config core.autocrlf=input ``` -Ensure that you include the `--config core.autocrlf=input` argument to guarantee proper line endings in files that are used inside the Linux container: +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: +Then navigate to the folder: ```terminal cd docker-django-webapp-linux cd docker-django-webapp-linux ### Download from GitHub -Instead of using git clone, you can visit [https://github.com/Azure-Samples/docker-django-webapp-linux](https://github.com/Azure-Samples/docker-django-webapp-linux), select **Clone**, and then select **Download ZIP**. +Instead of using git clone, you can visit [https://github.com/Azure-Samples/docker-django-webapp-linux](https://github.com/Azure-Samples/docker-django-webapp-linux) and select **Code** > **Local** > **Download ZIP**. Unpack the ZIP file into a folder named *docker-django-webapp-linux*. -Then, open a terminal window in the*docker-django-webapp-linux* folder. +Then open a terminal window in the *docker-django-webapp-linux* folder. ## (Optional) Examine the Docker file -The file in the sample named *Dockerfile* that describes the docker image and contains configuration instructions: +This is the file in the sample that's named *Dockerfile*. It describes the Docker image and contains configuration instructions. ```Dockerfile FROM tiangolo/uwsgi-nginx-flask:python3.6 ENTRYPOINT ["init.sh"] ``` - The first group of commands installs the app's requirements in the environment.-- The second group of commands create an [SSH](https://www.ssh.com/ssh/protocol/) server for secure communication between the container and the host.+- The second group of commands creates an [SSH](https://www.ssh.com/ssh/protocol/) server to provide improved-security communication between the container and the host. - The last line, `ENTRYPOINT ["init.sh"]`, invokes `init.sh` to start the SSH service and Python server. ## Build and test the image locally > [!NOTE]-> Docker Hub has [quotas on the number of anonymous pulls per IP and the number of authenticated pulls per free user (see **Data transfer**)](https://www.docker.com/pricing). If you notice your pulls from Docker Hub are being limited, try `docker login` if you're not already logged in. +> Docker Hub has [quotas on the number of anonymous pulls per IP and the number of authenticated pulls per free user.](https://www.docker.com/pricing) If you notice your pulls from Docker Hub are being limited, try `docker login` if you're not already logged in. > 1. Run the following command to build the image: ENTRYPOINT ["init.sh"] docker run -it -p 8000:8000 appsvc-tutorial-custom-image ``` - This [`docker run`](https://docs.docker.com/engine/reference/commandline/run/) command specifies the port with the `-p` argument followed by the name of the image. `-it` lets you stop it with `Ctrl+C`. + This [`docker run`](https://docs.docker.com/engine/reference/commandline/run/) command specifies the port with the `-p` argument and includes 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. + > 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 CRLF 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. -1. Browse to `http://localhost:8000` to verify the web app and container are functioning correctly. +1. Browse to `http://localhost:8000` to verify that the web app and container are functioning correctly. - :::image type="content" source="./media/app-service-linux-using-custom-docker-image/app-service-linux-browse-local.png" alt-text="Test web app locally."::: + :::image type="content" source="./media/app-service-linux-using-custom-docker-image/app-service-linux-browse-local.png" alt-text="Screenshot of the test results."::: ## I. Create a user-assigned managed identity -App Service can either use a default managed identity or a user-assigned managed identity to authenticate with a container registry. In this tutorial, you'll use a user-assigned managed identity. +App Service can use either a default managed identity or a user-assigned managed identity to authenticate with a container registry. In this tutorial, you'll use a user-assigned managed identity. ### [Azure CLI](#tab/azure-cli) App Service can either use a default managed identity or a user-assigned managed You can change the `--location` value to specify a region near you. -1. Create a managed identity in the resource group. +1. Create a managed identity in the resource group: ```azurecli-interactive az identity create --name myID --resource-group msdocs-custom-container-tutorial App Service can either use a default managed identity or a user-assigned managed :::column span="2"::: **I.B.** In the create wizard: 1. In **Subscription**, select the subscription you want to create your resources in.- 1. In **Resource group**, select **Create new**, type the name *msdocs-custom-container-tutorial* for the resource group, then type **OK**. + 1. In **Resource group**, select **Create new**, type the name *msdocs-custom-container-tutorial* for the resource group, then select **OK**. 1. In **Region**, select **West Europe**, or a region near you. 1. In **Name**, type **myID**. :::column-end::: App Service can either use a default managed identity or a user-assigned managed 1. Select **Create**. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-create-managed-identity-3.png" alt-text="A screenshot showing how to complete managed identity create in the creation wizard." lightbox="./media/tutorial-custom-container/azure-portal-create-managed-identity-3.png"::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-create-managed-identity-3.png" alt-text="A screenshot showing how to complete the managed identity." lightbox="./media/tutorial-custom-container/azure-portal-create-managed-identity-3.png"::: :::column-end::: :::row-end::: :::row::: App Service can either use a default managed identity or a user-assigned managed ### [Azure CLI](#tab/azure-cli) -1. Create a container registry with the [`az acr create`](/cli/azure/acr#az-acr-create) command and replace `<registry-name>` with a unique name for your registry. The name must contain only letters and numbers, and must be unique across all of Azure. +1. Create a container registry by using the following [`az acr create`](/cli/azure/acr#az-acr-create) command. Replace `<registry-name>` with a unique name for your registry. The name must contain only letters and numbers, and must be unique across all of Azure. ```azurecli-interactive az acr create --name <registry-name> --resource-group msdocs-custom-container-tutorial --sku Basic --admin-enabled true ``` - The `--admin-enabled` parameter lets you push images to the registry using a set of administrative credentials. + The `--admin-enabled` parameter lets you push images to the registry using administrative credentials. -1. Retrieve the administrative credentials by running the [`az acr show`](/cli/azure/acr#az-acr-show) command: +1. Retrieve the administrative credentials by running the [`az credential acr show`](/cli/azure/acr/credential#az-acr-credential-show) command: ```azurecli-interactive az acr credential show --resource-group msdocs-custom-container-tutorial --name <registry-name> App Service can either use a default managed identity or a user-assigned managed :::row-end::: :::row::: :::column span="2":::- **II.B.** In the create wizard: + **II.B.** In the creation wizard: 1. In **Subscription**, select the subscription you used earlier. 1. In **Resource group**, select *msdocs-custom-container-tutorial*. 1. In **Registry name**, type a unique name for your container registry. App Service can either use a default managed identity or a user-assigned managed **II.E.** In the left navigation menu: 1. Select **Access keys**. 1. In **Admin user**, select **Enabled**.- 1. Copy the values of **Login server**, **Username**, and **password**. You'll use them in the next step to sign into the registry and push a docker image. + 1. Copy the values for **Login server**, **Username**, and **password**. You'll use them in the next step to sign into the registry and push a docker image. :::column-end::: :::column::: :::image type="content" source="./media/tutorial-custom-container/azure-portal-create-container-registry-5.png" alt-text="A screenshot showing how to enable administrative credentials for a container registry." lightbox="./media/tutorial-custom-container/azure-portal-create-container-registry-5.png"::: In this section, you push the image to Azure Container Registry, which will be u docker login <registry-name>.azurecr.io --username <registry-username> ``` - Replace `<registry-name>` and `<registry-username>` with values from the previous steps. When prompted, type in one of the passwords from the previous step. + Replace `<registry-name>` and `<registry-username>` with values from the previous steps. When prompted, type in one of the passwords from the previous section. You use the same registry name in all the remaining steps of this section. The managed identity you created doesn't have authorization to pull from the con az role assignment create --assignee $principalId --scope $registryId --role "AcrPull" ``` - For more information about these permissions, see [What is Azure role-based access control](../role-based-access-control/overview.md). + For more information about these permissions, see [What is Azure role-based access control?](../role-based-access-control/overview.md). ### [Azure portal](#tab/azure-portal) :::row::: :::column span="2"::: **IV.A.** Back in the management page for the container registry:- 1. In the left navigation menu, select **Access control**. + 1. In the left navigation menu, select **Access control (IAM)**. 1. Select **Add role assignment**. :::column-end::: :::column::: The managed identity you created doesn't have authorization to pull from the con :::row-end::: :::row::: :::column span="2":::- **IV.B.** Select **AcrPull** in the list. + **IV.B.** Select **AcrPull** in the list of roles. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-grant-identity-to-registry-2.png" alt-text="A screenshot showing how to enable pull permission on container registry." lightbox="./media/tutorial-custom-container/azure-portal-grant-identity-to-registry-2.png"::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-grant-identity-to-registry-2.png" alt-text="A screenshot showing how to enable pull permission on the container registry." lightbox="./media/tutorial-custom-container/azure-portal-grant-identity-to-registry-2.png"::: :::column-end::: :::row-end::: :::row::: :::column span="2":::- **IV.C.**: + **IV.C.** 1. Select the **Members** tab. 1. Under **Assign access to**, select **Managed identity**. 1. Under **Members**, select **Select members**. The managed identity you created doesn't have authorization to pull from the con az appservice plan create --name myAppServicePlan --resource-group msdocs-custom-container-tutorial --is-linux ``` - 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](https://azure.microsoft.com/pricing/details/app-service/linux/) that is free for the first month. You can control the tier with the `--sku` parameter. + 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](https://azure.microsoft.com/pricing/details/app-service/linux/) that's free for the first month. You can specify the tier by using the `--sku` parameter. 1. Create the web app with the [`az webapp create`](/cli/azure/webapp#az-webapp-create) command: The managed identity you created doesn't have authorization to pull from the con az webapp create --resource-group msdocs-custom-container-tutorial --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. + Replace `<app-name>` with a name for the web app. The name must be unique across all of Azure. Also replace `<registry-name>` with the name of your registry from the previous section. > [!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 msdocs-custom-container-tutorial`. 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. The managed identity you created doesn't have authorization to pull from the con :::row-end::: :::row::: :::column span="2":::- **V.D.** Back in the Create Web App wizard: + **V.D.** Back in the app creation wizard: 1. Select the **Docker** tab. 1. In **Image Source**, select **Azure Container Registry**. 1. In **Registry**, select the container registry you created earlier. The managed identity you created doesn't have authorization to pull from the con 1. In **Tag**, select **latest**. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-create-app-service-4.png" alt-text="A screenshot showing how to configure docker settings in the creation wizard." lightbox="./media/tutorial-custom-container/azure-portal-create-app-service-4.png"::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-create-app-service-4.png" alt-text="A screenshot showing how to configure Docker settings in the creation wizard." lightbox="./media/tutorial-custom-container/azure-portal-create-app-service-4.png"::: :::column-end::: :::row-end::: :::row::: The managed identity you created doesn't have authorization to pull from the con In this step, you configure the web app as follows: -- The sample container is listening on port 8000 for web requests, and you configure the app to send requests to port 8000. +- Configure the app to send requests to port 8000. The sample container is listening on port 8000 for web requests. - Tell your app to use the managed identity to pull images from your container registry.-- Configure continuous deployment from the container registry (or, every image push to the registry will trigger your app to pull the new image). This part isn't needed for your web app to pull from your container registry, but it can let your web app know when a new image is pushed to the registry. Without it, you must manually trigger an image pull by restarting the web app.+- Configure continuous deployment from the container registry (every image push to the registry will trigger your app to pull the new image). This part isn't needed for your web app to pull from your container registry, but it can let your web app know when a new image is pushed to the registry. Without it, you must manually trigger an image pull by restarting the web app. ### [Azure CLI](#tab/azure-cli) In this step, you configure the web app as follows: 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](https://github.com/Azure-Samples/docker-django-webapp-linux). - 1. Enable the user-assigned managed identity in the web app with the [`az webapp identity assign`](/cli/azure/webapp/identity#az-webapp-identity-assign) command: ```azurecli-interactive In this step, you configure the web app as follows: az acr webhook create --name appserviceCD --registry <registry-name> --uri $cicdUrl --actions push --scope appsvc-tutorial-custom-image:latest ``` -1. To test if your webhook is configured properly, ping the webhook, and see if you get a 200 OK response. +1. To test if your webhook is configured properly, ping the webhook and see if you get a 200 OK response. ```azurecli-interactive eventId=$(az acr webhook ping --name appserviceCD --registry <registry-name> --query id --output tsv) In this step, you configure the web app as follows: > [!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. + > If you're streaming the container log, you should see a `Starting container for site` message after the webhook ping because the webhook triggers the app to restart. ### [Azure portal](#tab/azure-portal) :::row::: :::column span="2":::- **VI.A.** In your web app's management page, select **Configuration**. + **VI.A.** On your web app's management page, select **Configuration**. :::column-end::: :::column::: :::image type="content" source="./media/tutorial-custom-container/azure-portal-configure-app-service-1.png" alt-text="A screenshot showing how to open the Configuration page." lightbox="./media/tutorial-custom-container/azure-portal-configure-app-service-1.png"::: In this step, you configure the web app as follows: :::row-end::: :::row::: :::column span="2":::- **VI.B.** In the Configuration page: + **VI.B.** On the Configuration page: 1. Select **New application setting**.- 1. In **Name**, type *WEBSITES_PORT*. - 1. In **Value**, type *8000*. + 1. In **Name**, type **WEBSITES_PORT**. + 1. In **Value**, type **8000**. 1. Select **OK**. 1. Select **Save** in the top menu, then select **Continue**. The `WEBSITES_PORT` setting specifies the container port to forward web requests to. For more information, see [custom container app settings](reference-app-settings.md#custom-containers). In this step, you configure the web app as follows: :::row-end::: :::row::: :::column span="2":::- **VI.C.** In the left navigation menu, select **Identity**. Then do the following in the Identity page: + **VI.C.** In the left navigation menu, select **Identity**. Then do the following on the Identity page: 1. Select the **User assigned** tab. 1. Select **Add**. :::column-end::: In this step, you configure the web app as follows: :::row-end::: :::row::: :::column span="2":::- **VI.E.** In the left navigation menu, select **Deployment Center**. Then do the following in the Deployment Center page: + **VI.E.** In the left navigation menu, select **Deployment Center**. Then do the following on the Deployment Center page: 1. In **Authentication**, select **Managed Identity**. 1. In **Identity**, select **myID**. 1. In **Continuous deployment**, select **On**. In this step, you configure the web app as follows: When you turn on continuous deployment to a container registry, a webhook is automatically added to the registry for your web app. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-configure-app-service-5.png" alt-text="A screenshot showing a user-assigned managed identity selected for registry authentication and continuous deployment enabled." lightbox="./media/tutorial-custom-container/azure-portal-configure-app-service-5.png"::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-configure-app-service-5.png" alt-text="A screenshot showing a user-assigned managed identity selected for registry authentication. Continuous deployment is enabled." lightbox="./media/tutorial-custom-container/azure-portal-configure-app-service-5.png"::: :::column-end::: :::row-end::: :::row::: :::column span="2":::- **VI.F.** In the Deployment Center page, select the **Logs** tab. Here, you can see log messages for pulling the image and starting the container. Later, you'll learn how to see console message generated from within the container. + **VI.F.** On the Deployment Center page, select the **Logs** tab. Here, you can see log messages for pulling the image and starting the container. Later, you'll learn how to see generated console messages from within the container. :::column-end::: :::column::: :::image type="content" source="./media/tutorial-custom-container/azure-portal-configure-app-service-6.png" alt-text="A screenshot showing log messages for pulling an image and starting the container." lightbox="./media/tutorial-custom-container/azure-portal-configure-app-service-6.png"::: In this step, you configure the web app as follows: ### [Azure CLI](#tab/azure-cli) -To test the app, browse to `https://<app-name>.azurewebsites.net`, replacing `<app-name>` with the name of your web app. +To test the app, browse to `https://<app-name>.azurewebsites.net`. Replace `<app-name>` with the name of your web app. ### [Azure portal](#tab/azure-portal) :::row::: :::column span="2":::- **VII.A.** In the App Service page: + **VII.A.** On the App Service page: 1. In the left navigation menu, select **Overview**. 1. In **URL**, select the link. :::column-end::: To test the app, browse to `https://<app-name>.azurewebsites.net`, replacing `<a -- -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. +The first time you attempt to access the app, 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. ## VIII. Access diagnostic logs While you're waiting for the App Service to pull in the image, it's helpful to s You can also inspect the log files from the browser at `https://<app-name>.scm.azurewebsites.net/api/logs/docker`. -1. To stop log streaming at any time, type `Ctrl+C`. +1. To stop log streaming at any time, select **Ctrl+C**. ### [Azure portal](#tab/azure-portal) -In the Deployment Center page, you can already see the log messages for pulling and starting the container. In this step, you can enable logging of the console output from within the container. +On the Deployment Center page, you can already see the log messages for pulling and starting the container. In this step, you enable logging of the console output from within the container. :::row::: :::column span="2":::- **VIII.A.** In the App Service page: + **VIII.A.** On the App Service page: 1. In the left navigation menu, select **App Service logs**. 1. In **Application logging**, select **File System**. 1. Select **Save**. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-stream-diagnostic-logs-1.png" alt-text="A screenshot showing how to enable diagnostic logging for custom container." lightbox="./media/tutorial-custom-container/azure-portal-stream-diagnostic-logs-1.png"::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-stream-diagnostic-logs-1.png" alt-text="A screenshot showing how to enable diagnostic logging for the custom container." lightbox="./media/tutorial-custom-container/azure-portal-stream-diagnostic-logs-1.png"::: :::column-end::: :::row-end::: :::row::: In this section, you make a change to the web app code, rebuild the image, and t docker build --tag appsvc-tutorial-custom-image . ``` -1. Update the image's tag to latest: +1. Update the image's tag to `latest`: ```bash docker tag appsvc-tutorial-custom-image <registry-name>.azurecr.io/appsvc-tutorial-custom-image:latest In this section, you make a change to the web app code, rebuild the image, and t docker push <registry-name>.azurecr.io/appsvc-tutorial-custom-image:latest ``` -1. 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`. +1. When the image push is complete, the webhook notifies 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`. ## X. Connect to the container using SSH -SSH enables secure communication between a container and a client. To enable SSH connection to your container, your custom image must be configured for it. When the container is running, you can open an SSH connection. +SSH enables improved-security communication between a container and a client. To enable an SSH connection to your container, you must configure your custom image for it. When the container is running, you can open an SSH connection. ### Configure the container for SSH RUN apt-get update \ > [!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. +> `root:Docker!` should not be altered when you use SSH. SCM/KUDU will use your Azure portal credentials. Changing this value will result in an error when you use SSH. The *Dockerfile* also copies the *sshd_config* file to the */etc/ssh/* folder and exposes port 2222 on the container: Finally, the entry script, *init.sh*, starts the SSH server. service ssh start ``` -### Open SSH connection to container +### Open the SSH connection to the container ### [Azure CLI](#tab/azure-cli) service ssh start 1. When you sign in, you're redirected to an informational page for the web app. Select **SSH** at the top of the page to open the shell and use commands. - For example, you can examine the processes running within it using the `top` command. + For example, you can examine the processes running within the app by using the `top` command. ### [Azure portal](#tab/azure-portal) :::row::: :::column span="2":::- **X.A.** In the App Service page: + **X.A.** On the App Service page: 1. In the left navigation menu, select **SSH**. 1. Select **Go**. :::column-end::: service ssh start :::row-end::: :::row::: :::column span="2":::- **X.B.** The SSH session is opened in a new browser tab. Wait for the status bar at the bottom to show a green `SSH CONNECTION ESTABLISHED`. You can then run commands from within the container. Configuration changes made to your container aren't persisted across app restarts. + **X.B.** The SSH session is opened in a new browser tab. Wait for the status bar at the bottom to show a green `SSH CONNECTION ESTABLISHED message. You can then run commands from within the container. Configuration changes made to your container aren't persisted across app restarts. :::column-end::: :::column::: :::image type="content" source="./media/tutorial-custom-container/azure-portal-start-ssh-container-session-2.png" alt-text="A screenshot showing an SSH session with a custom container." lightbox="./media/tutorial-custom-container/azure-portal-start-ssh-container-session-2.png"::: az group delete --name msdocs-custom-container-tutorial :::row-end::: :::row::: :::column span="2":::- **XI.B.** In the resource group page, select **Delete resource group**. + **XI.B.** On the resource group page, select **Delete resource group**. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-delete-resource-group-2.png" alt-text="A screenshot showing the location of the Delete Resource Group button in the Azure portal." lightbox="./media/tutorial-custom-container/azure-portal-delete-resource-group-2.png"::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-delete-resource-group-2.png" alt-text="A screenshot showing the location of the Delete resource group button in the Azure portal." lightbox="./media/tutorial-custom-container/azure-portal-delete-resource-group-2.png"::: :::column-end::: :::row-end::: :::row::: az group delete --name msdocs-custom-container-tutorial 1. Select **Delete**. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-custom-container/azure-portal-delete-resource-group-3.png" alt-text="A screenshot of the confirmation dialog for deleting a resource group in the Azure portal." lightbox="./media/tutorial-custom-container/azure-portal-delete-resource-group-3.png":::: + :::image type="content" source="./media/tutorial-custom-container/azure-portal-delete-resource-group-3.png" alt-text="A screenshot of the confirmation dialog for deleting a resource group in the Azure portal." lightbox="./media/tutorial-custom-container/azure-portal-delete-resource-group-3.png"::: :::column-end::: :::row-end::: What you learned: > [!div class="checklist"] >-> - 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 +> - 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 by using SSH. ::: zone-end What you learned: > [!div class="checklist"] >-> - 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 +> - Push a custom Docker image to Azure Container Registry. +> - Deploy the custom image to App Service. +> - Configure environment variables. +> - Pull the image into App Service by using a managed identity. +> - Access diagnostic logs. +> - Enable CI/CD from Azure Container Registry to App Service. +> - Connect to the container by using SSH. ::: zone-end -In the next tutorial, you learn how to secure your app with a custom domain and certificate. +In the next tutorial, you learn how to provide security for your app with a custom domain and certificate. > [!div class="nextstepaction"]-> [Secure with custom domain and certificate](tutorial-secure-domain-certificate.md) +> [Provide security with custom domain and certificate](tutorial-secure-domain-certificate.md) Or, check out other resources: > [!div class="nextstepaction"]-> [Configure custom container](configure-custom-container.md) --> [!div class="nextstepaction"] -> [Configure sidecar](configure-custom-container.md) +> [Configure a custom container](configure-custom-container.md) ::: zone pivot="container-linux" > [!div class="nextstepaction"] |
app-service | Tutorial Dotnetcore Sqldb App | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/tutorial-dotnetcore-sqldb-app.md | Having issues? Check the [Troubleshooting section](#troubleshooting). ::: zone pivot="azure-portal" -## 1. Create App Service, database, and cache +## 2. Create App Service, database, and cache In this step, you create the Azure resources. The steps used in this tutorial create a set of secure-by-default resources that include App Service, Azure SQL Database, and Azure Cache. For the creation process, you'll specify: Sign in to the [Azure portal](https://portal.azure.com/) and follow these steps The creation wizard generated the connectivity string for you already as [.NET connection strings](configure-common.md#configure-connection-strings) and [app settings](configure-common.md#configure-app-settings). However, the security best practice is to keep secrets out of App Service completely. You'll move your secrets to key vault and change your app setting to [Key Vault references](app-service-key-vault-references.md) with the help of Service Connectors. +> [!TIP] +> To use passwordless authentication, see [How do I change the SQL Database connection to use a managed identity instead?](#how-do-i-change-the-sql-database-connection-to-use-a-managed-identity-instead) + :::row::: :::column span="2":::- **Step 1:** In the App Service page, + **Step 1:** In the App Service page: 1. In the left menu, select **Settings > Environment variables > Connection strings**. 1. Select **AZURE_SQL_CONNECTIONSTRING**. 1. In **Add/Edit connection string**, in the **Value** field, find the *Password=* part at the end of the string. The creation wizard generated the connectivity string for you already as [.NET c 1. In the App Service page, in the left menu, select **Settings > Service Connector**. There are already two connectors, which the app creation wizard created for you. 1. Select checkbox next to the SQL Database connector, then select **Edit**. 1. Select the **Authentication** tab.+ 1. In **Password**, paste the password you copied earlier. 1. Select **Store Secret in Key Vault**. 1. Under **Key Vault Connection**, select **Create new**. A **Create connection** dialog is opened on top of the edit dialog. The creation wizard generated the connectivity string for you already as [.NET c :::row-end::: :::row::: :::column span="2":::- **Step 8:** To verify that your changes: + **Step 8:** To verify your changes: 1. From the left menu, select **Environment variables > Connection strings** again. 1. Next to **AZURE_SQL_CONNECTIONSTRING**, select **Show value**. The value should be `@Microsoft.KeyValut(...)`, which means that it's a [key vault reference](app-service-key-vault-references.md) because the secret is now managed in the key vault. 1. To verify the Redis connection string, select the **App setting** tab. Next to **AZURE_REDIS_CONNECTIONSTRING**, select **Show value**. The value should be `@Microsoft.KeyValut(...)` too. The creation wizard generated the connectivity string for you already as [.NET c :::column-end::: :::row-end::: -## 3. Deploy sample code +## 4. Deploy sample code In this step, you configure GitHub deployment using GitHub Actions. It's just one of many ways to deploy to App Service, but also a great way to have continuous integration in your deployment process. By default, every `git push` to your GitHub repository kicks off the build and deploy action. In this step, you configure GitHub deployment using GitHub Actions. It's just on :::column-end::: :::row-end::: -## 4. Generate database schema +## 5. Generate database schema With the SQL Database protected by the virtual network, the easiest way to run [dotnet database migrations](/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli) is in an SSH session with the App Service container. In the SSH session, only changes to files in `/home` can persist beyond app rest Having issues? Check the [Troubleshooting section](#troubleshooting). -## 5. Browse to the app +## 6. Browse to the app :::row::: :::column span="2"::: Having issues? Check the [Troubleshooting section](#troubleshooting). > [!TIP] > The sample application implements the [cache-aside](/azure/architecture/patterns/cache-aside) pattern. When you visit a data view for the second time, or reload the same page after making data changes, **Processing time** in the webpage shows a much faster time because it's loading the data from the cache instead of the database. -## 6. Stream diagnostic logs +## 7. Stream diagnostic logs Azure App Service captures all messages logged to the console to assist you in diagnosing issues with your application. The sample app outputs console log messages in each of its endpoints to demonstrate this capability. Azure App Service captures all messages logged to the console to assist you in d :::column-end::: :::row-end::: -## 7. Clean up resources +## 8. Clean up resources When you're finished, you can delete all of the resources from your Azure subscription by deleting the resource group. The dev container already has the [Azure Developer CLI](/azure/developer/azure-d azd up ``` - The `azd up` command takes about 15 minutes to complete (the Redis cache take the most time). It also compiles and deploys your application code, but you'll modify your code later to work with App Service. While it's running, the command provides messages about the provisioning and deployment process, including a link to the deployment in Azure. When it finishes, the command also displays a link to the deploy application. + The `azd up` command takes about 15 minutes to complete (the Redis cache takes the most time). It also compiles and deploys your application code, but you'll modify your code later to work with App Service. While it's running, the command provides messages about the provisioning and deployment process, including a link to the deployment in Azure. When it finishes, the command also displays a link to the deploy application. This AZD template contains files (*azure.yaml* and the *infra* directory) that generate a secure-by-default architecture with the following Azure resources: Before you deploy these changes, you still need to generate a migration bundle. Having issues? Check the [Troubleshooting section](#troubleshooting). -## 4. Generate database schema +## 5. Generate database schema With the SQL Database protected by the virtual network, the easiest way to run database migrations is in an SSH session with the App Service container. However, the App Service Linux containers don't have the .NET SDK, so the easiest way to run database migrations is to upload a self-contained migrations bundle. |
app-service | Tutorial Java Spring Cosmosdb | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/tutorial-java-spring-cosmosdb.md | Sign in to the [Azure portal](https://portal.azure.com/) and follow these steps - **App Service**: Represents your app and runs in the App Service plan. - **Virtual network**: Integrated with the App Service app and isolates back-end network traffic. - **Azure Cosmos DB**: Accessible only from behind its private endpoint. A database is created for you on the database account.+ - **Private endpoints**: Access endpoints for the database server and the Redis cache in the virtual network. - **Private DNS zones**: Enable DNS resolution of the database server and the Redis cache in the virtual network. :::column-end::: :::column::: The creation wizard generated the connectivity string for you already as an [app :::row::: :::column span="2":::- **Step 1:** In the App Service page, + **Step 1:** In the App Service page: 1. In the left menu, select **Settings > Environment variables**. 1. Next to **AZURE_COSMOS_CONNECTIONSTRING**, select **Show value**. This connection string lets you connect to the Cosmos DB database secured behind a private endpoint. However, the secret is saved directly in the App Service app, which isn't the best. You'll change this. The creation wizard generated the connectivity string for you already as an [app :::row-end::: :::row::: :::column span="2":::- **Step 7:** To verify that you secured the secrets: + **Step 7:** To verify your changes: 1. From the left menu, select **Environment variables** again. 1. Make sure that the app setting **spring.data.mongodb.uri** exists. The default connector generated it for you, and your Spring Boot application already uses the variable. 1. Next to the app setting, select **Show value**. The value should be `@Microsoft.KeyValut(...)`, which means that it's a [key vault reference](app-service-key-vault-references.md) because the secret is now managed in the key vault. Like the Tomcat convention, if you want to deploy to the root context of Tomcat, :::column span="2"::: **Step 5 (Option 1: with GitHub Copilot):** 1. Start a new chat session by selecting the **Chat** view, then selecting **+**.- 1. Ask, "*@workspace why do i get the error in GitHub actions: The string 'java21' is not valid SemVer notation for a Java version.*" Copilot might give you an explanation and even give you the link to the workflow file that you need to fix. + 1. Ask, "*@workspace Why do I get the error in GitHub actions: The string 'java21' is not valid SemVer notation for a Java version.*" Copilot might give you an explanation and even give you the link to the workflow file that you need to fix. 1. Open *.github/workflows/starter-no-infra_msdocs-spring-cosmosdb-123.yaml* in the explorer and make the suggested fix. GitHub Copilot doesn't give you the same response every time, you might need to ask more questions to fine-tune its response. For tips, see [What can I do with GitHub Copilot in my codespace?](#what-can-i-do-with-github-copilot-in-my-codespace). :::column-end::: The dev container already has the [Azure Developer CLI](/azure/developer/azure-d azd up ``` - The `azd up` command takes about 15 minutes to complete (the Redis cache take the most time). It also compiles and deploys your application code, but you'll modify your code later to work with App Service. While it's running, the command provides messages about the provisioning and deployment process, including a link to the deployment in Azure. When it finishes, the command also displays a link to the deploy application. + The `azd up` command takes about 15 minutes to complete (the Redis cache takes the most time). It also compiles and deploys your application code, but you'll modify your code later to work with App Service. While it's running, the command provides messages about the provisioning and deployment process, including a link to the deployment in Azure. When it finishes, the command also displays a link to the deploy application. This AZD template contains files (*azure.yaml* and the *infra* directory) that generate a secure-by-default architecture with the following Azure resources: The dev container already has the [Azure Developer CLI](/azure/developer/azure-d - **Azure Cosmos DB account with MongoDB API**: Accessible only from behind its private endpoint. A database is created for you on the server. - **Azure Cache for Redis**: Accessible only from within the virtual network. - **Key vault**: Accessible only from behind its private endpoint. Used to manage secrets for the App Service app.+ - **Private endpoints**: Access endpoints for the key vault, the database server, and the Redis cache in the virtual network. - **Private DNS zones**: Enable DNS resolution of the Cosmos DB database, the Redis cache, and the key vault in the virtual network. - **Log Analytics workspace**: Acts as the target container for your app to ship its logs, where you can also query the logs. |
app-service | Tutorial Java Tomcat Mysql App | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/app-service/tutorial-java-tomcat-mysql-app.md | Having issues? Check the [Troubleshooting section](#troubleshooting). First, you create the Azure resources. The steps used in this tutorial create a set of secure-by-default resources that include App Service and Azure Database for MySQL. For the creation process, you specify: -* The **Name** for the web app. It's the name used as part of the DNS name for your app in the form of `https://<app-name>.azurewebsites.net`. +* The **Name** for the web app. It's used as part of the DNS name for your app in the form of `https://<app-name>-<hash>.<region>.azurewebsites.net`. * The **Region** to run the app physically in the world. It's also used as part of the DNS name for your app. * The **Runtime stack** for the app. It's where you select the version of Java to use for your app. * The **Hosting plan** for the app. It's the pricing tier that includes the set of features and scaling capacity for your app. Sign in to the [Azure portal](https://portal.azure.com/) and follow these steps - **App Service plan**: Defines the compute resources for App Service. A Linux plan in the *Basic* tier is created. - **App Service**: Represents your app and runs in the App Service plan. - **Virtual network**: Integrated with the App Service app and isolates back-end network traffic.- - **Azure Database for MySQL flexible server**: Accessible only from behind its private endpoint. A database and a user are created for you on the server. - - **Private DNS zones**: Enable DNS resolution of the database server and the Redis cache in the virtual network. + - **Azure Database for MySQL flexible server**: Accessible only from the virtual network. A database and a user are created for you on the server. + - **Private DNS zones**: Enable DNS resolution of the database server in the virtual network. + <!-- Author note: Azure Database for MySQL's networking is not the same as other databases. It integrates with a private DNS zone, not with a private endpoint. --> :::column-end::: :::column::: :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-create-app-mysql-3.png" alt-text="A screenshot showing the deployment process completed." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-create-app-mysql-3.png"::: Sign in to the [Azure portal](https://portal.azure.com/) and follow these steps Having issues? Check the [Troubleshooting section](#troubleshooting). -## 3. Verify connection settings +## 3. Secure connection secrets -The creation wizard generated the connectivity string for you already as [app settings](configure-common.md#configure-app-settings). In this step, you learn where to find the app settings, and how you can create your own. --App settings are one way to keep connection secrets out of your code repository. When you're ready to move your secrets to a more secure location, you can use [Key Vault references](app-service-key-vault-references.md) instead. +The creation wizard generated the connectivity string for you already as an [app setting](configure-common.md#configure-app-settings). However, the security best practice is to keep secrets out of App Service completely. You'll move your secrets to key vault and change your app setting to a [Key Vault reference](app-service-key-vault-references.md) with the help of Service Connectors. :::row::: :::column span="2":::- **Step 1:** In the App Service page, in the left menu, select **Configuration**. + **Step 1:** In the App Service page: + 1. In the left menu, select **Settings > Environment variables**. + 1. Select **AZURE_MYSQL_CONNECTIONSTRING**. It contains a JDBC connection string. If you add an app setting that contains a valid Oracle, SQL Server, PostgreSQL, or MySQL connection string, App Service injects it as a Java Naming and Directory Interface (JNDI) data source in the Tomcat server's *context.xml* file. + 1. In **Add/Edit application setting**, in the **Value** field, find the *password=* part at the end of the string. + 1. Copy the password string after *Password=* for use later. + This app setting lets you connect to the MySQL database secured behind a private endpoint. However, the secret is saved directly in the App Service app, which isn't the best. You'll change this. + :::column-end::: + :::column::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-1.png" alt-text="A screenshot showing how to see the value of an app setting." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-1.png"::: + :::column-end::: + :::column span="2"::: + **Step 2:** Create a key vault for secure management of secrets. + 1. In the top search bar, type "*key vault*", then select **Marketplace** > **Key Vault**. + 1. In **Resource Group**, select **msdocs-tomcat-mysql-tutorial**. + 1. In **Key vault name**, type a name that consists of only letters and numbers. + 1. In **Region**, set it to the sample location as the resource group. + :::column-end::: + :::column::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-2.png" alt-text="A screenshot showing how to create a key vault." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-2.png"::: + :::column-end::: + :::column span="2"::: + **Step 3:** + 1. Select the **Networking** tab. + 1. Unselect **Enable public access**. + 1. Select **Create a private endpoint**. + 1. In **Resource Group**, select **msdocs-tomcat-mysql-tutorial**. + 1. In **Key vault name**, type a name that consists of only letters and numbers. + 1. In **Region**, set it to the sample location as the resource group. + 1. In the dialog, in **Location**, select the same location as your App Service app. + 1. In **Resource Group**, select **msdocs-tomcat-mysql-tutorial**. + 1. In **Name**, type **msdocs-tomcat-mysql-XYZVaultEndpoint**. + 1. In **Virtual network**, select **msdocs-tomcat-mysql-XYZVnet**. + 1. In **Subnet**, **msdocs-tomcat-mysql-XYZSubnet**. + 1. Select **OK**. + 1. Select **Review + create**, then select **Create**. Wait for the key vault deployment to finish. You should see "Your deployment is complete." + :::column-end::: + :::column::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-3.png" alt-text="A screenshot showing how to secure a key vault with a private endpoint." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-3.png"::: + :::column-end::: + :::column span="2"::: + **Step 4:** + 1. In the top search bar, type *msdocs-tomcat-mysql*, then the App Service resource called **msdocs-tomcat-mysql-XYZ**. + 1. In the App Service page, in the left menu, select **Settings > Service Connector**. There's already a connector, which the app creation wizard created for you. + 1. Select checkbox next to the connector, then select **Edit**. + 1. In the **Basics** tab, set **Client type** to **Java**. + 1. Select the **Authentication** tab. + 1. In **Password**, paste the password you copied earlier. + 1. Select **Store Secret in Key Vault**. + 1. Under **Key Vault Connection**, select **Create new**. + A **Create connection** dialog is opened on top of the edit dialog. + :::column-end::: + :::column::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-4.png" alt-text="A screenshot showing how to edit a service connector with a key vault connection." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-4.png"::: + :::column-end::: + :::column span="2"::: + **Step 5:** In the **Create connection** dialog for the Key Vault connection: + 1. In **Key Vault**, select the key vault you created earlier. + 1. Select **Review + Create**. You should see that **System assigned managed identity** is set to **Selected**. + 1. When validation completes, select **Create**. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-get-connection-string-1.png" alt-text="A screenshot showing how to open the configuration page in App Service." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-get-connection-string-1.png"::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-5.png" alt-text="A screenshot showing how to configure a key vault service connector." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-5.png"::: :::column-end::: :::row-end::: :::row::: :::column span="2":::- **Step 2:** - 1. In the **Application settings** tab of the **Configuration** page, find the app setting `AZURE_MYSQL_CONNECTIONSTRING`. The creation wizard created it for you. - 1. If you want, you can select the **Edit** button to the right of each setting and see or copy its value, or select Add to add a variable to inject into your Tomcat container. If you add an app setting that contains a valid Oracle, SQL Server, PostgreSQL, or MySQL connection string, App Service adds it as a Java Naming and Directory Interface (JNDI) data source in the Tomcat server's *context.xml* file. + **Step 6:** You're back in the edit dialog for **defaultConnector**. + 1. In the **Authentication** tab, wait for the key vault connector to be created. When it's finished, the **Key Vault Connection** dropdown automatically selects it. + 1. Select **Next: Networking**. + 1. Select **Save**. Wait until the **Update succeeded** notification appears. :::column-end::: :::column:::- :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-get-connection-string-2.png" alt-text="A screenshot showing how to see the autogenerated connection string." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-get-connection-string-2.png"::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-6.png" alt-text="A screenshot showing the key vault connection selected in the defaultConnector." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-6.png"::: + :::column-end::: + :::column span="2"::: + **Step 7:** To verify your changes: + 1. From the left menu, select **Environment variables > Connection strings** again. + 1. Next to **AZURE_MYSQL_CONNECTIONSTRING**, select **Show value**. The value should be `@Microsoft.KeyValut(...)`, which means that it's a [key vault reference](app-service-key-vault-references.md) because the secret is now managed in the key vault. + :::column-end::: + :::column::: + :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-7.png" alt-text="A screenshot showing how to see the value of the MySQL environment variable in Azure." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-secure-connection-secrets-7.png"::: :::column-end::: :::row-end::: Having issues? Check the [Troubleshooting section](#troubleshooting). ## 4. Confirm JNDI data source -In this step, you use the SSH connection to the app container to verify the JNDI data source in the Tomcat server. In the process, you learn how to access the SSH shell for the Tomcat container. +If you add an app setting that contains a valid JDBC connection string for Oracle, SQL Server, PostgreSQL, or MySQL, App Service adds a Java Naming and Directory Interface (JNDI) data source for it in the Tomcat server's *context.xml* file. In this step, you use the SSH connection to the app container to verify the JNDI data source. In the process, you learn how to access the SSH shell for the Tomcat container. :::row::: :::column span="2":::- **Step 1:** Back in the App Service page, + **Step 1:** Back in the App Service page: 1. In the left menu, select **SSH**. 1. Select **Go**. :::column-end::: Having issues? Check the [Troubleshooting section](#troubleshooting). :::column span="2"::: **Step 1:** In the App Service page: 1. From the left menu, select **Overview**.- 1. Select the URL of your app. You can also navigate directly to `https://<app-name>.azurewebsites.net`. + 1. Select the URL of your app. :::column-end::: :::column::: :::image type="content" source="./media/tutorial-java-tomcat-mysql-app/azure-portal-browse-app-1.png" alt-text="A screenshot showing how to launch an App Service from the Azure portal." lightbox="./media/tutorial-java-tomcat-mysql-app/azure-portal-browse-app-1.png"::: The dev container already has the [Azure Developer CLI](/azure/developer/azure-d ||| |The current directory is not empty. Would you like to initialize a project here in '\<your-directory>'? | **Y** | |What would you like to do with these files? | **Keep my existing files unchanged** |- |Enter a new environment name | Type a unique name. The AZD template uses this name as part of the DNS name of your web app in Azure (`<app-name>.azurewebsites.net`). Alphanumeric characters and hyphens are allowed. | + |Enter a new environment name | Type a unique name. The AZD template uses this name as part of the DNS name of your web app in Azure (`<app-name>-<hash>.azurewebsites.net`). Alphanumeric characters and hyphens are allowed. | 1. Sign into Azure by running the `azd auth login` command and following the prompt: The dev container already has the [Azure Developer CLI](/azure/developer/azure-d azd up ``` - The `azd up` command takes about 15 minutes to complete (the Redis cache take the most time). It also compiles and deploys your application code, but you'll modify your code later to work with App Service. While it's running, the command provides messages about the provisioning and deployment process, including a link to the deployment in Azure. When it finishes, the command also displays a link to the deploy application. + The `azd up` command takes about 15 minutes to complete (the Redis cache takes the most time). It also compiles and deploys your application code, but you'll modify your code later to work with App Service. While it's running, the command provides messages about the provisioning and deployment process, including a link to the deployment in Azure. When it finishes, the command also displays a link to the deploy application. This AZD template contains files (*azure.yaml* and the *infra* directory) that generate a secure-by-default architecture with the following Azure resources: The dev container already has the [Azure Developer CLI](/azure/developer/azure-d - **App Service plan**: Defines the compute resources for App Service. A Linux plan in the *B1* tier is created. - **App Service**: Represents your app and runs in the App Service plan. - **Virtual network**: Integrated with the App Service app and isolates back-end network traffic.- - **Azure Database for MySQL flexible server**: Accessible only from behind its private endpoint. A database is created for you on the server. + - **Azure Database for MySQL flexible server**: Accessible only from the virtual network through the DNS zone integration. A database is created for you on the server. - **Azure Cache for Redis**: Accessible only from within the virtual network.- - **Private DNS zones**: Enable DNS resolution of the database server and the Redis cache in the virtual network. + - **Private endpoints**: Access endpoints for the key vault and the Redis cache in the virtual network. + - **Private DNS zones**: Enable DNS resolution of the key vault, the database server, and the Redis cache in the virtual network. - **Log Analytics workspace**: Acts as the target container for your app to ship its logs, where you can also query the logs. - **Key vault**: Used to keep your database password the same when you redeploy with AZD. Having issues? Check the [Troubleshooting section](#troubleshooting). The AZD template you use generated the connectivity variables for you already as [app settings](configure-common.md#configure-app-settings) and outputs the them to the terminal for your convenience. App settings are one way to keep connection secrets out of your code repository. -1. In the AZD output, find the app setting `AZURE_MYSQL_CONNECTIONSTRING`. To keep secrets safe, only the setting names are displayed. They look like this in the AZD output: +1. In the AZD output, find the app setting `AZURE_MYSQL_CONNECTIONSTRING`. Only the setting names are displayed. They look like this in the AZD output: <pre> App Service app has the following connection strings:- - AZURE_MYSQL_CONNECTIONSTRING - AZURE_REDIS_CONNECTIONSTRING+ - AZURE_KEYVAULT_RESOURCEENDPOINT + - AZURE_KEYVAULT_SCOPE </pre> `AZURE_MYSQL_CONNECTIONSTRING` contains the connection string to the MySQL database in Azure. You need to use it in your code later. In this step, you use the SSH connection to the app container to verify the JNDI 1. In the AZD output, find the URL for the SSH session and navigate to it in the browser. It looks like this in the output: <pre>- Open SSH session to App Service container at: https://<app-name>.scm.azurewebsites.net/webssh/host + Open SSH session to App Service container at: https://<app-name>-<hash>.scm.azurewebsites.net/webssh/host </pre> 1. In the SSH terminal, run `cat /usr/local/tomcat/conf/context.xml`. You should see that a JNDI resource called `jdbc/AZURE_MYSQL_CONNECTIONSTRING_DS` was added. You'll use this data source later. Having issues? Check the [Troubleshooting section](#troubleshooting). Deploying services (azd deploy) (Γ£ô) Done: Deploying service web- - Endpoint: https://<app-name>.azurewebsites.net/ + - Endpoint: https://<app-name>-<hash>.azurewebsites.net/ </pre> 2. Add a few tasks to the list. |
automation | Manage Change Tracking Monitoring Agent | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/change-tracking/manage-change-tracking-monitoring-agent.md | description: This article tells how to use change tracking and inventory to trac Previously updated : 07/17/2023- Last updated : 09/19/2024+ |
automation | Manage Change Tracking | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/change-tracking/manage-change-tracking.md | Title: Manage Change Tracking and Inventory in Azure Automation description: This article tells how to use Change Tracking and Inventory to track software and Microsoft service changes in your environment. Previously updated : 07/22/2024- Last updated : 09/15/2024+ |
automation | Manage Office 365 | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/manage-office-365.md | Title: Manage Office 365 services using Azure Automation description: This article tells how to use Azure Automation to manage Office 365 subscription services. Previously updated : 09/13/2024- Last updated : 09/15/2024+ |
automation | Manage Sql Server In Automation | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/manage-sql-server-in-automation.md | Title: Manage databases in Azure SQL databases using Azure Automation description: This article explains on how to use Azure SQL server database using a system assigned managed identity in Azure Automation. Previously updated : 09/23/2023- Last updated : 09/15/2024+ # Manage databases in Azure SQL database using Azure Automation |
automation | Quickstart Cli Support Powershell Runbook Runtime Environment | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/quickstart-cli-support-powershell-runbook-runtime-environment.md | Title: Add support for Azure CLI in PowerShell 7.2 runbooks in Runtime environme description: This article shows how to add support for Azure CLI in PowerShell 7.2 runbooks in Runtime environment. Previously updated : 01/17/2024- Last updated : 09/15/2024+ |
automation | Quickstart Create Automation Account Template | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/quickstart-create-automation-account-template.md | Title: Create an Azure Automation account using a Resource Manager template description: This article shows how to create an Automation account by using the Azure Resource Manager template. Previously updated : 04/12/2023- Last updated : 09/15/2024+ |
automation | Quickstart Update Runbook In Runtime Environment | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/quickstart-update-runbook-in-runtime-environment.md | Title: Update PowerShell runbook in Azure Runtime environment description: This article shows how to update a runbook from PowerShell 5.1 to PowerShell 7.2 in Runtime environment. Previously updated : 01/16/2024- Last updated : 09/15/2024+ |
automation | Variables | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/shared-resources/variables.md | Title: Manage variables in Azure Automation description: This article tells how to work with variables in runbooks and DSC configurations. Previously updated : 03/28/2021- Last updated : 09/15/2024+ |
automation | Configure Alerts | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/configure-alerts.md | Title: How to create alerts for Azure Automation Update Management description: This article tells how to configure Azure alerts to notify about the status of update assessments or deployments. Previously updated : 08/30/2024- Last updated : 09/15/2024+ # How to create alerts for Update Management Alerts in Azure proactively notify you of results from runbook jobs, service health issues, or other scenarios related to your Automation account. Azure Automation does not include pre-configured alert rules, but you can create your own based on data that it generates. This article provides guidance on creating alert rules using the metrics included with Update Management |
automation | Configure Groups | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/configure-groups.md | Title: Use dynamic groups with Azure Automation Update Management description: This article tells how to use dynamic groups with Azure Automation Update Management. Previously updated : 09/10/2024 Last updated : 09/15/2024 # Use dynamic groups with Update Management + Update Management allows you to target a dynamic group of Azure or non-Azure VMs for update deployments. Using a dynamic group keeps you from having to edit your deployment to update machines. > [!NOTE] |
automation | Configure Wuagent | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/configure-wuagent.md | Title: Configure Windows Update settings for Azure Automation Update Management description: This article tells how to configure Windows Update settings to work with Azure Automation Update Management. Previously updated : 07/15/2024- Last updated : 09/15/2024+ # Configure Windows Update settings for Azure Automation Update Management + Azure Automation Update Management relies on the [Windows Update client](/windows/deployment/update/windows-update-overview) to download and install Windows updates. There are specific settings that are used by the Windows Update client when connecting to Windows Server Update Services (WSUS) or Windows Update. Many of these settings can be managed with: - Local Group Policy Editor |
automation | Deploy Updates | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/deploy-updates.md | Title: How to create update deployments for Azure Automation Update Management description: This article describes how to schedule update deployments and review their status. Previously updated : 08/30/2024- Last updated : 09/15/2024+ |
automation | Enable From Automation Account | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/enable-from-automation-account.md | Title: Enable Azure Automation Update Management from Automation account description: This article tells how to enable Update Management from an Automation account. Previously updated : 09/10/2024 Last updated : 09/15/2024 |
automation | Enable From Portal | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/enable-from-portal.md | Title: Enable Azure Automation Update Management from the Azure portal description: This article tells how to enable Update Management from the Azure portal. Previously updated : 08/30/2024- Last updated : 09/15/2024+ # Enable Update Management from the Azure portal This article describes how you can enable the [Update Management](overview.md) feature for VMs by browsing the Azure portal. To enable Azure VMs at scale, you must enable an existing Azure VM using Update Management. |
automation | Enable From Runbook | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/enable-from-runbook.md | description: This article tells how to enable Update Management from a runbook. Previously updated : 09/10/2024 Last updated : 09/15/2024 # Enable Update Management from a runbook This article describes how you can use a runbook to enable the [Update Management](overview.md) feature for VMs in your environment. To enable Azure VMs at scale, you must enable an existing VM with Update Management. |
automation | Enable From Template | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/enable-from-template.md | description: This article tells how to use an Azure Resource Manager template to - Previously updated : 08/30/2024+ Last updated : 09/15/2024 # Enable Update Management using Azure Resource Manager template You can use an [Azure Resource Manager template](../../azure-resource-manager/templates/syntax.md) to enable the Azure Automation Update Management feature in your resource group. This article provides a sample template that automates the following: |
automation | Enable From Vm | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/enable-from-vm.md | Title: Enable Azure Automation Update Management for an Azure VM description: This article tells how to enable Update Management for an Azure VM. Previously updated : 09/10/2024 Last updated : 09/15/2024 |
automation | Manage Updates For Vm | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/manage-updates-for-vm.md | |
automation | Mecmintegration | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/mecmintegration.md | Title: Integrate Azure Automation Update Management with Microsoft Configuration description: This article tells how to configure Microsoft Configuration Manager with Update Management to deploy software updates to manager clients. Previously updated : 09/10/2024 Last updated : 09/15/2024 # Integrate Update Management with Microsoft Configuration Manager Customers who have invested in Microsoft Configuration Manager to manage PCs, servers, and mobile devices also rely on its strength and maturity in managing software updates as part of their software update management (SUM) cycle. |
automation | Operating System Requirements | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/operating-system-requirements.md | description: This article describes the supported Windows and Linux operating sy Previously updated : 09/10/2024 Last updated : 09/15/2024 |
automation | Overview | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/overview.md | description: This article provides an overview of the Update Management feature Previously updated : 09/10/2024 Last updated : 09/15/2024 -> - Azure Automation Update Management has retired on **31 August 2024**. Follow the guidelines for [migration to Azure Update Manager](../../update-manager/guidance-migration-automation-update-management-azure-update-manager.md). -> - Azure Log Analytics agent, also known as the Microsoft Monitoring Agent (MMA) has [retired in August 2024](https://azure.microsoft.com/updates/were-retiring-the-log-analytics-agent-in-azure-monitor-on-31-august-2024/). Azure Automation Update Management solution relies on this agent and may encounter issues once the agent is retired as it does not work with Azure Monitoring Agent (AMA). Therefore, if you are using the Azure Automation Update Management solution, we recommend that you move to Azure Update Manager for your software update needs. All the capabilities of Azure Automation Update management solution will be available on Azure Update Manager before the retirement date. Follow the [guidance](../../update-center/guidance-migration-automation-update-management-azure-update-manager.md) to move your machines and schedules from Automation Update Management to Azure Update Manager. +> Azure Log Analytics agent, also known as the Microsoft Monitoring Agent (MMA) has [retired in August 2024](https://azure.microsoft.com/updates/were-retiring-the-log-analytics-agent-in-azure-monitor-on-31-august-2024/). Azure Automation Update Management solution relies on this agent and may encounter issues once the agent is retired as it does not work with Azure Monitoring Agent (AMA). Therefore, if you are using the Azure Automation Update Management solution, we recommend that you move to Azure Update Manager for your software update needs. All the capabilities of Azure Automation Update management solution will be available on Azure Update Manager before the retirement date. You can use Update Management in Azure Automation to manage operating system updates for your Windows and Linux virtual machines in Azure, physical or VMs in on-premises environments, and in other cloud environments. You can quickly assess the status of available updates and manage the process of installing required updates for your machines reporting to Update Management. |
automation | Plan Deployment | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/plan-deployment.md | description: This article describes the considerations and decisions to be made Previously updated : 09/10/2024 Last updated : 09/15/2024 # Plan your Update Management deployment ## Step 1: Automation account |
automation | Pre Post Scripts | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/pre-post-scripts.md | Title: Manage pre-scripts and post-scripts in your Update Management deployment description: This article tells how to configure and manage pre-scripts and post-scripts for update deployments. Previously updated : 09/10/2024 Last updated : 09/15/2024 |
automation | Query Logs | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/query-logs.md | Title: Query Azure Automation Update Management logs description: This article tells how to query the logs for Update Management in your Log Analytics workspace. Previously updated : 09/10/2024 Last updated : 09/15/2024 # Query Update Management logs + In addition to the details that are provided during Update Management deployment, you can search the logs stored in your Log Analytics workspace. To search the logs from your Automation account, select **Update management** and open the Log Analytics workspace associated with your deployment. You can also customize the log queries or use them from different clients. See [Log Analytics search API documentation](/rest/api/loganalytics/). |
automation | Remove Feature | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/remove-feature.md | |
automation | Remove Vms | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/remove-vms.md | description: This article tells how to remove Azure and non-Azure machines manag - Previously updated : 08/30/2024+ Last updated : 09/15/2024 # Remove VMs from Update Management When you're finished managing updates on your Azure or non-Azure machines in your environment, you can stop managing them with the [Update Management](overview.md) feature. To stop managing them, you will edit the saved search query `MicrosoftDefaultComputerGroup` in your Log Analytics workspace that is linked to your Automation account. |
automation | Scope Configuration | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/scope-configuration.md | Title: Limit Azure Automation Update Management deployment scope description: This article tells how to use scope configurations to limit the scope of an Update Management deployment. Previously updated : 07/15/2024- Last updated : 09/15/2024+ # Limit Update Management deployment scope + This article describes how to work with scope configurations when using the [Update Management](overview.md) feature to deploy updates and patches to your machines. For more information, see [Targeting monitoring solutions in Azure Monitor (Preview)](/previous-versions/azure/azure-monitor/insights/solution-targeting). ## About scope configurations |
automation | View Update Assessments | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/automation/update-management/view-update-assessments.md | Title: View Azure Automation update assessments description: This article tells how to view update assessments for Update Management deployments. Previously updated : 08/30/2024- Last updated : 09/15/2024+ |
communication-services | Call Context | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/communication-services/how-tos/calling-sdk/call-context.md | Title: How to pass contextual data between calls description: Use Azure Communication Services SDKs to pass contextual data between calls.--++ Previously updated : 05/14/2024 Last updated : 09/13/2024 -# Passing Contextual Information +# Using the ACS calling SDK to pass contextual User-to-User Information (UUI) data between calls In this article, you learn how to pass along custom contextual information when routing calls with Azure Communication Services Calling SDKs. This capability allows users to pass metadata about the call, callee, or any other information that is relevant to their application or business logic. +The Azure Communication Services (ACS) WebJS SDK provides developers to include custom contextual data (included as a header on the calling object) when directing and routing calls from one person to another. This information, also known as User-to-User Information (UUI) data or call control UUI data, is a small piece of data inserted by an application initiating the call. The UUI data is opaque to end users making a call. + Contextual information supported includes both freeform custom headers and the standard User-to-User Information (UUI) SIP header. Also when you receive an inbound call, the custom headers and UUI are included in the incomingCall payload. All custom context data is opaque to Calling SDK or SIP protocols and its content is unrelated to any basic functions. +Developers can pass this context by using custom headers, which consist of optional key-value pairs. These pairs can be included in the 'AddParticipant' or 'Transfer' actions within the calling SDK. Once added, you can read the data payload as the call moves between endpoints. By efficiently looking up this metadata and associating it with the call, developers can avoid external database lookups and have the content information readily available within the call object. ++The custom call context can be transmitted to SIP endpoints using the SIP protocol. This transmission includes both the custom headers and the standard User-to-User Information (UUI) SIP header. When an inbound call is routed from your telephony network, the data from your Session Border Controller (SBC) in the custom headers and UUI is also included in the IncomingCall event payload. -## Prerequisites +ItΓÇÖs important to note that all custom context data remains transparent to the calling SDK and isn't related to any of the SDKΓÇÖs fundamental functions when used in SIP protocols. Here's a tutorial to assist you in adding custom context headers when using the WebJS SDK. -- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). -- A deployed Communication Services resource. [Create a Communication Services resource](../../quickstarts/create-communication-resource.md).-- A user access token to enable the calling client. For more information, see [Create and manage access tokens](../../quickstarts/identity/access-tokens.md).-- Optional: Complete the quickstart to [add voice calling to your application](../../quickstarts/voice-video-calling/getting-started-with-calling.md) +> [!IMPORTANT] +> To use the ability to pass User-to-User Information (UUI) data using the calling SDK you must use the calling WebJS SDK GA or public preview version `1.29.1` or later. [!INCLUDE [Passing Contextual Data - Client-side JavaScript](./includes/call-context/call-context-web.md)] |
communication-services | Send Email Smtp | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/communication-services/quickstarts/email/send-email-smtp/send-email-smtp.md | Title: How to use SMTP to send an email with Azure Communication Services. description: Learn about how to use SMTP to send emails to Email Communication Services.-+ Last updated 10/18/2023 |
communication-services | Smtp Authentication | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/communication-services/quickstarts/email/send-email-smtp/smtp-authentication.md | Title: How to create authentication credentials for sending emails using SMTP description: Learn about how to use a service principal to create authentication credentials for sending emails using SMTP.-+ Last updated 10/18/2023 In this quick start, you learn about how to use an Entra application to create t - An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). - An Azure Communication Email Resource created and ready with a provisioned domain [Get started with Creating Email Communication Resource](../create-email-communication-resource.md) - An active Azure Communication Services Resource connected with Email Domain and a Connection String. [Get started by Connecting Email Resource with a Communication Resource](../connect-email-communication-resource.md)-- An Entra application with access to the Azure Communication Services Resource. [Register an application with Microsoft Entra ID and create a service principal](/entra/identity-platform/howto-create-service-principal-portal#register-an-application-with-microsoft-entra-id-and-create-a-service-principal)-- A client secret for the Entra application with access to the Azure Communication Service Resource. [Create a new client secret](/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret)+- A Microsoft Entra application with access to the Azure Communication Services Resource. [Register an application with Microsoft Entra ID and create a service principal](/entra/identity-platform/howto-create-service-principal-portal#register-an-application-with-microsoft-entra-id-and-create-a-service-principal) +- A client secret for the Microsoft Entra application with access to the Azure Communication Service Resource. [Create a new client secret](/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret) ## Using a Microsoft Entra application with access to the Azure Communication Services Resource for SMTP -Application developers who build apps that send email using the SMTP protocol need to implement secure, modern authentication. Azure Communication Services does this by leveraging Entra application service principals. Combining the Azure Communication Services Resource and the Entra application service principal's information, the SMTP services undertakes authentication with Entra on the user's behalf to ensure a secure and seamless email transmission. +Application developers who build apps that send email using the SMTP protocol need to implement secure, modern authentication. Azure Communication Services does this by leveraging Microsoft Entra application service principals. Combining the Azure Communication Services Resource and the Microsoft Entra application service principal's information, the SMTP services undertakes authentication with Microsoft Entra on the user's behalf to ensure a secure and seamless email transmission. -### Creating a custom email role for the Entra application +### Creating a custom email role for the Microsoft Entra application -The Entra application must be assigned a role with both the **Microsoft.Communication/CommunicationServices/Read** and the **Microsoft.Communication/EmailServices/write** permissions on the Azure Communication Service Resource. This can be done either by using the **Contributor** role, or by creating a **custom role**. Follow these steps to create a custom role by cloning an existing role. +The Microsoft Entra application must be assigned a role with both the **Microsoft.Communication/CommunicationServices/Read**, **Microsoft.Communication/CommunicationServices/Write**, and the **Microsoft.Communication/EmailServices/write** permissions on the Azure Communication Service Resource. This can be done either by using the **Contributor** role, or by creating a **custom role**. Follow these steps to create a custom role by cloning an existing role. 1. In the portal, a custom role can be created by first navigating to the subscription, resource group, or Azure Communication Service Resource where you want the custom role to be assignable and then open **Access control (IAM)**. :::image type="content" source="../media/smtp-custom-role-iam.png" alt-text="Screenshot that shows Access control."::: The Entra application must be assigned a role with both the **Microsoft.Communic :::image type="content" source="../media/smtp-custom-role-basics.png" alt-text="Screenshot that shows creating a name for a new custom role."::: 1. Click the **Permissions** tab and click **Add permissions**. Search for **Microsoft.Communication** and select **Azure Communication Services** :::image type="content" source="../media/smtp-custom-role-permissions.png" alt-text="Screenshot that shows adding permissions for a new custom role.":::-1. Select the **Microsoft.Communication/CommunicationServices** **Read** and the **Microsoft.Communication/EmailServices** **Write*** permissions. Click **Add**. +1. Select the **Microsoft.Communication/CommunicationServices** **Read**, **Microsoft.Communication/CommunicationServices** **Write**, and the **Microsoft.Communication/EmailServices** **Write** permissions. Click **Add**. :::image type="content" source="../media/smtp-custom-role-add-permissions.png" alt-text="Screenshot that shows adding Azure Communication Services' permissions."::: 1. Review the permissions for the new role. Click **Review + create** and then **Create** on the next page. :::image type="content" source="../media/smtp-custom-role-review.png" alt-text="Screenshot that shows reviewing the new custom role."::: -When assigning the Entra application a role for the Azure Communication Services Resource, the new custom role will be available. For more information on creating custom roles, see [Create or update Azure custom roles using the Azure portal](../../../../role-based-access-control/custom-roles-portal.md) +When assigning the Microsoft Entra application a role for the Azure Communication Services Resource, the new custom role will be available. For more information on creating custom roles, see [Create or update Azure custom roles using the Azure portal](../../../../role-based-access-control/custom-roles-portal.md) -### Assigning the custom email role to the Entra application +### Assigning the custom email role to the Microsoft Entra application 1. In the portal, navigate to the subscription, resource group, or Azure Communication Service Resource where you want the custom role to be assignable and then open **Access control (IAM)**. :::image type="content" source="../media/smtp-custom-role-iam.png" alt-text="Screenshot that shows Access control."::: 1. Click **+Add** and then select **Add role assignment**. When assigning the Entra application a role for the Azure Communication Services :::image type="content" source="../media/email-smtp-select-custom-role.png" alt-text="Screenshot that shows selecting the custom role."::: 1. On the **Members** tab, choose **User, group, or service principal** and then click **+Select members**. :::image type="content" source="../media/email-smtp-select-members.png" alt-text="Screenshot that shows choosing select members.":::-1. Use the search box to find the **Entra** application that you'll use for authentication and select it. Then click **Select**. - :::image type="content" source="../media/email-smtp-select-entra.png" alt-text="Screenshot that shows selecting the Entra application."::: +1. Use the search box to find the **Microsoft Entra** application that you'll use for authentication and select it. Then click **Select**. + :::image type="content" source="../media/email-smtp-select-entra.png" alt-text="Screenshot that shows selecting the Microsoft Entra application."::: 1. After confirming the selection, click **Next**. :::image type="content" source="../media/email-smtp-select-review.png" alt-text="Screenshot that shows reviewing the assignment."::: 1. After confirming the scope and members, click **Review + assign**. :::image type="content" source="../media/email-smtp-select-assign.png" alt-text="Screenshot that shows assigning the custom role."::: -### Creating the SMTP credentials from the Entra application information. +### Creating the SMTP credentials from the Microsoft Entra application information. #### SMTP Authentication Username-Azure Communication Services allows the credentials for an Entra application to be used as the SMTP username and password. The username consists of the following three parts and can be pipe or dot delimited. +Azure Communication Services allows the credentials for a Microsoft Entra application to be used as the SMTP username and password. The username consists of the following three parts and can be pipe or dot delimited. 1. The Azure Communication Service Resource name. :::image type="content" source="../media/email-smtp-resource-name.png" alt-text="Screenshot that shows finding the resource name.":::-1. The Entra Application ID. - :::image type="content" source="../media/email-smtp-entra-details.png" alt-text="Screenshot that shows finding the Entra Application ID."::: -1. The Entra Tenant ID. - :::image type="content" source="../media/email-smtp-entra-tenant.png" alt-text="Screenshot that shows finding the Entra Tenant ID."::: +1. The Microsoft Entra Application ID. + :::image type="content" source="../media/email-smtp-entra-details.png" alt-text="Screenshot that shows finding the Microsoft Entra Application ID."::: +1. The Microsoft Entra Tenant ID. + :::image type="content" source="../media/email-smtp-entra-tenant.png" alt-text="Screenshot that shows finding the Microsoft Entra Tenant ID."::: **Dot-delimited Format:** ```-username: <Azure Communication Services Resource name>.<Entra Application ID>.<Entra Tenant ID> +username: <Azure Communication Services Resource name>.<Microsoft Entra Application ID>.<Microsoft Entra Tenant ID> ``` **Pipe-delimited Format:** ```-username: <Azure Communication Services Resource name>|<Entra Application ID>|<Entra Tenant ID> +username: <Azure Communication Services Resource name>|<Microsoft Entra Application ID>|<Microsoft Entra Tenant ID> ``` #### SMTP Authentication Password-The password is one of the Entra application's client secrets. - :::image type="content" source="../media/email-smtp-entra-secret.png" alt-text="Screenshot that shows finding the Entra client secret."::: +The password is one of the Microsoft Entra application's client secrets. + :::image type="content" source="../media/email-smtp-entra-secret.png" alt-text="Screenshot that shows finding the Microsoft Entra client secret."::: ### Requirements for SMTP AUTH client submission -- **Authentication**: Username and password authentication is supported using Entra application details as the credentials. The Azure Communication Services SMTP service will use the Entra application details to get an access token on behalf of the user and use that to submit the email. Because the Entra token isn't cached, access can be revoked immediately by either changing the Entra application client secret or by changing the access controls for the Azure Communication Services Resource.+- **Authentication**: Username and password authentication is supported using the Microsoft Entra application details as the credentials. The Azure Communication Services SMTP service will use the Microsoft Entra application details to get an access token on behalf of the user and use that to submit the email. Because the Microsoft Entra token isn't cached, access can be revoked immediately by either changing the Microsoft Entra application client secret or by changing the access controls for the Azure Communication Services Resource. - **Azure Communication Service**: An Azure Communication Services Resource with a connected Azure Communication Email Resource and domain is required. - **Transport Layer Security (TLS)**: Your device must be able to use TLS version 1.2 and above. - **Port**: Port 587 is required and must be unblocked on your network. Some network firewalls or ISPs block ports because that's the port that email servers use to send mail. Enter the following settings directly on your device or in the application as th |Server / smart host | smtp.azurecomm.net | |Port |Port 587| |TLS / StartTLS | Enabled|-|Username and password | Enter the Entra application credentials from an application with access to the Azure Communication Services Resource | +|Username and password | Enter the Microsoft Entra application credentials from an application with access to the Azure Communication Services Resource | |
digital-twins | How To Provision Using Device Provisioning Service | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/digital-twins/how-to-provision-using-device-provisioning-service.md | - Title: Automanage devices using Device Provisioning Service- -description: Learn how to set up an automated process to provision and retire IoT devices in Azure Digital Twins using Device Provisioning Service (DPS). -- Previously updated : 11/18/2022-----# Optional fields. Don't forget to remove # if you need a field. -# -# ---# Automanage devices in Azure Digital Twins using Device Provisioning Service (DPS) --In this article, you'll learn how to integrate Azure Digital Twins with [Device Provisioning Service (DPS)](../iot-dps/about-iot-dps.md). --The solution described in this article will allow you to automate the process to provision and retire IoT Hub devices in Azure Digital Twins, using Device Provisioning Service. --For more information about the provision and retire stages, and to better understand the set of general device management stages that are common to all enterprise IoT projects, see the [Device lifecycle section](../iot-hub/iot-hub-device-management-overview.md#device-lifecycle) of IoT Hub's device management documentation. --## Prerequisites --Before you can set up the provisioning, you'll need to set up the following resources: -* An Azure Digital Twins instance. Follow the instructions in [Set up an instance and authentication](how-to-set-up-instance-portal.md) to create an Azure digital twins instance. Gather the instance's **host name** in the Azure portal ([instructions](how-to-set-up-instance-portal.md#verify-success-and-collect-important-values)). -* An IoT hub. For instructions, see the "Create an IoT Hub" section of [the IoT Hub quickstart](../iot-hub/quickstart-send-telemetry-cli.md). -* An [Azure function](../azure-functions/functions-overview.md) that updates digital twin information based on IoT Hub data. Follow the instructions in [Ingest IoT hub data](how-to-ingest-iot-hub-data.md) to create this Azure function. Gather the function **name** to use it in this article. --This sample also uses a *device simulator* that includes provisioning using the Device Provisioning Service. The device simulator is located here: [Azure Digital Twins and IoT Hub Integration Sample](https://github.com/Azure-Samples/digital-twins-iothub-integration). Get the sample project on your machine by navigating to the GitHub repo for the sample, which you can download as a .zip file by selecting the **Code** button and **Download ZIP**. ---Unzip the downloaded folder. --You'll need [Node.js](https://nodejs.org) installed on your machine. The device simulator is based on Node.js, version 10.0.x or later. --## Solution architecture --This solution includes steps for provisioning and retiring a device in Azure Digital Twins, using Device Provisioning Service. --To allocate devices in the solution, data flows between a thermostat device and DPS. The data then flows from DPS into IoT Hub, and to Azure Digital Twins through an Azure function. --To retire a device, data from a manual device deletion flows into Azure Digital Twins through IoT Hub, Event Hubs, and an Azure function. --The image below illustrates this architecture. ---This article is divided into two sections, each focused on a portion of this full architecture: -* [Autoprovision device using Device Provisioning Service](#autoprovision-device-using-device-provisioning-service) -* [Autoretire device using IoT Hub lifecycle events](#autoretire-device-using-iot-hub-lifecycle-events) --## Autoprovision device using Device Provisioning Service --In this section, you'll be attaching Device Provisioning Service to Azure Digital Twins to autoprovision devices through the path below. This diagram is an excerpt from the full architecture shown [earlier](#solution-architecture). ---Here's a description of the process flow: -1. Device contacts the DPS endpoint, passing identifying information to prove its identity. -2. DPS validates device identity by validating the registration ID and key against the enrollment list, and calls an [Azure function](../azure-functions/functions-overview.md) to do the allocation. -3. The Azure function creates a new [twin](concepts-twins-graph.md) in Azure Digital Twins for the device. The twin will have the same name as the device's **registration ID**. -4. DPS registers the device with an IoT hub, and populates the device's chosen twin state. -5. The IoT hub returns device ID information and the IoT hub connection information to the device. The device can now connect to the IoT hub. --The following sections walk through the steps to set up this autoprovision device flow. --### Create a Device Provisioning Service --When a new device is provisioned using Device Provisioning Service, a new twin for that device can be created in Azure Digital Twins with the same name as the registration ID. --Create a Device Provisioning Service instance, which will be used to provision IoT devices. You can either use the Azure CLI instructions below, or use the Azure portal by following [Set up the IoT Hub Device Provisioning Service with the Azure portal](../iot-dps/quick-setup-auto-provision.md). --The following Azure CLI command will create a Device Provisioning Service. You'll need to specify a Device Provisioning Service name, resource group, and region. To see what regions support Device Provisioning Service, visit [Azure products available by region](https://azure.microsoft.com/global-infrastructure/services/?products=iot-hub). -The command can be run in [Cloud Shell](https://shell.azure.com), or locally if you have the [Azure CLI installed on your machine](/cli/azure/install-azure-cli). --```azurecli-interactive -az iot dps create --name <Device-Provisioning-Service-name> --resource-group <resource-group-name> --location <region> -``` --### Add a function to use with Device Provisioning Service --Inside your function app project that you created in the [Prerequisites section](#prerequisites), you'll create a new function to use with the Device Provisioning Service. This function will be used by the Device Provisioning Service in a [Custom Allocation Policy](../iot-dps/how-to-use-custom-allocation-policies.md) to provision a new device. --Navigate to the function app project on your machine and follow the steps below. --1. First, create a new function of type **HTTP-trigger** in the function app project. --2. Add a new NuGet package to the project: [Microsoft.Azure.Devices.Provisioning.Service](https://www.nuget.org/packages/Microsoft.Azure.Devices.Provisioning.Service/). You might need to add more packages to your project as well, if the packages used in the code aren't part of the project already. --3. In the newly created function code file, paste in the following code, name the function *DpsAdtAllocationFunc.cs*, and save the file. -- :::code language="csharp" source="~/digital-twins-docs-samples-dps/functions/DpsAdtAllocationFunc.cs"::: --4. Publish the project with the *DpsAdtAllocationFunc.cs* function to a function app in Azure. -- For instructions on how to publish the function using **Visual Studio**, see [Develop Azure Functions using Visual Studio](../azure-functions/functions-develop-vs.md#publish-to-azure). For instructions on how to publish the function using **Visual Studio Code**, see [Create a C# function in Azure using Visual Studio Code](../azure-functions/create-first-function-vs-code-csharp.md?tabs=in-process#publish-the-project-to-azure). For instructions on how to publish the function using the **Azure CLI**, see [Create a C# function in Azure from the command line](../azure-functions/create-first-function-cli-csharp.md?tabs=azure-cli%2Cin-process#deploy-the-function-project-to-azure). --> [!IMPORTANT] -> When creating the function app for the first time in the [Prerequisites section](#prerequisites), you may have already assigned an access role for the function and configured the application settings for it to access your Azure Digital Twins instance. These need to be done once for the entire function app, so verify they've been completed in your app before continuing. You can find instructions in the [Configure published app](how-to-authenticate-client.md#configure-published-app) section of the *Write app authentication code* article. --### Create Device Provisioning enrollment --Next, you'll need to create an enrollment in Device Provisioning Service using a *custom allocation function*. To create an enrollment, follow the instructions in the [Create the enrollment](../iot-dps/how-to-use-custom-allocation-policies.md#create-the-enrollment) section of the custom allocation policies article in the Device Provisioning Service documentation. --While going through that flow, make sure you select the following options to link the enrollment to the function you created. --* **Select how you want to assign devices to hubs**: Custom (Use Azure Function). -* **Select the IoT hubs this group can be assigned to:** Choose your IoT hub name or select the **Link a new IoT hub** button, and choose your IoT hub from the options. --Next, choose the **Select a new function** button to link your function app to the enrollment group. Then, fill in the following values: --* **Subscription**: Your Azure subscription is autopopulated. Make sure it's the right subscription. -* **Function App**: Choose your function app name. -* **Function**: Choose *DpsAdtAllocationFunc*. --Save your details. ---After creating the enrollment, select it to view its settings. Copy the **Primary Key** for the enrollment, which will be used later in this article to configure the device simulator. --### Set up the device simulator --This sample uses a device simulator that includes provisioning using the Device Provisioning Service. The device simulator is located in the [Azure Digital Twins and IoT Hub Integration Sample](https://github.com/Azure-Samples/digital-twins-iothub-integration) that you downloaded in the [Prerequisites section](#prerequisites). --#### Upload the model --The device simulator is a thermostat-type device that uses the model with this ID: `dtmi:contosocom:DigitalTwins:Thermostat;1`. You'll need to upload this model to Azure Digital Twins before you can create a twin of this type for the device. --The model looks like this: --To upload this model to your twins instance, run the following Azure CLI command, which uploads the above model as inline JSON. You can run the command in [Azure Cloud Shell](../cloud-shell/overview.md) in your browser (use the Bash environment), or on your machine if you have the [CLI installed locally](/cli/azure/install-azure-cli). There's one placeholder for the instance's host name (you can also use the instance's friendly name with a slight decrease in performance). --```azurecli-interactive -az dt model create --dt-name <instance-hostname-or-name> --models '{ "@id": "dtmi:contosocom:DigitalTwins:Thermostat;1", "@type": "Interface", "@context": "dtmi:dtdl:context;2", "contents": [ { "@type": "Property", "name": "Temperature", "schema": "double" } ]}' -``` -->[!NOTE] ->If you're using anything other than Cloud Shell in the Bash environment, you may need to escape certain characters in the inline JSON so that it's parsed correctly. For more information, see [Use special characters in different shells](concepts-cli.md#use-special-characters-in-different-shells). --For more information about models, see [Manage models](how-to-manage-model.md#upload-models). --#### Configure and run the simulator --In a command window on your local machine, navigate to the downloaded sample *Azure Digital Twins and IoT Hub Integration* that you unzipped earlier, and then into the *device-simulator* directory. Next, install the dependencies for the project using the following command: --```cmd -npm install -``` --Next, in your device simulator directory, copy the *.env.template* file to a new file called *.env*, and gather the following values to fill in the settings: --* PROVISIONING_IDSCOPE: To get this value, navigate to your device provisioning service in the [Azure portal](https://portal.azure.com/), then select **Overview** in the menu options and look for the field **ID Scope**. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/id-scope.png" alt-text="Screenshot of the Azure portal view of the device provisioning overview page highlighting the ID Scope value." lightbox="media/how-to-provision-using-device-provisioning-service/id-scope.png"::: --* PROVISIONING_REGISTRATION_ID: You can choose a registration ID for your device. -* ADT_MODEL_ID: `dtmi:contosocom:DigitalTwins:Thermostat;1` -* PROVISIONING_SYMMETRIC_KEY: This environment variable is the primary key for the enrollment you set up earlier. To get this value again, navigate to your device provisioning service in the Azure portal, select **Manage enrollments**, then select the enrollment group that you created earlier and copy the **Primary Key**. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/sas-primary-key.png" alt-text="Screenshot of the Azure portal view of the device provisioning service manage enrollments page highlighting the SAS primary key value." lightbox="media/how-to-provision-using-device-provisioning-service/sas-primary-key.png"::: --Now, use the values above to update the *.env* file settings. --```cmd -PROVISIONING_HOST = "global.azure-devices-provisioning.net" -PROVISIONING_IDSCOPE = "<Device-Provisioning-Service-Scope-ID>" -PROVISIONING_REGISTRATION_ID = "<Device-Registration-ID>" -ADT_MODEL_ID = "dtmi:contosocom:DigitalTwins:Thermostat;1" -PROVISIONING_SYMMETRIC_KEY = "<Device-Provisioning-Service-enrollment-primary-SAS-key>" -``` --Save and close the file. --### Start running the device simulator --Still in the *device-simulator* directory in your command window, start the device simulator using the following command: --```cmd -node .\adt_custom_register.js -``` --You should see the device being registered and connected to IoT Hub, and then starting to send messages. --### Validate --The flow you've set up in this article will result in the device automatically being registered in Azure Digital Twins. Use the following [Azure Digital Twins CLI](/cli/azure/dt/twin#az-dt-twin-show) command to find the twin of the device in the Azure Digital Twins instance you created. There's a placeholder for the instance's host name (you can also use the instance's friendly name with a slight decrease in performance), and a placeholder for the device registration ID. --```azurecli-interactive -az dt twin show --dt-name <instance-hostname-or-name> --twin-id "<device-registration-ID>" -``` --You should see the twin of the device being found in the Azure Digital Twins instance. --## Autoretire device using IoT Hub lifecycle events --In this section, you'll be attaching IoT Hub lifecycle events to Azure Digital Twins to autoretire devices through the path below. This diagram is an excerpt from the full architecture shown [earlier](#solution-architecture). ---Here's a description of the process flow: -1. An external or manual process triggers the deletion of a device in IoT Hub. -2. IoT Hub deletes the device and generates a [device lifecycle](../iot-hub/iot-hub-device-management-overview.md#device-lifecycle) event that will be routed to an [event hub](../event-hubs/event-hubs-about.md). -3. An Azure function deletes the twin of the device in Azure Digital Twins. --The following sections walk through the steps to set up this autoretire device flow. --### Create an event hub --Next, you'll create an Azure [event hub](../event-hubs/event-hubs-about.md) to receive IoT Hub lifecycle events. --Follow the steps described in the [Create an event hub](../event-hubs/event-hubs-create.md) quickstart. Name your event hub *lifecycleevents*. You'll use this event hub name when you set up IoT Hub route and an Azure function in the next sections. --The screenshot below illustrates the creation of the event hub. --#### Create SAS policy for your event hub --Next, you'll need to create a [shared access signature (SAS) policy](../event-hubs/authorize-access-shared-access-signature.md) to configure the event hub with your function app. -To create the SAS policy: -1. Navigate to the event hub you created in the Azure portal and select **Shared access policies** in the menu options on the left. -2. Select **Add**. In the **Add SAS Policy** window that opens, enter a policy name of your choice and select the **Listen** checkbox. -3. Select **Create**. - --#### Configure event hub with function app --Next, configure the Azure function app that you set up in the [Prerequisites section](#prerequisites) to work with your new event hub. You'll configure the function by setting an environment variable inside the function app with the event hub's connection string. --1. Open the policy that you created and copy the **Connection string-primary key** value. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/event-hub-sas-policy-connection-string.png" alt-text="Screenshot of the Azure portal showing how to copy the connection string-primary key." lightbox="media/how-to-provision-using-device-provisioning-service/event-hub-sas-policy-connection-string.png"::: --2. Add the connection string as a variable in the function app settings with the following Azure CLI command. The command can be run in [Cloud Shell](https://shell.azure.com), or locally if you have the [Azure CLI installed on your machine](/cli/azure/install-azure-cli). -- ```azurecli-interactive - az functionapp config appsettings set --settings "EVENTHUB_CONNECTIONSTRING=<Event-Hubs-SAS-connection-string-Listen>" --resource-group <resource-group> --name <your-function-app-name> - ``` --### Add a function to retire with IoT Hub lifecycle events --Inside your function app project that you created in the [Prerequisites section](#prerequisites), you'll create a new function to retire an existing device using IoT Hub lifecycle events. --For more about lifecycle events, see [IoT Hub Non-telemetry events](../iot-hub/iot-hub-devguide-messages-d2c.md#non-telemetry-events). For more information about using Event Hubs with Azure functions, see [Azure Event Hubs trigger for Azure Functions](../azure-functions/functions-bindings-event-hubs-trigger.md). --Navigate to the function app project on your machine and follow the steps below. --1. First, create a new function of type **Event Hub Trigger** in the function app project. --2. Add a new NuGet package to the project: [Microsoft.Azure.Devices.Provisioning.Service](https://www.nuget.org/packages/Microsoft.Azure.Devices.Provisioning.Service/). You might need to add more packages to your project as well, if the packages used in the code aren't part of the project already. --3. In the newly created function code file, paste in the following code, name the function *DeleteDeviceInTwinFunc.cs*, and save the file. -- :::code language="csharp" source="~/digital-twins-docs-samples-dps/functions/DeleteDeviceInTwinFunc.cs"::: --4. Publish the project with the *DeleteDeviceInTwinFunc.cs* function to a function app in Azure. -- For instructions on how to publish the function using **Visual Studio**, see [Develop Azure Functions using Visual Studio](../azure-functions/functions-develop-vs.md#publish-to-azure). For instructions on how to publish the function using **Visual Studio Code**, see [Create a C# function in Azure using Visual Studio Code](../azure-functions/create-first-function-vs-code-csharp.md?tabs=in-process#publish-the-project-to-azure). For instructions on how to publish the function using the **Azure CLI**, see [Create a C# function in Azure from the command line](../azure-functions/create-first-function-cli-csharp.md?tabs=azure-cli%2Cin-process#deploy-the-function-project-to-azure). --> [!IMPORTANT] -> When creating the function app for the first time in the [Prerequisites section](#prerequisites), you may have already assigned an access role for the function and configured the application settings for it to access your Azure Digital Twins instance. These need to be done once for the entire function app, so verify they've been completed in your app before continuing. You can find instructions in the [Configure published app](how-to-authenticate-client.md#configure-published-app) section of the *Write app authentication code* article. --### Create an IoT Hub route for lifecycle events --Now you'll set up an IoT Hub route, to route device lifecycle events. In this case, you'll specifically listen to device delete events, identified by `if (opType == "deleteDeviceIdentity")`. This event will trigger the delete of the digital twin item, completing the retirement process of a device and its digital twin. --First, you'll need to create an event hub endpoint in your IoT hub. Then, you'll add a route in IoT hub to send lifecycle events to this event hub endpoint. -Follow these steps to create an event hub endpoint: --1. In the [Azure portal](https://portal.azure.com/), navigate to the IoT hub you created in the [Prerequisites section](#prerequisites) and select **Message routing** in the menu options on the left. -2. Select the **Custom endpoints** tab. -3. Select **+ Add** and choose **Event hubs** to add an Event Hubs type endpoint. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/event-hub-custom-endpoint.png" alt-text="Screenshot of the Azure portal showing how to add an Event Hubs custom endpoint." lightbox="media/how-to-provision-using-device-provisioning-service/event-hub-custom-endpoint.png"::: --4. In the window **Add an event hub endpoint** that opens, choose the following values: - * **Endpoint name**: Choose an endpoint name. - * **Event hub namespace**: Select your event hub namespace from the dropdown list. - * **Event hub instance**: Choose the event hub name that you created in the previous step. -5. Select **Create**. Keep this window open to add a route in the next step. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/add-event-hub-endpoint.png" alt-text="Screenshot of the Azure portal showing how to add an event hub endpoint." lightbox="media/how-to-provision-using-device-provisioning-service/add-event-hub-endpoint.png"::: --Next, you'll add a route that connects to the endpoint you created in the above step, with a routing query that sends the delete events. Follow these steps to create a route: --1. Navigate to the **Routes** tab and select **Add** to add a route. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/add-message-route.png" alt-text="Screenshot of the Azure portal showing how to add a route to send events." lightbox="media/how-to-provision-using-device-provisioning-service/add-message-route.png"::: --2. In the **Add a route** page that opens, choose the following values: -- * **Name**: Choose a name for your route. - * **Endpoint**: Choose the Event Hubs endpoint you created earlier from the dropdown. - * **Data source**: Choose **Device Lifecycle Events**. - * **Routing query**: Enter `opType='deleteDeviceIdentity'`. This query limits the device lifecycle events to only send the delete events. --3. Select **Save**. -- :::image type="content" source="media/how-to-provision-using-device-provisioning-service/lifecycle-route.png" alt-text="Screenshot of the Azure portal showing how to add a route to send lifecycle events." lightbox="media/how-to-provision-using-device-provisioning-service/lifecycle-route.png"::: --Once you've gone through this flow, everything is set to retire devices end-to-end. --### Validate --To trigger the process of retirement, you need to manually delete the device from IoT Hub. --You can manually delete the device from IoT Hub with an [Azure CLI command](/cli/azure/iot/hub/module-identity#az-iot-hub-module-identity-delete) or in the Azure portal. -Follow the steps below to delete the device in the Azure portal: --1. Navigate to your IoT hub, and choose **IoT devices** in the menu options on the left. -2. You'll see a device with the device registration ID you chose in the [first half of this article](#autoprovision-device-using-device-provisioning-service). You can also choose any other device to delete, as long as it has a twin in Azure Digital Twins so you can verify that the twin is automatically deleted after the device is deleted. -3. Select the device and choose **Delete**. ---It might take a few minutes to see the changes reflected in Azure Digital Twins. --Use the following [Azure Digital Twins CLI](/cli/azure/dt/twin#az-dt-twin-show) command to verify the twin of the device in the Azure Digital Twins instance was deleted. There's a placeholder for the instance's host name (you can also use the instance's friendly name with a slight decrease in performance), and a placeholder for the device registration ID. --```azurecli-interactive -az dt twin show --dt-name <instance-hostname-or-name> --twin-id "<device-registration-ID>" -``` --You should see that the twin of the device cannot be found in the Azure Digital Twins instance anymore. ---## Clean up resources --If you no longer need the resources created in this article, follow these steps to delete them. --Using the Azure Cloud Shell or local Azure CLI, you can delete all Azure resources in a resource group with the [az group delete](/cli/azure/group#az-group-delete) command. This command removes the resource group; the Azure Digital Twins instance; the IoT hub and the hub device registration; the Event Grid topic and associated subscriptions; the Event Hubs namespace and both Azure Functions apps, including associated resources like storage. --> [!IMPORTANT] -> Deleting a resource group is irreversible. The resource group and all the resources contained in it are permanently deleted. Make sure that you do not accidentally delete the wrong resource group or resources. --```azurecli-interactive -az group delete --name <your-resource-group> -``` --Then, delete the project sample folder you downloaded from your local machine. --## Next steps --The digital twins created for the devices are stored as a flat hierarchy in Azure Digital Twins, but they can be enriched with model information and a multi-level hierarchy for organization. To learn more about this concept, read: --* [Digital twins and the twin graph](concepts-twins-graph.md) --For more information about using HTTP requests with Azure functions, see: --* [Azure Http request trigger for Azure Functions](../azure-functions/functions-bindings-http-webhook-trigger.md) --You can write custom logic to automatically provide this information using the model and graph data already stored in Azure Digital Twins. To read more about managing, upgrading, and retrieving information from the twins graph, see the following how-to guides: --* [Manage a digital twin](how-to-manage-twin.md) -* [Query the twin graph](how-to-query-graph.md) |
healthcare-apis | Use Postman | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/healthcare-apis/fhir/use-postman.md | To access the FHIR service, you need to create or update these variables: |--|--|-| | **tenantid** | Azure tenant where the FHIR service is deployed | Located on the Application registration overview | | **subid** | Azure subscription where the FHIR service is deployed | Located on the FHIR service overview |-| **clientid** | Application client registration ID | - | -| **clientsecret** | Application client registration secret | - | +| **clientid** | Application client registration ID | | +| **clientsecret** | Application client registration secret | | | **fhirurl** | The FHIR service full URL (for example, `https://xxx.azurehealthcareapis.com`) | Located on the FHIR service overview | | **bearerToken** | Stores the Microsoft Entra access token in the script | Leave blank | To access the FHIR service, you need to create or update these variables: ## Get the capability statement -Enter `{{fhirurl}}/metadata` in the `GET`request, and then choose `Send`. You should see the capability statement of the FHIR service. +Enter `{{fhirurl}}/metadata` in the `GET` request, then choose `Send`. You should see the capability statement of the FHIR service. :::image type="content" source="media/postman/postman-capability-statement.png" alt-text="Screenshot showing capability request parameters." lightbox="media/postman/postman-create-new-request.png"::: Enter `{{fhirurl}}/metadata` in the `GET`request, and then choose `Send`. You sh ## Get a Microsoft Entra access token -Get a Microsoft Entra access token by using a service principal or a Microsoft Entra user account. Choose one of the two methods. +Get a Microsoft Entra access token by choosing either a service principal, or a Microsoft Entra user account. ### Use a service principal with a client credential grant type Create a new `POST` request: > [!NOTE] > In scenarios where the FHIR service audience parameter isn't mapped to the FHIR service endpoint URL, the resource parameter value should be mapped to the audience value on the FHIR service **Authentication** pane. -3. Select the **Test** tab and enter in the text section: `pm.environment.set("bearerToken", pm.response.json().access_token);` To make the value available to the collection, use the pm.collectionVariables.set method. For more information on the set method and its scope level, see [Using variables in scripts](https://learning.postman.com/docs/sending-requests/variables/#defining-variables-in-scripts). +3. Select the **Test** tab and enter `pm.environment.set("bearerToken", pm.response.json().access_token);` in the text section. To make the value available to the collection, use the pm.collectionVariables.set method. For more information on the set method and its scope level, see [Using variables in scripts](https://learning.postman.com/docs/sending-requests/variables/#defining-variables-in-scripts). 4. Select **Save** to save the settings.-5. Select **Send**. You should see a response with the Microsoft Entra access token, which is saved to the variable `bearerToken` automatically. You can then use it in all FHIR service API requests. +5. Select **Send**. You should see a response with the Microsoft Entra access token, which is automatically saved to the variable `bearerToken`. You can then use it in all FHIR service API requests. :::image type="content" source="media/postman/postman-send-button.png" alt-text="Screenshot showing the send button." lightbox="media/postman/postman-send-button.png"::: You can examine the access token using online tools such as [https://jwt.ms](htt ## Use a user account with the authorization code grant type -You can get the Microsoft Entra access token by using your Entra account credentials and following the listed steps. +You can get the Microsoft Entra access token by using your Microsoft Entra account credentials and following the listed steps. 1. Verify that you're a member of Microsoft Entra tenant with the required access permissions. You can get the Microsoft Entra access token by using your Entra account credent :::image type="content" source="media/postman/app-registration-permissions-2.png" alt-text="Screenshot showing application registration permissions screen." lightbox="media/postman/app-registration-permissions-2.png"::: -1. In the Postman, select the **Authorization** tab of either a collection or a specific REST Call, select **Type** as OAuth 2.0 and under **Configure New Token** section, set these values: +1. In Postman, select the **Authorization** tab of either a collection or a specific REST Call, select **Type** as OAuth 2.0 and under **Configure New Token** section, set these values: - **Callback URL**: `https://oauth.pstmn.io/v1/callback` - **Auth URL**: `https://login.microsoftonline.com/{{tenantid}}/oauth2/v2.0/authorize` You can get the Microsoft Entra access token by using your Entra account credent 1. Choose **Get New Access Token** at the bottom of the page. -1. You're asked for User credentials for sign-in. +1. Provide User credentials for sign-in. -1. You receive the token. Choose **Use Token.** +1. Once you receive the token, choose **Use Token.** 1. Ensure the token is in the **Authorization Header** of the REST call. Open Postman, select the **workspace**, **collection**, and **environment** you :::image type="content" source="media/postman/postman-create-new-request.png" alt-text="Screenshot showing creation of new request." lightbox="media/postman/postman-create-new-request.png"::: -To perform health check on FHIR service, enter `{{fhirurl}}/health/check` in the GET request, and then choose **Send**. You should be able to see the `Status of FHIR service - HTTP Status` code response with 200 and OverallStatus as **Healthy** in response, which means your health check is successful. +To perform a health check on the FHIR service, enter `{{fhirurl}}/health/check` in the GET request, and then choose **Send**. You should be able to see the `Status of FHIR service - HTTP Status` code response with 200 and OverallStatus as **Healthy** in response, which means your health check is successful. ## Get the FHIR resource Select **Bearer Token** as authorization type. Enter `{{bearerToken}}` in the ** After you obtain a Microsoft Entra access token, you can create or update the FHIR data. For example, you can create a new patient or update an existing patient. -Create a new request, change the method to **Post**, and then enter the value in the request section. +Create a new request, change the method to **Post**, and enter the value in the request section. `{{fhirurl}}/Patient` -Select **Bearer Token** as the authorization type. Enter `{{bearerToken}}` in the **Token** section. Select the **Body** tab. Select the **raw** option and **JSON** as body text format. Copy and paste the text to the body section. +Select **Bearer Token** as the authorization type. Enter `{{bearerToken}}` in the **Token** section. Select the **Body** tab. Select the **raw** option and **JSON** as body text format. Copy and paste the following text to the body section. ``` Select **Bearer Token** as authorization type. Enter `{{bearerToken}}` in the ** - **Prefer**: `respond-async` -Select **Send**. You should notice a `202 Accepted` response. Select the **Headers** tab of the response and make a note of the value in the **Content-Location**. You can use the value to query the export job status. +Select **Send**. You should notice a `202 Accepted` response. Select the **Headers** tab of the response and make a note of the value in the **Content-Location**. You can use this value to query the export job status. :::image type="content" source="media/postman/postman-202-accepted-response.png" alt-text="Screenshot showing selection 202 accepted response." lightbox="media/postman/postman-202-accepted-response.png"::: |
healthcare-apis | Using Curl | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/healthcare-apis/fhir/using-curl.md | -In this article, you'll learn how to access Azure Health Data Services with cURL. +In this article, you learn how to access Azure Health Data Services with cURL. ## Prerequisites ### PowerShell * An Azure account with an active subscription. [Create one for free](https://azure.microsoft.com/free/).-* If you want to run the code locally, install [PowerShell](/powershell/module/powershellget/) and [Azure Az PowerShell](/powershell/azure/install-azure-powershell). +* If you want to run the code locally, install [PowerShell](/powershell/module/powershellget/) and [Azure Az PowerShell module PowerShell](/powershell/azure/install-azure-powershell). * Optionally, you can run the scripts in Visual Studio Code with the REST Client extension. For more information, see [Make a link to the REST Client doc](using-rest-client.md). * Download and install [cURL](https://curl.se/download.html). In this article, you'll learn how to access Azure Health Data Services with cURL * An Azure account with an active subscription. [Create one for free](https://azure.microsoft.com/free/). * If you want to run the code locally, install [Azure CLI](/cli/azure/install-azure-cli). -* Optionally, install a Bash shell, such as Git Bash, which it's included in [Git for Windows](https://gitforwindows.org/). +* Optionally, install a Bash shell, such as Git Bash, which is included in [Git for Windows](https://gitforwindows.org/). * Optionally, run the scripts in Visual Studio Code with the REST Client extension. For more information, see [Make a link to the REST Client doc](using-rest-client.md). * Download and install [cURL](https://curl.se/download.html). token=$(az account get-access-token --resource=$dicomtokenurl --query accessToke > [!NOTE] -> In the scenarios where the FHIR service audience parameter is not mapped to the FHIR service endpoint url. The resource parameter value should be mapped to Audience value under FHIR Service Authentication blade. +> When the FHIR® service audience parameter is not mapped to the FHIR service endpoint url, the resource parameter value should be mapped to Audience value under the FHIR Service Authentication blade. ## Access data in the FHIR service To learn about how to access Azure Health Data Services data using REST Client e >[!div class="nextstepaction"] >[Access Azure Health Data Services using REST Client](using-rest-client.md) -FHIR® is a registered trademark of [HL7](https://hl7.org/fhir/) and is used with the permission of HL7. |
healthcare-apis | Using Rest Client | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/healthcare-apis/fhir/using-rest-client.md | -In this article, you'll learn how to access Azure Health Data Services using [REST Client extension in Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=humao.rest-client). +In this article, you learn how to access Azure Health Data Services using [REST Client extension in Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=humao.rest-client). ## Install REST Client extension Select the Extensions icon on the left side panel of your Visual Studio Code, and search for "REST Client". Find the [REST Client extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) and install. -[ ![REST Client VSCode extension](media/rest-install.png) ](media/rest-install.png#lightbox) +[![REST Client VSCode extension](media/rest-install.png)](media/rest-install.png#lightbox) ## Create a `.http` file and define variables Create a new file in Visual Studio Code. Enter a `GET` request command line in the file, and save it as `test.http`. The file suffix `.http` automatically activates the REST Client environment. Select `Send Request` to get the metadata. -[ ![Send Request](media/rest-send-request.png) ](media/rest-send-request.png#lightbox) +[![Send Request](media/rest-send-request.png)](media/rest-send-request.png#lightbox) ## Get client application values > [!Important]-> Before calling the FHIR server REST API (other than getting the metadata), you must complete [application registration](../register-application.md). Make a note of your Azure **tenant ID**, **client ID**, **client secret** and the **service URL**. +> Before calling the FHIR® server REST API (other than getting the metadata), you must complete [application registration](../register-application.md). Make a note of your Azure **tenant ID**, **client ID**, **client secret** and the **service URL**. While you can use values such as the client ID directly in calls to the REST API, it's a good practice that you define a few variables for these values and use the variables instead. -In your `test.http` file, include the following information obtained from registering your application: +In your `test.http` file, include the following information obtained from registering your application. ``` ### REST Client In your `test.http` file, include the following information obtained from regist ## Get Microsoft Entra access token -After including the information below in your `test.http` file, hit `Send Request`. You'll see an HTTP response that contains your access token. +After including the following information in your `test.http` file, hit `Send Request`. You'll see an HTTP response that contains your access token. The line starting with `@name` contains a variable that captures the HTTP response containing the access token. The variable, `@token`, is used to store the access token. grant_type=client_credentials [ ![Get access token](media/rest-config.png) ](media/rest-config.png#lightbox) > [!NOTE] -> In the scenarios where the FHIR service audience parameter is not mapped to the FHIR service endpoint url. The resource parameter value should be mapped to Audience value under FHIR Service Authentication blade. +> When the FHIR service audience parameter is not mapped to the FHIR service endpoint url, the resource parameter value should be mapped to the Audience value under the FHIR Service Authentication blade. -## `GET` FHIR Patient data +## Get FHIR Patient data -You can now get a list of patients or a specific patient with the `GET` request. The line with `Authorization` is the header info for the `GET` request. You can also send `PUT` or `POST` requests to create/update FHIR resources. +You can now get a list of patients or a specific patient with the `GET` request. The line with `Authorization` is the header info for the `GET` request. You can also send `PUT` or `POST` requests to create and update FHIR resources. ``` ### GET Patient You can run PowerShell or CLI scripts within Visual Studio Code. Press `CTRL` an ## Troubleshooting -If you're unable to get the metadata, which doesn't require access token based on the HL7 specification, check that your FHIR server is running properly. +If you're unable to get the metadata (which doesn't require access token based on the HL7 specification) check that your FHIR server is running properly. If you're unable to get an access token, make sure that the client application is registered properly and you're using the correct values from the application registration step. If you're unable to get data from the FHIR server, make sure that the client app ## Next steps -In this article, you learned how to access Azure Health Data Services data using the using the REST Client extension in Visual Studio Code. +In this article, you learned how to access Azure Health Data Services data using the REST Client extension in Visual Studio Code. To learn about how to validate FHIR resources against profiles in Azure Health Data Services, see >[!div class="nextstepaction"] >[Validate FHIR resources against profiles in Azure Health Data Services](validation-against-profiles.md) -FHIR® is a registered trademark of [HL7](https://hl7.org/fhir/) and is used with the permission of HL7. + |
healthcare-apis | Validation Against Profiles | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/healthcare-apis/fhir/validation-against-profiles.md | -In the [store profiles in the FHIR service](store-profiles-in-fhir.md) article, you walked through the basics of FHIR profiles and storing them. The FHIR service in Azure Health Data Services (hereby called the FHIR service) allows validating resources against profiles to see if the resources conform to the profiles. This article will guide you through how to use `$validate` for validating resources against profiles. +In the [store profiles in the FHIR® service](store-profiles-in-fhir.md) article, you walked through the basics of FHIR profiles and storing them. The FHIR service in Azure Health Data Services allows validating resources against profiles to see if the resources conform to the profiles. This article guides you through how to use `$validate` for validating resources against profiles. ++`$validate` is an operation in Fast Healthcare Interoperability Resources (FHIR) that allows you to ensure that a FHIR resource conforms to the base resource requirements or a specified profile. This operation ensures that the data in a FHIR service has the expected attributes and values. For information on the validate operation, visit [HL7 FHIR Specification](https://www.hl7.org/fhir/resource-operation-validate.html). -`$validate` is an operation in Fast Healthcare Interoperability Resources (FHIR®) that allows you to ensure that a FHIR resource conforms to the base resource requirements or a specified profile. This operation ensures that the data in FHIR service has the expected attributes and values. For information on validate operation, visit [HL7 FHIR Specification](https://www.hl7.org/fhir/resource-operation-validate.html). Per specification, Mode can be specified with `$validate`, such as create and update: - `create`: FHIR service checks that the profile content is unique from the existing resources and that it's acceptable to be created as a new resource.--- `update`: Checks that the profile is an update against the nominated existing resource (that is no changes are made to the immutable fields).+- `update`: Checks that the profile is an update against the nominated existing resource (that is, no changes are made to the immutable fields). There are different ways provided for you to validate resource:-- Option 1: Validate an existing resource with validate operation.-- Option 2: Validate a new resource with validate operation.-- Option 3: Validate on resource CREATE/ UPDATE using header.+- Option 1: Validate an existing resource with the validate operation. +- Option 2: Validate a new resource with the validate operation. +- Option 3: Validate on resource CREATE or UPDATE using a header. -On the successful validation of an existing/ new resource with the validate operation, resource is not persisted into the FHIR service. Use Option 3: Validate on resource CREATE/ UPDATE using header, to persist successfully validated resource to the FHIR service. +On the successful validation of an existing or new resource with the validate operation, the resource isn't persisted into the FHIR service. Use Option 3 to successfully persist validated resources to the FHIR service. -FHIR Service will always return an `OperationOutcome` as the validation results for $validate operation. FHIR service does two step validation, once a resource is passed into $validate endpoint - the first step is a basic validation to ensure resource can be parsed. During resource parsing, individual errors need to be fixed before proceeding further to next step. Once resource is successfully parsed, full validation is conducted as second step. +The FHIR service always returns an `OperationOutcome` as the validation results for a $validate operation. Once a resource is passed into $validate endpoint, the FHIR service does two step validation. The first step is a basic validation to ensure resource can be parsed. During resource parsing, individual errors need to be fixed before proceeding to the next step. Once a resource is successfully parsed, full validation is conducted as the second step. > [!NOTE]-> Any valuesets that are to be used for validation must be uploaded to the FHIR server. This includes any Valuesets which are part of the FHIR specification, as well as any ValueSets defined in Implementation Guides. Only fully expanded Valuesets which contain a full list of all codes are supported. Any ValueSet definitions which reference external sources are not supported. +> Any valuesets that are to be used for validation must be uploaded to the FHIR server. This includes any Valuesets which are part of the FHIR specification, as well as any ValueSets defined in implementation guides. Only fully expanded Valuesets which contain a full list of all codes are supported. Any ValueSet definitions which reference external sources are not supported. ## Option 1: Validating an existing resource -To validate an existing resource, use `$validate` in a `GET` request: +To validate an existing resource, use `$validate` in a `GET` request. `GET http://<your FHIR service base URL>/{resource}/{resource ID}/$validate` For example: `GET https://myworkspace-myfhirserver.fhir.azurehealthcareapis.com/Patient/a6e11662-def8-4dde-9ebc-4429e68d130e/$validate` -In this example, you're validating the existing Patient resource `a6e11662-def8-4dde-9ebc-4429e68d130e` against the base Patient resource. If it's valid, you'll get an `OperationOutcome` such as the following code example: +In this example, you're validating the existing Patient resource `a6e11662-def8-4dde-9ebc-4429e68d130e` against the base Patient resource. If it's valid, you get an `OperationOutcome` such as the following code example. ```json { In this example, you're validating the existing Patient resource `a6e11662-def8- ] } ```-If the resource isn't valid, you'll get an error code and an error message with details on why the resource is invalid. An example `OperationOutcome` gets returned with error messages and could look like the following code example: +If the resource isn't valid, you get an error code and an error message with details on why the resource is invalid. An example `OperationOutcome` gets returned with error messages and could look like the following code example. ```json { If the resource isn't valid, you'll get an error code and an error message with In this example, the resource didn't conform to the provided Patient profile, which required a patient identifier value and gender. -If you'd like to specify a profile as a parameter, you can specify the canonical URL for the profile to validate against, such as the following example for the HL7 base profile for `heartrate`: +If you'd like to specify a profile as a parameter, you can specify the canonical URL for the profile to validate against, such as the following example for the HL7 base profile for `heartrate`. `GET https://myworkspace-myfhirserver.fhir.azurehealthcareapis.com/Observation/12345678/$validate?profile=http://hl7.org/fhir/StructureDefinition/heartrate` ## Option 2: Validating a new resource -If you'd like to validate a new resource that you're uploading to the server, you can do a `POST` request: +If you'd like to validate a new resource that you're uploading to the server, you can do a `POST` request. `POST http://<your FHIR service base URL>/{Resource}/$validate` For example: `POST https://myworkspace-myfhirserver.fhir.azurehealthcareapis.com/Patient/$validate` -This request will first validate the resource. New resource you're specifying in the request will be created after validation. -The server will always return an `OperationOutcome` as the result. +This request validates the resource. New resource you're specifying in the request will be created after validation. +The server always returns an `OperationOutcome` as the result. -## Option 3: Validate on resource CREATE/UPDATE using header +## Option 3: Validate on resource CREATE or UPDATE using a header -You can choose when you'd like to validate your resource, such as on resource `CREATE` or `UPDATE`. By default, the FHIR service is configured to opt out of validation on resource `Create/Update`. This capability allows to validate on `Create/Update`, using the `x-ms-profile-validation` header. Set `x-ms-profile-validation' to true for validation. +You can choose when you'd like to validate your resource, such as on resource `CREATE` or `UPDATE`. By default, the FHIR service is configured to opt out of validation on resource `Create/Update`. This capability allows validation on `Create/Update` using the `x-ms-profile-validation` header. Set `x-ms-profile-validation` to true for validation. > [!NOTE] You can choose when you'd like to validate your resource, such as on resource `C } } ```-To enable strict validation, use 'Prefer: handling' header with value strict. By setting this header, validation warning will be reported as an error. +To enable strict validation, use a 'Prefer: handling' header with value strict. By setting this header, a validation warning is reported as an error. ## Next steps In this article, you learned how to validate resources against profiles using `$ >[!div class="nextstepaction"] >[Supported FHIR features](fhir-features-supported.md) -FHIR® is a registered trademark of [HL7](https://hl7.org/fhir/) and is used with the permission of HL7. |
logic-apps | Monitor Health Standard Workflows | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/logic-apps/monitor-health-standard-workflows.md | After you enable Health Check, the App Service platform pings the specified work If a workflow running on an instance doesn't respond to the ping after 10 requests, the App Service platform determines that the instance is unhealthy and removes the instance for that specific logic app from the load balancer in Azure. With a two-request minimum, you can specify the required number of failed requests to determine that an instance is unhealthy. For more information about overriding default behavior, see [Configuration: Monitor App Service instances using Health Check](../app-service/monitor-instances-health-check.md#configuration). -After Health Check removes the unhealthy instance, the feature continues to ping the instance. If the instance responds with a healthy status code, inclusively ranging from 200 to 299, Health Check returns the instance to the load balancer. However, if the instance remains unhealthy for one hour, Health Check replaces the instance with a new one. For more information, see [What App Service does with health checks](../app-service/monitor-instances-health-check.md#what-app-service-does-with-health-checks). +After Health Check removes the unhealthy instance, the feature continues to ping the instance. If the instance responds with a healthy status code, inclusively ranging from 200 to 299, Health Check returns the instance to the load balancer. However, if the instance remains unhealthy for one hour, Health Check replaces the instance with a new one. For more information, see [What App Service does with health checks](../app-service/monitor-instances-health-check.md#how-health-check-works). ## Prerequisites |
service-bus-messaging | Configure Customer Managed Key | https://github.com/MicrosoftDocs/azure-docs/commits/main/articles/service-bus-messaging/configure-customer-managed-key.md | There are some caveats to the customer managed key for service side encryption. You can use Azure Key Vault (including Azure Key Vault Managed HSM) to manage your keys and audit your key usage. You can either create your own keys and store them in a key vault, or you can use the Azure Key Vault APIs to generate keys. For more information about Azure Key Vault, see [What is Azure Key Vault?](/azure/key-vault/general/overview) ## Enable customer-managed keys (Azure portal)+ To enable customer-managed keys in the Azure portal, follow these steps: 1. Navigate to your Service Bus Premium namespace.-2. On the **Settings** page of your Service Bus namespace, select **Encryption**. -3. Select the **Customer-managed key encryption at rest** as shown in the following image. -- ![Enable customer managed key](./media/configure-customer-managed-key/enable-customer-managed-key.png) +1. On the **Settings** page of your Service Bus namespace, select **Encryption**. +1. Select the **Customer-managed key encryption at rest** as shown in the following image. + ![Screenshot showing how to enable a customer managed key.](media/configure-customer-managed-key/enable-customer-managed-key.png) + > [!NOTE] > Currently you can't configure Azure Key Vault Managed HSM through the portal. After you enable customer-managed keys, you need to associate the customer manag > Using customer-managed keys with Azure Service Bus requires that the key vault have two required properties configured. They are: **Soft Delete** and **Do Not Purge**. The Soft Delete property is enabled by default when you create a new key vault in the Azure portal whereas the Purge Protection is optional so make sure to select it when creating the Key Vault. Also, if you need to enable these properties on an existing key vault, you must use either PowerShell or Azure CLI. # [Key Vault](#tab/Key-Vault)-+ 2. To turn on both soft delete and purge protection when creating a vault, use the [az keyvault create](/cli/azure/keyvault#az-keyvault-create) command.-- ```azurecli-interactive - az keyvault create --name contoso-SB-BYOK-keyvault --resource-group ContosoRG --location westus --enable-soft-delete true --enable-purge-protection true - ``` + +```azurecli-interactive +az keyvault create --name contoso-SB-BYOK-keyvault --resource-group ContosoRG --location westus --enable-soft-delete true --enable-purge-protection true +``` + 3. To add purge protection to an existing vault (that already has soft delete enabled), use the [az keyvault update](/cli/azure/keyvault#az-keyvault-update) command.-- ```azurecli-interactive - az keyvault update --name contoso-SB-BYOK-keyvault --resource-group ContosoRG --enable-purge-protection true - ``` -+ +```azurecli-interactive +az keyvault update --name contoso-SB-BYOK-keyvault --resource-group ContosoRG --enable-purge-protection true +``` + # [Key Vault Managed HSM](#tab/Key-Vault-Managed-HSM)-+ 2. To turn on both soft delete and purge protection when creating a vault, use the [az keyvault create](/cli/azure/keyvault#az-keyvault-create) command.+ +```azurecli-interactive +az keyvault create --hsm-name contoso-SB-BYOK-keyvault --resource-group ContosoRG --location westus --enable-soft-delete true --enable-purge-protection true +``` - ```azurecli-interactive - az keyvault create --hsm-name contoso-SB-BYOK-keyvault --resource-group ContosoRG --location westus --enable-soft-delete true --enable-purge-protection true - ``` 3. To add purge protection to an existing vault (that already has soft delete enabled), use the [az keyvault update](/cli/azure/keyvault#az-keyvault-update) command.-- ```azurecli-interactive - az keyvault update --hsm-name contoso-SB-BYOK-keyvault --resource-group ContosoRG --enable-purge-protection true - ``` ---4. Create keys by following these steps: - 1. To create a new key, select **Generate/Import** from the **Keys** menu under **Settings**. - ![Select Generate/Import button](./media/configure-customer-managed-key/select-generate-import.png) -- 1. Set **Options** to **Generate** and give the key a name. -- ![Create a key](./media/configure-customer-managed-key/create-key.png) +```azurecli-interactive +az keyvault update --hsm-name contoso-SB-BYOK-keyvault --resource-group ContosoRG --enable-purge-protection true +``` + - 1. You can now select this key to associate with the Service Bus namespace for encrypting from the drop-down list. +Create keys by following these steps: - ![Select key from key vault](./media/configure-customer-managed-key/select-key-from-key-vault.png) - > [!NOTE] - > For redundancy, you can add up to 3 keys. In the event that one of the keys has expired, or is not accessible, the other keys will be used for encryption. +1. To create a new key, select **Generate/Import** from the **Keys** menu under **Settings**. + + ![Screenshot showing the Generate/Import button.](./media/configure-customer-managed-key/select-generate-import.png) + +1. Set **Options** to **Generate** and give the key a name. + + ![Screenshot that shows how to name a key.](./media/configure-customer-managed-key/create-key.png) + +1. You can now select this key to associate with the Service Bus namespace for encrypting from the drop-down list. + + ![Screenshot that shows how to select a key from key vault.](./media/configure-customer-managed-key/select-key-from-key-vault.png) + + > [!NOTE] + > For redundancy, you can add up to 3 keys. In the event that one of the keys has expired, or is not accessible, the other keys will be used for encryption. - 1. Fill in the details for the key and click **Select**. This enables the encryption of the Microsoft-managed key with your key (customer-managed key). -+1. Fill in the details for the key and click **Select**. This enables the encryption of the Microsoft-managed key with your key (customer-managed key). > [!IMPORTANT] > If you are looking to use Customer managed key along with [Geo-Disaster Recovery](service-bus-geo-dr.md), please review this section. There are two types of managed identities that you can assign to a Service Bus n - **System-assigned**: You can enable a managed identity directly on a Service Bus namespace. When you enable a system-assigned managed identity, an identity is created in Microsoft Entra that's tied to the lifecycle of that Service Bus namespace. So when the namespace is deleted, Azure automatically deletes the identity for you. By design, only that Azure resource (namespace) can use this identity to request tokens from Microsoft Entra ID. - **User-assigned**: You may also create a managed identity as a standalone Azure resource, which is called user-assigned identity. You can create a user-assigned managed identity and assign it to one or more Service Bus namespaces. When you use user-assigned managed identities, the identity is managed separately from the resources that use it. They aren't tied to the lifecycle of the namespace. You can explicitly delete a user-assigned identity when you no longer need it. - For more information, see [What are managed identities for Azure resources?](../active-directory/managed-identities-azure-resources/overview.md). +For more information, see [What are managed identities for Azure resources?](../active-directory/managed-identities-azure-resources/overview.md). ## Encrypt using system-assigned identities (template)-This section shows how to do the following tasks: -1. Create a **premium** Service Bus namespace with a **managed service identity**. -2. Create a **key vault** and grant the service identity access to the key vault. -3. Update the Service Bus namespace with the key vault information (key/value). +This section shows you how to do the following tasks: ++- Create a **premium** Service Bus namespace with a **managed service identity**. +- Create a **key vault** and grant the service identity access to the key vault. +- Update the Service Bus namespace with the key vault information (key/value). ### Create a premium Service Bus namespace with managed service identity+ This section shows you how to create an Azure Service Bus namespace with managed service identity by using an Azure Resource Manager template and PowerShell. 1. Create an Azure Resource Manager template to create a Service Bus premium tier namespace with a managed service identity. Name the file: **CreateServiceBusPremiumNamespace.json**: Set-AzureRmKeyVaultAccessPolicy -VaultName {keyVaultName} -ResourceGroupName {RG ``` ### Encrypt data in Service Bus namespace with customer-managed key from key vault + You have done the following steps so far: 1. Created a premium namespace with a managed identity. In this step, you update the Service Bus namespace with key vault information. 1. Create a **premium** Service Bus namespace with the managed user-identity and the key vault information. ### Create a user-assigned identity+ Follow instructions from the [Create a user-assigned managed identity](../active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-portal.md#create-a-user-assigned-managed-identity) article to create a user-assigned identity. You can also create a user-assigned identity using [CLI](../active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-cli.md), [PowerShell](../active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-powershell.md), [Azure Resource Manager template](../active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-arm.md), and [REST](../active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-rest.md). > [!NOTE] This section gives you an example that shows you how to do the following tasks u ``` ## Use both user-assigned and system-assigned identities+ A namespace can have both system-assigned and user-assigned identities at the same time. In this case, the `type` property would be `SystemAssigned`, `UserAssigned` as shown in the following example. ```json See the following example for using the user-managed identity for the encryption ``` ## Enable infrastructure (double) encryption of data+ If you require a higher level of assurance that your data is secure, you can enable infrastructure level encryption, which is also known as Double Encryption. When infrastructure encryption is enabled, data in the Azure Service Bus is encrypted twice, once at the service level and once at the infrastructure level, using two different encryption algorithms and two different keys. Hence, infrastructure encryption of Azure Service Bus data protects against a scenario where one of the encryption algorithms or keys may be compromised. Here are more details: ## Considerations when using Geo-Disaster Recovery -### Geo-Disaster Recovery - encryption with system-assigned identities +### Encryption with system-assigned identities To enable encryption of Microsoft-managed key with a customer managed key, an [access policy](/azure/key-vault/general/secure-your-key-vault) is set up for a system-assigned managed identity on the specified Azure KeyVault. This step ensures controlled access to the Azure KeyVault from the Azure Service Bus namespace. Therefore, you need to follow these steps: - - If [Geo-Disaster Recovery](service-bus-geo-dr.md) is already enabled for the Service Bus namespace and you're looking to enable customer managed key, then - Break the pairing. - [Set up the access policy](/azure/key-vault/general/assign-access-policy-portal) for the system-assigned managed identity for both the primary and secondary namespaces to the key vault. To enable encryption of Microsoft-managed key with a customer managed key, an [a - [Set up the access policy](/azure/key-vault/general/assign-access-policy-portal) for the managed identity for the secondary namespace to the key vault. - Pair the primary and secondary namespaces. -### Geo-Disaster Recovery - encryption with user-assigned identities +### Encryption with user-assigned identities + Here are a few recommendations: -1. Create managed identity and assign Key Vault permissions to your managed identity. -2. Add the identity as a user assigned identity, and enable encryption with the identity on both namespaces. -3. Pair namespaces together +- Create managed identity and assign Key Vault permissions to your managed identity. +- Add the identity as a user assigned identity, and enable encryption with the identity on both namespaces. +- Pair namespaces together. Conditions for enabling Geo-Disaster Recovery and Encryption with User-Assigned Identities: -1. Secondary namespace must already have Encryption enabled with a User-Assigned identity if it's to be paired with a primary namespace that has Encryption enabled. -2. It isn't possible to enable Encryption on an already paired primary, even if the secondary has a User-Assigned identity associated with the namespace. +- Secondary namespace must already have Encryption enabled with a User-Assigned identity if it's to be paired with a primary namespace that has Encryption enabled. +- It isn't possible to enable Encryption on an already paired primary, even if the secondary has a User-Assigned identity associated with the namespace. ## Troubleshoot ### Symptom+ You get an error stating that the Service Bus namespace is disabled because the encryption key is no longer valid. ### Cause+ You may be using the `resource_id` or `version`, which links to a specific version of the key, which may have expired. If a specific version is provided, Service Bus uses that version of the key, even if the key is rotated. ### Resolution+ Use the [`resource__versionless_id` or `versionless_id`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#attributes-reference) instead of using `resource_id` or `version`. ## Next steps+ See the following articles:+ - [Service Bus overview](service-bus-messaging-overview.md)-- [Key Vault overview](/azure/key-vault/general/overview)+- [Key Vault overview](/azure/key-vault/general/overview) |