Teilen über


Azure-Funktionen mit Aspire

Aspire ist ein vorgabebestimmter Stack, der die Entwicklung verteilter Systeme in Cloud-Systemen vereinfacht. Mit der Integration von Aspire mit Azure Functions können Sie ein Azure Functions .NET-Projekt als Teil des Aspire-App-Hosts entwickeln, debuggen und koordinieren.

Voraussetzungen

Richten Sie Ihre Entwicklungsumgebung für die Verwendung von Azure Functions mit Aspire ein:

Wenn Sie Visual Studio verwenden, aktualisieren Sie auf Version 17.12 oder höher. Sie müssen auch über die neueste Version der Azure Functions-Tools für Visual Studio verfügen. So suchen Sie nach Updates:

  1. Wechseln Sie zu Tools>Optionen.
  2. Wählen Sie unter "Projekte und Lösungen" die Option "Azure Functions" aus.
  3. Wählen Sie Nach Updates suchen aus, und installieren Sie Updates, wenn Sie dazu aufgefordert werden.

Projektmappenstruktur

Eine Lösung, die Azure Functions und Aspire verwendet, verfügt über mehrere Projekte, einschließlich eines App-Hostprojekts und eines oder mehrerer Funktionen-Projekte.

Das App-Hostprojekt ist der Einstiegspunkt für Ihre Anwendung. Es koordiniert die Einrichtung der Komponenten Ihrer Anwendung, einschließlich des Functions-Projekts.

Die Lösung enthält in der Regel auch ein Dienststandardprojekt . Dieses Projekt stellt eine Reihe von Standarddiensten und Konfigurationen bereit, die für projekte in Ihrer Anwendung verwendet werden sollen.

App-Hostprojekt

Um die Integration erfolgreich zu konfigurieren, stellen Sie sicher, dass das App-Hostprojekt die folgenden Anforderungen erfüllt:

  • Das App-Hostprojekt muss auf Aspire.Hosting.Azure.Functions verweisen. Dieses Paket definiert die erforderliche Logik für die Integration.
  • Das App-Hostprojekt muss über einen Projektverweis für jedes Funktionen-Projekt verfügen, das Sie in die Orchestrierung einbeziehen möchten.
  • In der Datei des App-Hosts AppHost.cs müssen Sie das Projekt einschließen, indem Sie AddAzureFunctionsProject<TProject>() auf Ihrer IDistributedApplicationBuilder Instanz aufrufen. Sie verwenden diese Methode anstelle der AddProject<TProject>() Methode, die Sie für andere Projekttypen in Aspire verwenden. Wenn Sie AddProject<TProject>() verwenden, kann das Functions-Projekt nicht ordnungsgemäß gestartet werden.

Das folgende Beispiel zeigt eine minimale AppHost.cs Datei für ein App-Hostprojekt:

var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");

builder.Build().Run();

Azure Functions-Projekt

Um die Integration erfolgreich zu konfigurieren, stellen Sie sicher, dass das Azure Functions-Projekt die folgenden Anforderungen erfüllt:

Das folgende Beispiel zeigt eine minimale Program.cs Datei für ein in Aspire verwendetes Functions-Projekt:

using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.ConfigureFunctionsWebApplication();

builder.Build().Run();

Dieses Beispiel enthält nicht die standardmäßige Application Insights-Konfiguration, die in vielen anderen Program.cs Beispielen und in den Azure Functions-Vorlagen angezeigt wird. Stattdessen konfigurieren Sie die OpenTelemetry-Integration in Aspire, indem Sie die builder.AddServiceDefaults Methode aufrufen.

Beachten Sie die folgenden Richtlinien, um die Integration optimal zu verwenden:

  • Fügen Sie keine direkten Application Insights-Integrationen in das Funktionsprojekt ein. Die Überwachung in Aspire wird stattdessen über die OpenTelemetry-Unterstützung abgewickelt. Sie können Aspire so konfigurieren, dass Daten über das Dienststandardprojekt nach Azure Monitor exportiert werden.
  • Definieren Sie keine benutzerdefinierten App-Einstellungen in der local.settings.json Datei für das Functions-Projekt. Die einzige Einstellung, die in local.settings.json enthalten sein soll, ist "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated". Legen Sie alle anderen App-Konfigurationen über das App-Hostprojekt fest.

