Skip to content

Commit ea63211

Browse files
committed
reorganizations and tweaks
1 parent fb69a7f commit ea63211

File tree

2 files changed

+148
-151
lines changed

2 files changed

+148
-151
lines changed

articles/azure-functions/durable/durable-functions-mssql-container-apps-hosting.md

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ms.date: 05/06/2025
1010
This article shows how to host a Durable Functions app in Azure Container Apps. While Durable Functions supports several [storage providers](./durable-functions-storage-providers.md) or *backends*, autoscaling of the app is only available when using the Microsoft SQL (MSSQL) backend. If another backends is used, you need to [manually set up scaling](../functions-container-apps-hosting.md#event-driven-scaling) today.
1111

1212
## Prerequisites
13+
1314
+ [Visual Studio Code](https://code.visualstudio.com/download) installed.
1415

1516
+ [.NET 8.0 SDK](https://dotnet.microsoft.com/download).
@@ -25,10 +26,12 @@ This article shows how to host a Durable Functions app in Azure Container Apps.
2526
+ An HTTP test tool that keeps your data secure. For more information, see [HTTP test tools](../functions-develop-local.md#http-test-tools).
2627

2728
## Create a local Durable Functions project
29+
2830
In Visual Studio Code, [create a .NET isolated Durable Functions project](./quickstart-mssql.md) configured to use the MSSQL backend. Follow the article until the [Test locally](./quickstart-mssql.md#test-locally) section and make sure you can run the app locally before going to the next step.
2931

3032
### Add Docker related files
31-
1. In the project root directory, add a *Dockerfile* with the following content:
33+
34+
1. In the project root directory, add a _Dockerfile_ with the following content:
3235
```
3336
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS installer-env
3437
@@ -45,14 +48,14 @@ In Visual Studio Code, [create a .NET isolated Durable Functions project](./quic
4548
4649
COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]
4750
```
48-
49-
1. Add a *.dockerignore* file with the following content:
51+
1. Add a _.dockerignore_ file with the following content:
5052
```
5153
local.settings.json
5254
```
5355
5456
## Build the container image
55-
The Dockerfile in the project root describes the minimum required environment to run the function app in a container. You can find the complete list of supported base images for Azure Functions documented as Host images in the prerequisites section or can be found in the [Azure Functions Base by Microsoft | Docker Hub](https://hub.docker.com/_/microsoft-azure-functions-base)
57+
58+
The Dockerfile in the project root describes the minimum required environment to run the function app in a container. The complete list of supported base images for Azure Functions is documented above as Host images in the pre-requisites section or can be found in the [Azure Functions Base by Microsoft | Docker Hub](https://hub.docker.com/_/microsoft-azure-functions-base)
5659
5760
1. Start the Docker daemon.
5861
@@ -74,44 +77,46 @@ The Dockerfile in the project root describes the minimum required environment to
7477
```bash
7578
docker push $dockerId/$imageName:$imageVersion
7679
```
77-
78-
Depending on network speed, pushing the image the first time might take a few minutes (pushing subsequent changes is faster). While you're waiting, proceed to the next section to create Azure resources in another terminal.
80+
Depending on network speed, pushing the image the first time might take a few minutes (pushing subsequent changes is much faster). While you're waiting, proceed to the next section to create Azure resources in another terminal.
7981
8082
## Create Azure resources
81-
The following instructions guide you through creating these Azure resources:
83+
84+
The following instructions will guide you through creating these Azure resources:
8285
- Azure resource group: For convenient cleanup later, all resources are created in this group.
8386
- Azure Container App environment: Environment where container app is hosted.
8487
- Azure Container App: Image containing the Durable Functions app is deployed to this app.
8588
- Azure Storage Account: Required by the function app to store app related data such as application code.
86-
- A virtual network: Required when running container apps.
89+
- A virtual network: Required by the Azure Container App environment.
8790
88-
### Initial setup
89-
1. Log in to your Azure subscription:
90-
```azurecli
91-
az login
92-
az account set -subscription | -s <subscription_name>
93-
```
91+
### Initial set up
9492
95-
1. Run the required commands to setup the Azure Container Apps CLI extension:
96-
```azurecli
97-
az upgrade
93+
1. Login to your Azure subscription:
94+
```azurecli
95+
az login
9896
99-
az extension add --name containerapp --upgrade
97+
az account set -subscription | -s <subscription_name>
98+
```
10099
101-
az provider register --namespace Microsoft.App
100+
1. Run the required commands to set up the Azure Container Apps CLI extension:
101+
```azurecli
102+
az upgrade
102103
103-
az provider register --namespace Microsoft.OperationalInsights
104-
```
104+
az extension add --name containerapp --upgrade
105+
106+
az provider register --namespace Microsoft.App
107+
108+
az provider register --namespace Microsoft.OperationalInsights
109+
```
110+
111+
### Create container app and related resources
105112
106-
### Create app related resources
107113
A workload profile determines the amount of compute and memory resources available to the container apps deployed in an environment. Create a Consumption workload profile for scale-to-zero support and pay-per-use. Learn more about [workload profiles](../functions-container-apps-hosting.md#hosting-and-workload-profiles).
108114
109115
```azurecli
110116
location=<REGION>
111117
resourceGroup=<RESOURCE_GROUP_NAME>
112118
storage=<STORAGE_NAME>
113119
containerAppEnv=<CONTAINER_APP_ENVIRONMNET_NAME>
114-
storageSku=Standard_LRS
115120
functionApp=<APP_NAME>
116121
vnet=<VNET_NAME>
117122
@@ -161,21 +166,24 @@ https://<APP_NAME>.victoriouswave-3866c33e.<REGION>.azurecontainerapps.io/
161166
```
162167

163168
### Create databases
164-
You need to create an Azure Storage account for storing app related data:
169+
170+
Create an Azure Storage account as required by the function app:
165171

166172
```azurecli
167-
az storage account create --name $storage --location $location --resource-group $resourceGroup --sku $storageSku
173+
az storage account create --name $storage --location $location --resource-group $resourceGroup --sku Standard_LRS
168174
```
169175

170-
Your Durable Functions also needs an Azure SQL Database as its storage backend. This backend is where state information is persisted as your orchestrations run. In the Azure portal, you can [create an Azure SQL database](/azure/azure-sql/database/single-database-create-quickstart). During creation:
171-
- Enable Azure services and resources to access this server (under **Networking**)
172-
- Set the value for **Database collation** (under **Additional settings**) to `Latin1_General_100_BIN2_UTF8`.
176+
Your Durable Functions also needs an Azure SQL Database as its storage backend. This is where state information is persisted as your orchestrations run. In the Azure portal, you can [create an Azure SQL database](/azure/azure-sql/database/single-database-create-quickstart). During creation:
177+
- Enable Azure services and resources to access this server (under _Networking_)
178+
- Set the value for _Database collation_ (under _Additional settings_) to `Latin1_General_100_BIN2_UTF8`.
173179

174180
> [!NOTE]
175181
> Enabling the **Allow Azure services and resources to access this server** setting isn't a recommended security practice for production scenarios. Real applications should implement more secure approaches, such as stronger firewall restrictions or virtual network configurations.
176182
183+
177184
### Configure identity-based authentication
178-
Managed identities make your app more secure by eliminating secrets from your app, such as credentials in the connection strings. You can choose between [system-assigned and user-assigned managed identity](/entra/identity/managed-identities-azure-resources/overview). This article demonstrates setting up user-assigned managed identity, which is the recommended option as it isn't tied to the app lifecycle.
185+
186+
Managed identities make your app more secure by eliminating secrets from your app, such as credentials in the connection strings. You can choose between [system-assigned and user-assigned managed identity](/entra/identity/managed-identities-azure-resources/overview). This article demonstrates setting up user-assigned managed identity, which is the recommended option as it is not tied to the app lifecycle.
179187

180188
1. Create identity and assign it to the container app:
181189
```azurecli
@@ -187,9 +195,6 @@ Managed identities make your app more secure by eliminating secrets from your ap
187195
echo "Creating $identity"
188196
az identity create -g $resourceGroup -n $identity --location "$location"
189197
190-
# Construct the identity resource ID
191-
resourceId="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$identity"
192-
193198
# Assign the identity to the container app
194199
echo "Assigning $identity to app"
195200
az containerapp identity assign --resource-group $resourceGroup --name $functionApp --user-assigned $identity
@@ -199,7 +204,7 @@ Managed identities make your app more secure by eliminating secrets from your ap
199204
```
200205
# Set the scope of the access
201206
scope="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.Storage/storageAccounts/$storage"
202-
207+
203208
# Get the identity's ClientId
204209
clientId=$(az identity show --name $identity --resource-group $resourceGroup --query 'clientId' --output tsv)
205210
@@ -208,9 +213,12 @@ Managed identities make your app more secure by eliminating secrets from your ap
208213
az role assignment create --assignee "$clientId" --role "Storage Blob Data Owner" --scope "$scope"
209214
```
210215
216+
> [!NOTE]
217+
> Authenticating to the MSSQL database using managed identity isn't supported when hosting a Durable Functions app in Azure Container Apps. Use connection string for now.
218+
211219
### Set up app settings
212-
1. Start by storing the SQL database's connection string as a [secret](../../container-apps/manage-secrets.md) in the container app. Find the connection string by going to the SQL database resource on Azure portal, navigating to the **Settings** tab, then clicking on **Connection strings**:
213220
221+
1. Find the connection string by going to the SQL database resource on Azure portal, navigating to the **Settings** tab, then clicking on **Connection strings**:
214222
:::image type="content" source="./media/quickstart-mssql/mssql-azure-db-connection-string.png" alt-text="Screenshot showing database connection string.":::
215223
216224
The connection string should have this format:
@@ -223,14 +231,10 @@ Managed identities make your app more secure by eliminating secrets from your ap
223231
connStr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$username;Password=$password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
224232
```
225233
226-
> [!NOTE]
227-
> Authenticating to the MSSQL database using managed identity isn't yet supported when hosting a Durable Functions app in Azure Container Apps. Only connection string is supported today.
228-
>
229-
> If you forget the password from the previous database creation step, you can reset it on the SQL server resource:
230-
> :::image type="content" source="./media/quickstart-mssql/mssql-azure-reset-pass-2.png" alt-text="Screenshot showing reset password button.":::
231-
232-
1. Store the connection string as a secret:
234+
If you forget the password from the previous database creation step, you can reset it on the SQL server resource:
235+
:::image type="content" source="./media/quickstart-mssql/mssql-azure-reset-pass-2.png" alt-text="Screenshot showing reset password button.":::
233236
237+
1. Store the SQL database's connection string as a [secret](../../container-apps/manage-secrets.md) called _sqldbconnection_ in the container app:
234238
```azurecli
235239
az containerapp create \
236240
--resource-group $resourceGroup \
@@ -240,12 +244,12 @@ Managed identities make your app more secure by eliminating secrets from your ap
240244
--secrets sqldbconnection=$connStr
241245
```
242246
243-
1. Add these settings required by the app:
244-
- `AzureWebJobsStorage__accountName`: <STORAGE_NAME>
245-
- `AzureWebJobsStorage__clientId`: <IDENTITY_CLIENT_ID>
246-
- `AzureWebJobsStorage__credential`: <MANAGED_IDENTITY>
247-
- `SQLDB_Connection`: <SQLDB_CONNECTION_STRING>
248-
- `FUNCTIONS_WORKER_RUNTIME`: <APP_LANGUAGE>
247+
1. Add these settings to the app:
248+
- `AzureWebJobsStorage__accountName`: Azure Storage account name
249+
- `AzureWebJobsStorage__clientId`: ClientId of the managed identity
250+
- `AzureWebJobsStorage__credential`: Credential type, which is _managedidentity_
251+
- `SQLDB_Connection`: Reference the SQL database connection string stored as a secret
252+
- `FUNCTIONS_WORKER_RUNTIME`: Programming language of the app
249253
250254
```azurecli
251255
az containerapp update \
@@ -267,8 +271,7 @@ Managed identities make your app more secure by eliminating secrets from your ap
267271
268272
The response is the HTTP function's initial result. It lets you know that the Durable Functions orchestration started successfully. It doesn't yet display the end result of the orchestration. The response includes a few useful URLs.
269273
270-
1. Copy the URL value for `statusQueryGetUri`, paste it in your browser's address bar, and execute the request. Alternatively, you can also continue to use the HTTP test tool to issue the `GET` request.
271-
274+
1. Copy the URL value for `statusQueryGetUri`, paste it in your browser's address bar, and execute the request. Alternatively, you can also continue to use the HTTP test tool to issue the GET request.
272275
The request queries the orchestration instance for the status. You should see that the instance finished and that it includes the outputs or results of the Durable Functions app like in this example:
273276
274277
```json
@@ -284,7 +287,6 @@ Managed identities make your app more secure by eliminating secrets from your ap
284287
}
285288
```
286289
287-
288290
## Next steps
289291
290292
Learn more about:

0 commit comments

Comments
 (0)