Skip to content

Commit 0de5cdb

Browse files
Adding .NET Aspire content
1 parent 90b6e64 commit 0de5cdb

6 files changed

+169
-25
lines changed

articles/azure-functions/dotnet-isolated-in-process-differences.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Use the following table to compare feature and functional differences between th
4343
| Cold start times<sup>2</sup> | [Configurable optimizations](./dotnet-isolated-process-guide.md#performance-optimizations) | Optimized |
4444
| ReadyToRun | [Supported](dotnet-isolated-process-guide.md#readytorun) | [Supported](functions-dotnet-class-library.md#readytorun) |
4545
| [Flex Consumption] | [Supported](./flex-consumption-plan.md#supported-language-stack-versions) | Not supported |
46+
| .NET Aspire | [Preview](dotnet-isolated-process-guide.md#net-aspire-preview) | Not supported |
4647

4748
<sup>1</sup> When you need to interact with a service using parameters determined at runtime, using the corresponding service SDKs directly is recommended over using imperative bindings. The SDKs are less verbose, cover more scenarios, and have advantages for error handling and debugging purposes. This recommendation applies to both models.
4849

articles/azure-functions/dotnet-isolated-process-guide.md

Lines changed: 148 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,19 @@ var builder = FunctionsApplication.CreateBuilder(args);
127127
builder.Services
128128
.AddApplicationInsightsTelemetryWorkerService()
129129
.ConfigureFunctionsApplicationInsights()
130-
.AddSingleton<IHttpResponderService, DefaultHttpResponderService>()
131-
.Configure<LoggerFilterOptions>(options =>
130+
.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
131+
132+
builder.Logging.Services.Configure<LoggerFilterOptions>(options =>
133+
{
134+
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
135+
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/azure/azure-monitor/app/worker-service#ilogger-logs
136+
LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
137+
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
138+
if (defaultRule is not null)
132139
{
133-
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
134-
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/azure/azure-monitor/app/worker-service#ilogger-logs
135-
LoggerFilterRule toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
136-
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
137-
138-
if (toRemove is not null)
139-
{
140-
options.Rules.Remove(toRemove);
141-
}
142-
});
140+
options.Rules.Remove(defaultRule);
141+
}
142+
});
143143

144144
var host = builder.Build();
145145
```
@@ -837,7 +837,11 @@ When you use an `IHostApplicationBuilder`, by default, exceptions thrown by your
837837

838838
### Application Insights
839839

840-
You can configure your isolated process application to emit logs directly to [Application Insights](/azure/azure-monitor/app/app-insights-overview?tabs=net). This behavior replaces the default behavior of [relaying logs through the host](./configure-monitoring.md#custom-application-logs), and is recommended because it gives you control over how those logs are emitted.
840+
You can configure your isolated process application to emit logs directly to [Application Insights](/azure/azure-monitor/app/app-insights-overview?tabs=net). This behavior replaces the default behavior of [relaying logs through the host](./configure-monitoring.md#custom-application-logs). Unless you are using .NET Aspire, configuring direct Application Insights integration is recommended because it gives you control over how those logs are emitted.
841+
842+
Application Insights integration is not enabled by default in all setup experiences. Some templates will create Functions projects with the necessary packages and startup code commented out. If you want to use Application Insights integration, you can uncomment these lines in `Program.cs` and the project's `.csproj` file. The instructions in the rest of this section also describe how to enable the integration.
843+
844+
If your project is part of a [.NET Aspire orchestration](#net-aspire-preview), it uses OpenTelemetry for monitoring instead. You should not enable direct Application Insights integration within .NET Aspire projects. Instead, configure the Azure Monitor OpenTelemetry exporter as part of the [service defaults project](/dotnet/aspire/fundamentals/service-defaults#opentelemetry-configuration). If your Functions project uses Application Insights integration in a .NET Aspire context, the application will error on startup.
841845

842846
#### Install packages
843847

@@ -1130,6 +1134,128 @@ There are a few requirements for running .NET functions in the isolated worker m
11301134

11311135
When you create your function app in Azure using the methods in the previous section, these required settings are added for you. When you create these resources [by using ARM templates or Bicep files for automation](functions-infrastructure-as-code.md), you must make sure to set them in the template.
11321136

1137+
## .NET Aspire (Preview)
1138+
1139+
[.NET Aspire](/dotnet/aspire/get-started/aspire-overview) is an opinionated stack that simplifies development of distributed applications in the cloud. You can enlist .NET 8 and .NET 9 isolated worker model projects in Aspire 9.0 orchestrations using preview support. The section outlines the core requirements for enlistment.
1140+
1141+
This integration requires specific setup:
1142+
1143+
- Use [Aspire 9.0 or later](/dotnet/aspire/fundamentals/setup-tooling) and the [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0). Aspire 9.0 supports the .NET 8 and .NET 9 frameworks.
1144+
- If you use Visual Studio, update to version 17.12 or later. You must also have the latest version of the Functions tools for Visual Studio. To check for updates, navigate to **Tools** > **Options**, choose **Azure Functions** under **Projects and Solutions**. Select **Check for updates** and install updates as prompted.
1145+
- In the [Aspire app host project](/dotnet/aspire/fundamentals/app-host-overview):
1146+
- You must reference [Aspire.Hosting.Azure.Functions].
1147+
- You must have a project reference to your Functions project.
1148+
- In the app host's `Program.cs`, you must also include the project by calling `AddAzureFunctionsProject<TProject>()` on your `IDistributedApplicationBuilder`. This method is used instead of the `AddProject<TProject>()` that you use for other project types. If you just use `AddProject<TProject>()`, the Functions project will not start properly.
1149+
- In the Functions project:
1150+
- You must reference the [2.x versions](#version-2x-preview) of [Microsoft.Azure.Functions.Worker] and [Microsoft.Azure.Functions.Worker.Sdk]. You must also update any references you have to `Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore` to the 2.x version as well.
1151+
- Your `Program.cs` should use the `IHostApplicationBuilder` version of [host instance startup](#start-up-and-configuration).
1152+
- If you want to use your Aspire service defaults, you should include a project reference to the service defaults project. Before building your `IHostApplicationBuilder` in `Program.cs`, you should also include a call to `builder.AddServiceDefaults()`.
1153+
- You shouldn't keep configuration in `local.settings.json`, aside from the `FUNCTIONS_WORKER_RUNTIME` setting, which should remain "dotnet-isolated". Other configuration should be set through the app host project.
1154+
- You should remove any direct Application Insights integrations. Monitoring in Aspire is instead handled through its OpenTelemetry support.
1155+
1156+
The following example shows a minimal `Program.cs` for an App Host project:
1157+
1158+
```csharp
1159+
var builder = DistributedApplication.CreateBuilder(args);
1160+
1161+
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");
1162+
1163+
builder.Build().Run();
1164+
```
1165+
1166+
The following example shows a minimal `Program.cs` for a Functions project used in Aspire:
1167+
1168+
```csharp
1169+
using Microsoft.Azure.Functions.Worker;
1170+
using Microsoft.Azure.Functions.Worker.Builder;
1171+
using Microsoft.Extensions.DependencyInjection;
1172+
using Microsoft.Extensions.Hosting;
1173+
1174+
var builder = FunctionsApplication.CreateBuilder(args);
1175+
1176+
builder.AddServiceDefaults();
1177+
1178+
builder.ConfigureFunctionsWebApplication();
1179+
1180+
builder.Build().Run();
1181+
```
1182+
1183+
This does not include the default Application Insights configuration that you see in many of the other `Program.cs` examples in this article. Instead, Aspire's OpenTelemetry integration is configured through the `builder.AddServiceDefaults()` call.
1184+
1185+
### Considerations and best practices for .NET Aspire integration
1186+
1187+
Consider the following points when evaluating .NET Aspire with Azure Functions:
1188+
1189+
- Support for Azure Functions with .NET Aspire is currently in preview. During the preview period, when you publish the Aspire solution to Azure, Functions projects are deployed as Azure Container Apps resources without event-driven scaling. Azure Functions support is not available for apps deployed in this mode.
1190+
- Trigger and binding configuration through Aspire is currently limited to specific integrations. See [Connection configuration with Aspire](#connection-configuration-with-aspire) for details.
1191+
- Your `Program.cs` should use the `IHostApplicationBuilder` version of [host instance startup](#start-up-and-configuration). This allows you to call `builder.AddServiceDefaults()` to add [.NET Aspire service defaults](/dotnet/aspire/fundamentals/service-defaults) to your Functions project.
1192+
- Aspire uses OpenTelemetry for monitoring. You can configure Aspire to export telemetry to Azure Monitor through the service defaults project. In many other Azure Functions contexts, you might include direct integration with Application Insights by registering the telemetry worker service. This is not recommended in Aspire and can lead to runtime errors with version 2.22.0 of `Microsoft.ApplicationInsights.WorkerService`. You should remove any direct Application Insights integrations from your Functions project when using Aspire.
1193+
- For Functions projects enlisted into an Aspire orchestration, most of the application configuration should come from the Aspire app host project. You should typically avoid setting things in `local.settings.json`, other than the `FUNCTIONS_WORKER_RUNTIME` setting. If the same environment variable is set by `local.settings.json` and Aspire, the system uses the Aspire version.
1194+
- Do not configure the Storage emulator for any connections in `local.settings.json`. Many Functions starter templates include the emulator as a default for `AzureWebJobsStorage`. However, emulator configuration can prompt some IDEs to start a version of the emulator that can conflict with the version that Aspire uses.
1195+
1196+
### Connection configuration with Aspire
1197+
1198+
Azure Functions requires a [host storage connection (`AzureWebJobsStorage`)](./functions-reference.md#connecting-to-host-storage-with-an-identity) for several of its core behaviors. When you call `AddAzureFunctionsProject<TProject>()` in your app host project, a default `AzureWebJobsStorage` connection is created and provided to the Functions project. This default connection uses the Storage emulator for local development runs and automatically provisions a storage account when deployed. For additional control, you can replace this connection by calling `.WithHostStorage()` on the Functions project resource.
1199+
1200+
The following example shows a minimal `Program.cs` for an app host project that replaces the host storage:
1201+
1202+
```csharp
1203+
var builder = DistributedApplication.CreateBuilder(args);
1204+
1205+
var myHostStorage = builder.AddAzureStorage("myHostStorage");
1206+
1207+
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
1208+
.WithHostStorage(myHostStorage);
1209+
1210+
builder.Build().Run();
1211+
```
1212+
1213+
> [!NOTE]
1214+
> When Aspire provisions the host storage in publish mode, it defaults to creating role assignments for the [Storage Account Contributor], [Storage Blob Data Contributor], [Storage Queue Data Contributor], and [Storage Table Data Contributor] roles.
1215+
1216+
Your triggers and bindings reference connections by name. Some Aspire integrations are enabled to provide these through a call to `WithReference()` on the project resource:
1217+
1218+
| Aspire integration | Notes |
1219+
|-----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1220+
| [Azure Blobs](/dotnet/aspire/storage/azure-storage-blobs-integration) | When Aspire provisions the resource, it defaults to creating role assignments for the [Storage Blob Data Contributor], [Storage Queue Data Contributor], and [Storage Table Data Contributor] roles. |
1221+
| [Azure Queues](/dotnet/aspire/storage/azure-storage-queues-integration) | When Aspire provisions the resource, it defaults to creating role assignments for the [Storage Blob Data Contributor], [Storage Queue Data Contributor], and [Storage Table Data Contributor] roles. |
1222+
| [Azure Event Hubs](/dotnet/aspire/messaging/azure-event-hubs-integration) | When Aspire provisions the resource, it defaults to creating a role assignment using the [Azure Event Hubs Data Owner] role. |
1223+
| [Azure Service Bus](/dotnet/aspire/messaging/azure-service-bus-integration) | When Aspire provisions the resource, it defaults to creating a role assignment using the [Azure Service Bus Data Owner] role. |
1224+
1225+
The following example shows a minimal `Program.cs` for an app host project that configures a queue trigger. In this example, the corresponding queue trigger has its `Connection` property set to "MyQueueTriggerConnection".
1226+
1227+
```csharp
1228+
var builder = DistributedApplication.CreateBuilder(args);
1229+
1230+
var myAppStorage = builder.AddAzureStorage("myAppStorage").RunAsEmulator();
1231+
var queues = myAppStorage.AddQueues("queues");
1232+
1233+
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
1234+
.WithReference(queues, "MyQueueTriggerConnection");
1235+
1236+
builder.Build().Run();
1237+
```
1238+
1239+
For other integrations, calls to `WithReference` set the configuration in a different way, making it available to [Aspire client integrations](/dotnet/aspire/fundamentals/integrations-overview#client-integrations), but not to triggers and bindings. For these integrations, you should call `WithEnvironment()` to pass the connection information for the trigger or binding to resolve. The following example shows how to set the environment variable "MyBindingConnection" for a resource that exposes a connection string expression:
1240+
1241+
```csharp
1242+
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
1243+
.WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);
1244+
```
1245+
1246+
You can configure both `WithReference()` and `WithEnvironment()` if you want a connection to be used both by Aspire client integrations and the triggers and bindings system.
1247+
1248+
For some resources, the structure of a connection might be different between when you run it locally and when you publish it to azure. In the previous example, `otherIntegration` could be a resource that runs as an emulator, so `ConnectionStringExpression` would return an emulator connection string. However, when the resource is published, Aspire might set up an identity-based connection, and `ConnectionStringExpression` would return the service's URI. In this case, to set up [identity based connections for Azure Functions](./functions-reference.md#configure-an-identity-based-connection), you might need to provide a different environment variable name. The following example uses `builder.ExecutionContext.IsPublishMode` to conditionally add the necessary suffix:
1249+
1250+
```csharp
1251+
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
1252+
.WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);
1253+
```
1254+
1255+
Depending on your scenario, you may also need to adjust the permissions that will be assigned for an identity-based connection. You can use the [`ConfigureConstruct<T>()` method](/dotnet/api/aspire.hosting.azureconstructresourceextensions.configureconstruct) to customize how Aspire configures infrastructure when it publishes your project.
1256+
1257+
Consult each binding's [reference pages](./functions-triggers-bindings.md#supported-bindings) for details on the connection formats it supports and the permissions those formats require.
1258+
11331259
## Debugging
11341260

11351261
When running locally using Visual Studio or Visual Studio Code, you're able to debug your .NET isolated worker project as normal. However, there are two debugging scenarios that don't work as expected.
@@ -1300,6 +1426,15 @@ Keep these considerations in mind when using Functions with preview versions of
13001426
[Microsoft.Azure.Functions.Worker]: https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker/
13011427
[Microsoft.Azure.Functions.Worker.Sdk]: https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Sdk/
13021428
1429+
[Aspire.Hosting.Azure.Functions]: https://www.nuget.org/packages/Aspire.Hosting.Azure.Functions
1430+
1431+
[Storage Account Contributor]: ../role-based-access-control/built-in-roles.md#storage-account-contributor
1432+
[Storage Blob Data Contributor]: ../role-based-access-control/built-in-roles.md#storage-blob-data-contributor
1433+
[Storage Queue Data Contributor]: ../role-based-access-control/built-in-roles.md#storage-queue-data-contributor
1434+
[Storage Table Data Contributor]: ../role-based-access-control/built-in-roles.md#storage-table-data-contributor
1435+
[Azure Event Hubs Data Owner]: ../role-based-access-control/built-in-roles.md#azure-event-hubs-data-owner
1436+
[Azure Service Bus Data Owner]: ../role-based-access-control/built-in-roles.md#azure-service-bus-data-owner
1437+
13031438
[HostBuilder]: /dotnet/api/microsoft.extensions.hosting.hostbuilder
13041439
[IHostApplicationBuilder]: /dotnet/api/microsoft.extensions.hosting.ihostapplicationbuilder
13051440
[IHost]: /dotnet/api/microsoft.extensions.hosting.ihost

articles/azure-functions/functions-bindings-service-bus.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ Functions 1.x apps automatically have a reference the [Microsoft.Azure.WebJobs](
6767

6868
This version allows you to bind to types from [Azure.Messaging.ServiceBus](/dotnet/api/azure.messaging.servicebus).
6969

70+
This version supports configuration of triggers and bindings through [.NET Aspire integration](./dotnet-isolated-process-guide.md#connection-configuration-with-aspire).
71+
7072
Add the extension to your project by installing the [NuGet package](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.ServiceBus), version 5.x.
7173

7274
# [Functions 2.x+](#tab/functionsv2/isolated-process)

articles/azure-functions/functions-bindings-storage-blob.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ Functions 1.x apps automatically have a reference the [Microsoft.Azure.WebJobs](
7878

7979
This version allows you to bind to types from [Azure.Storage.Blobs](/dotnet/api/azure.storage.blobs). Learn more about how these new types are different from `WindowsAzure.Storage` and `Microsoft.Azure.Storage` and how to migrate to them from the [Azure.Storage.Blobs Migration Guide](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/storage/Azure.Storage.Blobs/AzureStorageNetMigrationV12.md).
8080

81+
This version supports configuration of triggers and bindings through [.NET Aspire integration](./dotnet-isolated-process-guide.md#connection-configuration-with-aspire).
82+
8183
Add the extension to your project by installing the [Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs NuGet package], version 5.x or later.
8284

8385
Using the .NET CLI:

0 commit comments

Comments
 (0)