Verbindungskonfiguration mit Aspire

Das App-Hostprojekt definiert Ressourcen und unterstützt Sie beim Erstellen von Verbindungen zwischen ihnen mithilfe von Code. In diesem Abschnitt wird gezeigt, wie Verbindungen konfiguriert und angepasst werden, die ihr Azure Functions-Projekt verwendet.

Aspire enthält Standardverbindungsberechtigungen, die Ihnen bei den ersten Schritten helfen können. Diese Berechtigungen sind jedoch möglicherweise nicht geeignet oder für Ihre Anwendung ausreichend.

Für Szenarien, die die rollenbasierte Zugriffssteuerung (Azure Role-Based Access Control, RBAC) verwenden, können Sie Berechtigungen anpassen, indem Sie die WithRoleAssignments() Methode für die Projektressource aufrufen. Wenn Sie aufrufen WithRoleAssignments(), werden alle Standardrollenzuweisungen entfernt, und Sie müssen explizit die gewünschten vollständigen Rollenzuweisungen definieren. Wenn Sie Ihre Anwendung in Azure Container-Apps hosten, erfordert die Verwendung von WithRoleAssignments() auch, dass Sie AddAzureContainerAppEnvironment() auf DistributedApplicationBuilder anrufen.

Hostspeicher von Azure Functions

Azure Functions erfordert für mehrere seiner wichtigsten Funktionalitäten eine Hostspeicherverbindung (AzureWebJobsStorage). Wenn Sie AddAzureFunctionsProject<TProject>() in Ihrem App-Hostprojekt aufrufen, wird die AzureWebJobsStorage-Verbindung standardmäßig erstellt und dem Functions-Projekt bereitgestellt. Diese Standardverbindung verwendet den Azure Storage-Emulator für die lokale Entwicklung und stellt automatisch ein Speicherkonto bereit, wenn sie bereitgestellt wird. Um mehr Kontrolle zu erhalten, können Sie diese Verbindung durch Aufrufen .WithHostStorage() der Projektressource "Functions" ersetzen.

Die Standardberechtigungen, die Aspire für die Hostspeicherverbindung festlegt, hängt davon ab, ob Sie anrufen WithHostStorage() oder nicht. Beim Hinzufügen von WithHostStorage() wird eine Zuordnung von Mitwirkenden für das Speicherkonto entfernt. In der folgenden Tabelle sind die Standardberechtigungen aufgeführt, die Von Aspire für die Hostspeicherverbindung festgelegt werden:

Hostspeicherverbindung Standardrollen
Kein Anruf an WithHostStorage() Mitwirkender an Storage-Blobdaten,
Mitwirkender an Storage-Warteschlangendaten,
Mitwirkende für Speichertabellendaten,
Speicherkontomitwirkender
Aufrufen von WithHostStorage() Mitwirkender an Storage-Blobdaten,
Mitwirkender an Storage-Warteschlangendaten,
Mitwirkender an Storage-Tabellendaten

Das folgende Beispiel zeigt eine minimale AppHost.cs Datei für ein App-Hostprojekt, das den Hostspeicher ersetzt und eine Rollenzuweisung angibt:

using Azure.Provisioning.Storage;

var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureContainerAppEnvironment("myEnv");

var myHostStorage = builder.AddAzureStorage("myHostStorage");

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithHostStorage(myHostStorage)
    .WithRoleAssignments(myHostStorage, StorageBuiltInRole.StorageBlobDataOwner);

builder.Build().Run();

Hinweis

Der Besitzer von Speicher-BLOB-Daten ist die Rolle, die wir für die grundlegenden Anforderungen der Hostspeicherverbindung empfehlen. Ihre App kann Probleme verursachen, wenn die Verbindung mit dem Blob-Dienst nur den Aspire-Standardwert von "Storage Blob Data Contributor" aufweist.

Fügen Sie für Produktionsszenarien Aufrufe von WithHostStorage() und WithRoleAssignments() hinzu. Sie können diese Rolle dann explizit festlegen, zusammen mit allen anderen Personen, die Sie benötigen.

