Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New article]: Aspire + Azure Functions integration #1706

Closed
captainsafia opened this issue Sep 30, 2024 · 2 comments · Fixed by #1867
Closed

[New article]: Aspire + Azure Functions integration #1706

captainsafia opened this issue Sep 30, 2024 · 2 comments · Fixed by #1867
Assignees
Labels
doc-idea Indicates issues that are suggestions for new topics [org][type][category] documentation Improvements or additions to documentation in-pr okr-freshness OKR: Freshness of content Pri1 High priority, do before Pri2 and Pri3 📌 seQUESTered Identifies that an issue has been imported into Quest. 📦 release-9.0 Used to track doc updates for release 9.0 of .NET Aspire.
Milestone

Comments

@captainsafia
Copy link
Member

captainsafia commented Sep 30, 2024

Proposed topic or title

Azure Functions

Location in table of contents.

/ Integrations

Reason for the article

We're gearing up to ship our initial iteration of support for Azure Functions in Aspire in .NET 9. We'll want to document this support prior to this release. There are some limitations to the support at the moment so these will need to be documented as well.

Article abstract

In this article, you learn how to use the .NET Aspire Azure Functions integration. The Aspire.Hosting.Azure.Functions library is used to:

  • Register a .NET Azure Functions project onto the Aspire App Host
  • Reference Azure Storage, Azure Event Hubs, and Azure Storage Bus resources in Azure Functions projects

Relevant searches

aspire azure functions, aspire functions


Associated WorkItem - 335639

@captainsafia captainsafia added the doc-idea Indicates issues that are suggestions for new topics [org][type][category] label Sep 30, 2024
@dotnetrepoman dotnetrepoman bot added the ⌚ Not Triaged Not triaged label Sep 30, 2024
@captainsafia
Copy link
Member Author

WRT to the location in the table of contents, Azure Functions is moreso an app type but I think the "Integrations" subsection is still the right place for this.

@IEvangelist IEvangelist self-assigned this Oct 21, 2024
@IEvangelist IEvangelist added the 📦 release-9.0 Used to track doc updates for release 9.0 of .NET Aspire. label Oct 21, 2024
@IEvangelist IEvangelist added this to the 9.0 milestone Oct 21, 2024
@captainsafia
Copy link
Member Author

Below is a brain dump of the implementation details/constraints that can be massaged into cleaner content for the docs. 😄

The integration depends on the Aspire.Hosting.Azure.Functions package. This package exposes three public APIs:

  • AddAzureFunctionsProject: This is the Functions-specific variant of the AddProject API that Aspire provides. This API returns an AzureFunctionsProjectResource which extends ProjectResource.
  • WithHostStorage: This extension method targets AzureFunctionsProjectResource and allows the user to configure the default Azure Storage resource that the Azure Functions host will use for its own bookkeeping.
  • WithReference: This extension methods targets the AzureFunctionsProjectResource and expects the provided parameter to implement the IResourceWithAzureFunctions config interface.

The AddAzureFunctionsProject extension method applies some of the same behaviors that the AddProject method does but there are some distinctions:

  • In run mode, the extension method will provision an emulated Azure Storage resource with a name like funcstorage67c6c. The last five characters of this SHA are derived from the AppHost project file path.
  • In publish mode, the extension method will provision an Azure Storage resource with the a similar name. The last five characters of the sea in this case are derived from the AppHost project name to avoid deployments from the same app trampling over each other because they were checked out into local directories. In publish mode, this storage resource is enhanced with the StorageAccountContributor role in Azure.
  • In both run and publish mode, a set of environment variables to support configuring OpenTelemetry are injected into the container.
  • In publish mode, the ASPNETCORE_URLS environment variable is configured to support listening on the non-priveliged port 8080 in the running container.
  • In run mode, the launch profile associated with the Functions project is parsed. We inspected the commandLineArgs property in this file for the --port value and use that to set the target HTTP endpoint in the Functions resource. This allows us to align with the configuration that Visual Studio uses when it launches the Functions host on our behalf.