Trigger und Bindungsverbindungen

Ihre Trigger und Bindungen verweisen mithilfe des Namens auf Verbindungen. Die folgenden Aspire-Integrationen bieten diese Verbindungen durch einen Aufruf der Projektressource WithReference():

Aspire Integration Standardrollen
Azure Blob Storage Mitwirkender an Storage-Blobdaten,
Mitwirkender an Storage-Warteschlangendaten,
Mitwirkender an Storage-Tabellendaten
Azure Queue Storage Mitwirkender an Storage-Blobdaten,
Mitwirkender an Storage-Warteschlangendaten,
Mitwirkender an Storage-Tabellendaten
Azure Event Hubs Azure Event Hubs-Datenbesitzer
Azure Service Bus Azure Service Bus-Datenbesitzer

Das folgende Beispiel zeigt eine minimale AppHost.cs Datei für ein App-Hostprojekt, das einen Warteschlangentrigger konfiguriert. In diesem Beispiel ist die Connection-Eigenschaft des entsprechenden Warteschlangenauslösers auf MyQueueTriggerConnection festgelegt, sodass der Aufruf von WithReference() den Namen angibt.

var builder = DistributedApplication.CreateBuilder(args);

var myAppStorage = builder.AddAzureStorage("myAppStorage").RunAsEmulator();
var queues = myAppStorage.AddQueues("queues");

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithReference(queues, "MyQueueTriggerConnection");

builder.Build().Run();

Bei anderen Integrationen werden Aufrufe zum WithReference Festlegen der Konfiguration auf eine andere Weise durchgeführt. Sie stellen die Konfiguration für Aspire-Clientintegrationen zur Verfügung, aber nicht für Trigger und Bindungen. Für diese Integrationen rufen Sie WithEnvironment() auf, um die Verbindungsinformationen zum Auflösen des Auslösers oder der Bindung zu übergeben.

Das folgende Beispiel zeigt, wie Die Umgebungsvariable MyBindingConnection für eine Ressource festgelegt wird, die einen Verbindungszeichenfolgenausdruck verfügbar macht:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);

Wenn Sie möchten, dass sowohl Aspire-Clientintegrationen als auch das System von Triggern und Bindungen einen Anschluss verwenden, können Sie beide WithReference() und WithEnvironment() konfigurieren.

Bei einigen Ressourcen kann sich die Struktur einer Verbindung zwischen der lokalen Ausführung und der Veröffentlichung in Azure möglicherweise unterscheiden. Im vorherigen Beispiel könnte otherIntegration eine Ressource sein, die als Emulator ausgeführt wird, sodass ConnectionStringExpression eine Emulatorverbindungszeichenfolge zurückgeben würde. Wenn die Ressource veröffentlicht wird, kann Aspire jedoch eine identitätsbasierte Verbindung einrichten und ConnectionStringExpression den URI des Diensts zurückgeben. In diesem Fall müssen Sie möglicherweise einen anderen Umgebungsvariablennamen angeben, um identitätsbasierte Verbindungen für Azure-Funktionen einzurichten.

Im folgenden Beispiel wird builder.ExecutionContext.IsPublishMode verwendet, um das erforderliche Suffix bedingt hinzuzufügen:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);

Ausführliche Informationen zu den Verbindungsformaten, die jede Bindung unterstützt, sowie zu den Berechtigungen, die diese Formate erfordern, finden Sie auf den Referenzseiten der Bindung.

Hosten der Anwendung

Aspire unterstützt zwei verschiedene Möglichkeiten zum Hosten Ihres Functions-Projekts in Azure:

In beiden Fällen wird Ihr Projekt als Container bereitgestellt. Aspire kümmert sich um das Erstellen des Container-Images für Sie und das Hochladen in die Azure Container Registry.

Als Container-App veröffentlichen

Wenn Sie ein Aspire-Projekt in Azure veröffentlichen, wird es standardmäßig in Azure-Container-Apps bereitgestellt. Das System richtet Skalierungsregeln für Ihr Functions-Projekt mithilfe von KEDA ein. Bei Verwendung von Azure-Container-Apps ist zusätzliches Setup für Funktionsschlüssel erforderlich. Weitere Informationen finden Sie unter Zugriffstasten in Azure-Container-Apps .

Zugriffstasten in Azure-Container-Apps

Mehrere Azure Functions-Szenarien verwenden Zugriffstasten, um eine grundlegende Gegenmaßnahme gegen unerwünschten Zugriff bereitzustellen. Beispielsweise müssen HTTP-Triggerfunktionen standardmäßig einen Zugriffsschlüssel aufrufen, obwohl diese Anforderung mithilfe der AuthLevel Eigenschaft deaktiviert werden kann. Siehe Arbeiten mit Zugriffstasten in Azure-Funktionen für Szenarien, für die möglicherweise ein Schlüssel erforderlich ist.

Wenn Sie ein Functions-Projekt mithilfe von Aspire to Azure Container Apps bereitstellen, erstellt oder verwaltet das System keine Funktionszugriffsschlüssel. Wenn Sie Zugriffstasten verwenden müssen, können Sie sie als Teil Ihres App-Host-Setups verwalten. In diesem Abschnitt erfahren Sie, wie Sie eine Erweiterungsmethode erstellen, die Sie aus der Datei Ihres App-Hosts Program.cs aufrufen können, um Zugriffstasten zu erstellen und zu verwalten. Dieser Ansatz verwendet Azure Key Vault, um die Schlüssel zu speichern und als geheime Schlüssel in die Container-App zu integrieren.

Hinweis

Das Verhalten basiert hier auf dem ContainerApps geheimen Anbieter, der nur ab der Hostversion 4.1044.0von Functions verfügbar ist. Diese Version ist noch nicht in allen Regionen verfügbar. Solange das der Fall ist, könnte beim Veröffentlichen Ihres Aspire-Projekts das Basisbild, das für das Functions-Projekt verwendet wird, möglicherweise nicht die notwendigen Änderungen enthalten.

Für diese Schritte ist Bicep-Version 0.38.3 oder höher erforderlich. Sie können Ihre Bicep-Version überprüfen, indem Sie das Kommando bicep --version in einem Eingabeaufforderungsfenster ausführen. Wenn Sie die Azure CLI installiert haben, können Sie az bicep upgrade verwenden, um Bicep schnell auf die neueste Version zu aktualisieren.

Fügen Sie ihrem App-Hostprojekt die folgenden NuGet-Pakete hinzu:

Erstellen Sie eine neue Klasse in Ihrem App-Hostprojekt, und fügen Sie den folgenden Code ein:

using Aspire.Hosting.Azure;
using Azure.Provisioning.AppContainers;

namespace Aspire.Hosting;

internal static class Extensions
{
    private record SecretMapping(string OriginalName, IAzureKeyVaultSecretReference Reference);

    public static IResourceBuilder<T> PublishWithContainerAppSecrets<T>(
        this IResourceBuilder<T> builder,
        IResourceBuilder<AzureKeyVaultResource>? keyVault = null,
        string[]? hostKeyNames = null,
        string[]? systemKeyExtensionNames = null)
        where T : AzureFunctionsProjectResource
    {
        if (!builder.ApplicationBuilder.ExecutionContext.IsPublishMode)
        {
            return builder;
        }

        keyVault ??= builder.ApplicationBuilder.AddAzureKeyVault("functions-keys");

        var hostKeysToAdd = (hostKeyNames ?? []).Append("default").Select(k => $"host-function-{k}");
        var systemKeysToAdd = systemKeyExtensionNames?.Select(k => $"host-systemKey-{k}_extension") ?? [];
        var secrets = hostKeysToAdd.Union(systemKeysToAdd)
            .Select(secretName => new SecretMapping(
                secretName,
                CreateSecretIfNotExists(builder.ApplicationBuilder, keyVault, secretName.Replace("_", "-"))
            )).ToList();

        return builder
            .WithReference(keyVault)
            .WithEnvironment("AzureWebJobsSecretStorageType", "ContainerApps")
            .PublishAsAzureContainerApp((infra, app) => ConfigureFunctionsContainerApp(infra, app, builder.Resource, secrets));
    }