The WithHostStorage extension method allows the user to modify the default storage account that the Azure Functions host uses. It must be invoked by chaining onto the AddAzureFunctionsProject call, like so:

var hostStorage = builder.AddAzureStorage("my-custom-storage");

builder.AddAzureFunctionsProject<Project>("funcapp")
  .WithHostStorage(hostStorage);

Note: since the StorageAccountContributor role is required for deployed instances, it is up to the user to manually configure this role into their resource when operating in publish mode. This role assignment is included automatically for the implicitly generated host storage.

The Azure Functions Host doesn't support the same connection string key/value format that Aspire uses. As such, it's a requirement that a different format of connection key name be injected by Aspire resources for consumption in Azure Functions project. This behavior is supported by the IResourceWithAzureFunctionsConfig interface that is currently implemented on the following resource types:

  • Azure Service Bus
  • Azure Storage Queues
  • Azure Storage Blobs
  • Azure Event Hubs

Resources that implement this interface can be consumed by Azure Functions triggers. Implementing this interface isn't a requirement if the user wants to use the standard Aspire client integrations in their Functions app though. You can still resolve the Aspire-configured injected resources from the applications DI container by leveraging the client integrations. Because this interface is required to support triggers, that means the implementation currently only supports the following triggers:

  • Azure Service Bus trigger
  • Azure Storage Queues trigger
  • Azure Storage Blobs trigger
  • Azure Event Hubs trigger
  • Timer trigger (only needs host storage)
  • HTTP trigger (no resource dependencies)

So, that's on the APIs shipped out of the Aspire packages for this. This feature also takes a dependency on some components in Functions lands. Specifically, we're looking at:

  • A minimum version of Azure Functions Core Tools that supports OpenTelemetry (TBD once all this flows through)
  • Microsoft.Azure.Functions.Worker.Sdk 2.0.0-preview2 and above to support dotnet run and azd publish for Functions projects
  • Microsoft.Azure.Functions.Worker 2.0.0-preview2 and above to support the IHostApplicationBuilder implementation in FunctionsApplicationBuilder
  • Microsoft.Azure.Functions.Http.AspNetCore 2.0.0-preview2 and above to support the HTTP trigger-supporting APIs that target IHostApplicationBuilder implementation

Alongside these minimum required versions, there's also constraints on what types of Functions projects can be Aspirified. We currently only support:

  • .NET workers
  • Targeting .NET 8 and above
  • On the isolated worker model

When it comes to deployment, we're currently only supporting deploying to plain ol' containers on ACA by building on top of the SDK container publish function built into Microsoft.Azure.Functions.Worker.Sdk. This means that deployments to this target can't take advantage of any KEDA-based autoscaling on the deployment.

Speaking of deployment, if users would like HTTP triggers to be publicly accessible, they will need to call the WithExternalHttpEndpoints API on the AzureFunctionsProjectResource to get publicly accessible endpoints on the deployment target.

@IEvangelist IEvangelist added documentation Improvements or additions to documentation 🗺️ reQUEST Triggers an issue to be imported into Quest. Pri1 High priority, do before Pri2 and Pri3 okr-freshness OKR: Freshness of content and removed ⌚ Not Triaged Not triaged labels Oct 29, 2024
@sequestor sequestor bot added 📌 seQUESTered Identifies that an issue has been imported into Quest. and removed 🗺️ reQUEST Triggers an issue to be imported into Quest. labels Oct 30, 2024
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in dotnet/docs November 2024 sprint Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-idea Indicates issues that are suggestions for new topics [org][type][category] documentation Improvements or additions to documentation in-pr okr-freshness OKR: Freshness of content Pri1 High priority, do before Pri2 and Pri3 📌 seQUESTered Identifies that an issue has been imported into Quest. 📦 release-9.0 Used to track doc updates for release 9.0 of .NET Aspire.
Projects
No open projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

2 participants