    private static void ConfigureFunctionsContainerApp(
        AzureResourceInfrastructure infrastructure, 
        ContainerApp containerApp, 
        IResource resource, 
        List<SecretMapping> secrets)
    {
        const string volumeName = "functions-keys";
        const string mountPath = "/run/secrets/functions-keys";

        var appIdentityAnnotation = resource.Annotations.OfType<AppIdentityAnnotation>().Last();
        var containerAppIdentityId = appIdentityAnnotation.IdentityResource.Id.AsProvisioningParameter(infrastructure);

        var containerAppSecretsVolume = new ContainerAppVolume
        {
            Name = volumeName,
            StorageType = ContainerAppStorageType.Secret
        };

        foreach (var mapping in secrets)
        {
            var secret = mapping.Reference.AsKeyVaultSecret(infrastructure);

            containerApp.Configuration.Secrets.Add(new ContainerAppWritableSecret()
            {
                Name = mapping.Reference.SecretName.ToLowerInvariant(),
                KeyVaultUri = secret.Properties.SecretUri,
                Identity = containerAppIdentityId
            });

            containerAppSecretsVolume.Secrets.Add(new SecretVolumeItem
            {
                Path = mapping.OriginalName.Replace("-", "."),
                SecretRef = mapping.Reference.SecretName.ToLowerInvariant()
            });
        }

        containerApp.Template.Containers[0].Value!.VolumeMounts.Add(new ContainerAppVolumeMount
        {
            VolumeName = volumeName,
            MountPath = mountPath
        });
        containerApp.Template.Volumes.Add(containerAppSecretsVolume);
    }

    public static IAzureKeyVaultSecretReference CreateSecretIfNotExists(
        IDistributedApplicationBuilder builder,
        IResourceBuilder<AzureKeyVaultResource> keyVault,
        string secretName)
    {
        var secretParameter = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"param-{secretName}", special: false);
        builder.AddBicepTemplateString($"key-vault-key-{secretName}", """
                param location string = resourceGroup().location
                param keyVaultName string
                param secretName string
                @secure()
                param secretValue string    

                // Reference the existing Key Vault
                resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
                  name: keyVaultName
                }

                // Deploy the secret only if it does not already exist
                @onlyIfNotExists()
                resource newSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
                  parent: keyVault
                  name: secretName
                  properties: {
                      value: secretValue
                  }
                }
                """)
            .WithParameter("keyVaultName", keyVault.GetOutput("name"))
            .WithParameter("secretName", secretName)
            .WithParameter("secretValue", secretParameter);

        return keyVault.GetSecret(secretName);
    }
}

Sie können diese Methode dann in der Datei Ihres App-Hosts Program.cs verwenden:

builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
       .WithHostStorage(storage)
       .WithExternalHttpEndpoints()
       .PublishWithContainerAppSecrets(systemKeyExtensionNames: ["mcp"]);

In diesem Beispiel wird ein Standard-Key Vault verwendet, der durch die Erweiterungsmethode erstellt wurde. Er führt zu einem Standardschlüssel und einem Systemschlüssel für die Verwendung mit der Model Context Protocol-Erweiterung.

Um diese Schlüssel von Clients zu verwenden, müssen Sie sie aus dem Schlüsseltresor abrufen.

Als Funktions-App veröffentlichen

Hinweis

Die Veröffentlichung als Funktions-App erfordert die Aspire Azure App Service-Integration, die sich derzeit in der Vorschau befindet.

Sie können Aspire so konfigurieren, dass sie mithilfe der Integration von Aspire Azure App Service in eine Funktions-App bereitgestellt wird. Da Aspire das Functions-Projekt als Container veröffentlicht, muss der Hostingplan für Ihre Funktions-App die Bereitstellung von containerisierten Anwendungen unterstützen.

Führen Sie die folgenden Schritte aus, um Ihr Projekt "Aspire Functions" als Funktions-App zu veröffentlichen:

  1. Fügen Sie einen Verweis auf das Aspire.Hosting.Azure.AppService NuGet-Paket in Ihrem App-Hostprojekt hinzu.
  2. Rufen Sie in der AppHost.cs-Datei AddAzureAppServiceEnvironment() auf Ihrer IDistributedApplicationBuilder-Instanz auf, um einen App Service-Plan zu erstellen. Beachten Sie, dass dies trotz des Namens keine App Service Environment-Ressource bereitstellt.
  3. Rufen Sie in der Projektressource „Functions“ .WithExternalHttpEndpoints() auf. Dies ist für die Bereitstellung mit der Aspire Azure App Service-Integration erforderlich.
  4. Rufen Sie in der Projektressource „Functions“ .PublishAsAzureAppServiceWebsite((infra, app) => app.Kind = "functionapp,linux") auf, um das Projekt auf dem Plan zu veröffentlichen.

Von Bedeutung

Stellen Sie sicher, dass Sie die app.Kind Eigenschaft auf "functionapp,linux" setzen. Diese Einstellung stellt sicher, dass die Ressource als Funktions-App erstellt wird, die sich auf die Erfahrungen beim Arbeiten mit Ihrer Anwendung auswirkt.

Das folgende Beispiel zeigt eine minimale AppHost.cs Datei für ein App-Hostprojekt, das ein Funktionsprojekt als Funktions-App veröffentlicht:

var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureAppServiceEnvironment("functions-env");
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
    .WithExternalHttpEndpoints()
    .PublishAsAzureAppServiceWebsite((infra, app) => app.Kind = "functionapp,linux");

Diese Konfiguration erstellt einen Premium V3-Plan. Bei Verwendung einer dedizierten App Service-Plan-SKU ist die Skalierung nicht ereignisbasiert. Stattdessen wird die Skalierung über die App Service-Planeinstellungen verwaltet.

Überlegungen und bewährte Methoden

Berücksichtigen Sie die folgenden Punkte, wenn Sie die Integration von Azure Functions mit Aspire bewerten:

  • Trigger- und Bindungskonfiguration über Aspire ist derzeit auf bestimmte Integrationen beschränkt. Ausführliche Informationen finden Sie in diesem Artikel unter Verbindungskonfiguration mit Aspire .

  • Die Program.cs-Datei des Funktionsprojekts sollte die IHostApplicationBuilder-Version des Hostinstanzstarrtups verwenden. IHostApplicationBuilder ermöglicht es Ihnen, builder.AddServiceDefaults() aufzurufen, um Aspire-Dienststandardeinstellungen zu Ihrem Functions-Projekt hinzuzufügen.

  • Aspire verwendet OpenTelemetry zur Überwachung. Sie können Aspire so konfigurieren, dass Daten über das Dienststandardprojekt nach Azure Monitor exportiert werden.

    In vielen anderen Azure Functions-Kontexten können Sie die direkte Integration in Application Insights einschließen, indem Sie den Workerdienst registrieren. Wir empfehlen diese Art von Integration in Aspire nicht. Es kann zu Laufzeitfehlern mit Version 2.22.0 von Microsoft.ApplicationInsights.WorkerService führen, doch Version 2.23.0 behebt dieses Problem. Wenn Sie Aspire verwenden, entfernen Sie alle direkten Application Insights-Integrationen aus Ihrem Functions-Projekt.

  • Bei Funktionen-Projekten, die in eine Aspire-Orchestrierung aufgenommen wurden, sollte der Großteil der Anwendungskonfiguration aus dem Projekt "Aspire App Host" stammen. Vermeiden Sie das Festlegen von Elementen in local.settings.json, außer der FUNCTIONS_WORKER_RUNTIME Einstellung. Wenn Sie dieselbe Umgebungsvariable in local.settings.json und Aspire festlegen, verwendet das System die Aspire-Version.

  • Konfigurieren Sie den Azure Storage-Emulator nicht für Verbindungen in local.settings.json. Viele Functions-Startvorlagen enthalten den Emulator als Standard für AzureWebJobsStorage. Die Emulatorkonfiguration kann jedoch einige Entwicklertools auffordern, eine Version des Emulators zu starten, die mit der von Aspire verwendeten Version in Konflikt geraten kann.