Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Aspire je názorově zaměřený stack, který zjednodušuje vývoj distribuovaných aplikací v cloudu. Integrace Aspire s Azure Functions umožňuje vyvíjet, ladit a orchestrovat projekt Azure Functions .NET jako součást hostitele aplikace Aspire.
Požadavky
Nastavení vývojového prostředí pro použití Azure Functions s Aspire:
-
Nainstalujte požadavky Aspire.
- Úplná podpora integrace Azure Functions vyžaduje Aspire 13.1 nebo novější. Aspire 13.0 obsahuje také verzi
Aspire.Hosting.Azure.FunctionsPreview, která funguje jako kandidát verze s podporou go-live.
- Úplná podpora integrace Azure Functions vyžaduje Aspire 13.1 nebo novější. Aspire 13.0 obsahuje také verzi
- Nainstalujte nástroje Azure Functions Core Tools.
Pokud používáte Visual Studio, aktualizujte na verzi 17.12 nebo novější. Musíte mít také nejnovější verzi nástrojů Azure Functions pro Visual Studio. Kontrola aktualizací:
- Přejděte naMožnosti>.
- V části Projekty a řešení vyberte Azure Functions.
- Podle výzvy vyberte Vyhledat aktualizace a nainstalovat aktualizace.
Struktura řešení
Řešení, které používá Azure Functions a Aspire, má několik projektů, včetně hostitelského projektu aplikace a jednoho nebo více projektů Functions.
Projekt hostitele aplikace je vstupním bodem vaší aplikace. Orchestruje nastavení komponent aplikace, včetně projektu Functions.
Řešení obvykle zahrnuje také výchozí projekt služby . Tento projekt poskytuje sadu výchozích služeb a konfigurací, které se mají použít napříč projekty ve vaší aplikaci.
Projekt hostingu aplikace
Pokud chcete úspěšně nakonfigurovat integraci, ujistěte se, že hostitelský projekt aplikace splňuje následující požadavky:
- Projekt hostitele aplikace musí odkazovat na Aspire.Hosting.Azure.Functions. Tento balíček definuje potřebnou logiku pro integraci.
- Hostitelský projekt aplikace musí mít odkaz na projekt pro každý projekt Functions, který chcete zahrnout do orchestrace.
- V souboru
AppHost.cshostitele aplikace musíte voláním na instanciAddAzureFunctionsProject<TProject>()zahrnout projektIDistributedApplicationBuilder. Tuto metoduAddProject<TProject>()použijete místo metody, kterou používáte pro jiné typy projektů v Aspire. Pokud používáteAddProject<TProject>(), projekt Functions se nemůže správně spustit.
Následující příklad ukazuje minimální AppHost.cs soubor pro hostitelský projekt aplikace:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");
builder.Build().Run();
Projekt Azure Functions
Pokud chcete úspěšně nakonfigurovat integraci, ujistěte se, že projekt Azure Functions splňuje následující požadavky:
Projekt Functions musí odkazovat na verze 2.xmicrosoft.Azure.Functions.Worker a Microsoft.Azure.Functions.Worker.Sdk. Také musíte aktualizovat všechny odkazy Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore na verzi 2.x.
Soubor
Program.csmusí používatIHostApplicationBuilderverzi pro spuštění instance hostitele. Tento požadavek znamená, že musíte použítFunctionsApplication.CreateBuilder(args).Pokud vaše řešení obsahuje výchozí projekt služby, ujistěte se, že je projekt Functions nakonfigurovaný tak, aby ho používal:
- Projekt Functions by měl obsahovat odkaz na projekt s výchozími nastaveními služby.
- Před sestavením
IHostApplicationBuildervProgram.cszahrňte voláníbuilder.AddServiceDefaults().
Následující příklad ukazuje minimální Program.cs soubor pro projekt Functions použitý v Aspire:
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;
var builder = FunctionsApplication.CreateBuilder(args);
builder.AddServiceDefaults();
builder.ConfigureFunctionsWebApplication();
builder.Build().Run();
Tento příklad neobsahuje výchozí konfiguraci Application Insights, která se zobrazí v mnoha dalších Program.cs příkladech a v šablonách Azure Functions. Místo toho nakonfigurujete integraci OpenTelemetry v Aspire voláním builder.AddServiceDefaults metody.
Pokud chcete využít integraci na maximum, zvažte následující pokyny:
- Do projektu Functions nezahrnujte žádné přímé integrace Application Insights. Monitorování v Aspire se místo toho zpracovává prostřednictvím podpory OpenTelemetry. Aspire můžete nakonfigurovat tak, aby exportoval data do služby Azure Monitor prostřednictvím výchozího projektu služby.
- Nedefinujte vlastní nastavení aplikace v
local.settings.jsonsouboru pro projekt Functions. Jediné nastavení, které by mělo být vlocal.settings.jsonje"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated". Nastavte všechny ostatní konfigurace aplikací prostřednictvím hostitelského projektu aplikace.
Konfigurace připojení pomocí Aspire
Projekt hostitele aplikace definuje prostředky a pomáhá vytvářet propojení mezi nimi pomocí kódu. Tato část ukazuje, jak nakonfigurovat a přizpůsobit připojení, která váš projekt Azure Functions používá.
Aspire obsahuje výchozí oprávnění připojení, která vám můžou pomoct začít. Tato oprávnění ale nemusí být pro vaši aplikaci vhodná nebo dostatečná.
Ve scénářích, které používají řízení přístupu na základě role v Azure (RBAC), můžete oprávnění přizpůsobit voláním WithRoleAssignments() metody pro prostředek projektu. Při volání WithRoleAssignments()se odeberou všechna výchozí přiřazení rolí a musíte explicitně definovat požadovaná přiřazení rolí úplné sady. Pokud hostujete aplikaci ve službě Azure Container Apps, je nutné použít WithRoleAssignments() a volat AddAzureContainerAppEnvironment() na DistributedApplicationBuilder.
Hostitelské úložiště Azure Functions
Azure Functions vyžaduje připojení k úložišti hostitele (AzureWebJobsStorage) pro několik základních chování. Při volání AddAzureFunctionsProject<TProject>() ve vašem hostitelském projektu aplikace se ve výchozím nastavení vytvoří připojení, které je poskytnuto projektu Functions. Toto výchozí připojení používá emulátor služby Azure Storage pro spuštění místního vývoje a automaticky zřídí účet úložiště při nasazení. Pokud chcete mít větší kontrolu, můžete toto připojení nahradit voláním .WithHostStorage() zdroje projektu Functions.
Výchozí oprávnění, která Aspire nastaví pro připojení k úložišti hostitele, závisí na tom, jestli voláte WithHostStorage() nebo ne. Přidáním WithHostStorage() se odebere přiřazení přispěvatele účtu úložiště. Následující tabulka uvádí výchozí oprávnění, která Aspire nastaví pro připojení k úložišti hostitele:
| Připojení k úložišti hostitele | Výchozí role |
|---|---|
Žádný hovor na WithHostStorage() |
Přispěvatel dat objektů blob služby Storage Přispěvatel dat fronty služby Storage Přispěvatel dat tabulky služby Storage Přispěvatel ke službě úložiště |
Volání WithHostStorage() |
Přispěvatel dat objektů blob služby Storage Přispěvatel dat fronty služby Storage Přispěvatel dat tabulky úložiště |
Následující příklad ukazuje minimální AppHost.cs soubor pro hostitelský projekt aplikace, který nahrazuje úložiště hostitele a určuje přiřazení role:
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();
Poznámka:
Vlastník dat objektů blob služby Storage je role, kterou doporučujeme pro základní potřeby připojení hostitele k úložišti. Aplikace může narazit na problémy, pokud připojení ke službě blob má pouze výchozí roli Storage Blob Data Contributor.
V produkčních scénářích uveďte volání jak WithHostStorage(), tak WithRoleAssignments(). Tuto roli pak můžete explicitně nastavit společně s ostatními, které potřebujete.
Připojení spouštěče a vazby
Vaše spouštěče a vazby odkazují na připojení podle jména. Následující integrace Aspire poskytují tato připojení prostřednictvím volání na WithReference() zdroje projektu:
| Integrace Aspire | Výchozí role |
|---|---|
| Azure Blob Storage |
Přispěvatel dat objektů blob služby Storage Přispěvatel dat fronty služby Storage Přispěvatel dat tabulky úložiště |
| Azure Queue Storage |
Přispěvatel dat objektů blob služby Storage Přispěvatel dat fronty služby Storage Přispěvatel dat tabulky úložiště |
| Azure Event Hubs | Vlastník dat služby Azure Event Hubs |
| Azure Service Bus | Vlastník dat služby Azure Service Bus |
Následující příklad ukazuje minimální AppHost.cs soubor pro hostitelský projekt aplikace, který konfiguruje spouštěč fronty. V tomto příkladu má odpovídající aktivační událost fronty vlastnost Connection nastavenu na MyQueueTriggerConnection, takže volání specifikuje název WithReference().
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();
Při jiných integracích se volání k nastavení WithReference konfigurace provádějí odlišně. Zpřístupní konfiguraci integrací klientů Aspire, ale ne triggerům a vazbám. U těchto integrací zavolejte WithEnvironment() pro zpracování informací o připojení s cílem vyřešení triggeru nebo vazby.
Následující příklad ukazuje, jak nastavit proměnnou MyBindingConnection prostředí pro prostředek, který zveřejňuje výraz připojovacího řetězce:
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);
Pokud chcete, aby integrace klienta Aspire i systém triggerů a vazeb používaly připojení, můžete nakonfigurovat obojí WithReference() i WithEnvironment().
U některých prostředků se struktura připojení může lišit mezi tím, kdy ho spouštíte místně a kdy ho publikujete do Azure. V předchozím příkladu může být otherIntegration prostředek, který běží jako emulátor, takže ConnectionStringExpression by vrátil připojovací řetězec emulátoru. Když je prostředek publikován, Aspire však může nastavit připojení založené na identitě a ConnectionStringExpression poskytnout URI služby. V tomto případě může být při nastavování připojení založených na identitě pro Azure Functions potřeba zadat jiný název proměnné prostředí.
Následující příklad používá builder.ExecutionContext.IsPublishMode k podmíněnému přidání nezbytné přípony:
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);
Podrobnosti o formátech připojení, které jednotlivé vazby podporují, a oprávnění, která tyto formáty vyžadují, najdete na referenčních stránkách vazby.
Hostování aplikace
Aspire podporuje dva různé způsoby hostování projektu Functions v Azure:
- Publikování jako aplikace typu kontejner (výchozí)
- Publikovat jako Function App pomocí integrace App Service v Preview
V obou případech se váš projekt nasadí jako kontejner. Aspire se postará o vytvoření image kontejneru za vás a nasdílí ji do služby Azure Container Registry.
Publikování jako aplikace typu kontejner
Když publikujete projekt Aspire do Azure, ve výchozím nastavení se nasadí do Azure Container Apps. Systém nastaví pravidla škálování pro váš projekt Functions pomocí KEDA. Pokud používáte Azure Container Apps, je potřeba další nastavení pro klíče funkcí. Další informace najdete v tématu Přístupové klíče v Azure Container Apps .
Přístupové klíče v Azure Container Apps
Několik scénářů Azure Functions používá přístupové klíče k zajištění základního omezení rizik proti nežádoucímu přístupu. Například funkce triggeru HTTP ve výchozím nastavení vyžadují vyvolání přístupového klíče, i když tento požadavek může být zakázán pomocí AuthLevel vlastnosti. Scénáře, které můžou vyžadovat klíč, najdete v tématu Práce s přístupovými klíči ve službě Azure Functions .
Když nasadíte projekt Functions pomocí Aspire do Azure Container Apps, systém automaticky nevytváří ani nespravuje přístupové klíče Functions. Pokud potřebujete používat přístupové klíče, můžete je spravovat v rámci nastavení hostitele aplikací. V této části se dozvíte, jak vytvořit metodu rozšíření, kterou můžete volat ze souboru hostitele Program.cs aplikace za účelem vytvoření a správy přístupových klíčů. Tento přístup používá Azure Key Vault k ukládání klíčů a jejich připojení do aplikace kontejneru jako tajných kódů.
Poznámka:
Toto chování závisí na poskytovateli tajemství ContainerApps, který je k dispozici pouze od verze 4.1044.0 hostitele Functions. Tato verze ještě není k dispozici ve všech oblastech a dokud nebude, když publikujete projekt Aspire, nemusí základní image použitá pro projekt Functions obsahovat potřebné změny.
Tyto kroky vyžadují verzi 0.38.3 Bicep nebo novější. Verzi Bicep můžete zkontrolovat spuštěním bicep --version z příkazového řádku. Pokud máte nainstalované Rozhraní příkazového řádku Azure, můžete použít az bicep upgrade k rychlé aktualizaci Bicep na nejnovější verzi.
Do hostitelského projektu aplikace přidejte následující balíčky NuGet:
Vytvořte novou třídu v hostitelském projektu aplikace a zadejte následující kód:
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);
}
}
Tuto metodu Program.cs pak můžete použít v souboru hostitele aplikace:
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithHostStorage(storage)
.WithExternalHttpEndpoints()
.PublishWithContainerAppSecrets(systemKeyExtensionNames: ["mcp"]);
Tento příklad používá výchozí trezor klíčů vytvořený metodou rozšíření. Výsledkem je výchozí klíč a systémový klíč pro použití s rozšířením Model Context Protocol.
Pokud chcete tyto klíče používat z klientů, musíte je načíst z klíčového úložiště.
Publikovat jako aplikaci funkcí
Poznámka:
Publikování jako aplikace funkcí vyžaduje integraci služby Aspire Azure App Service, která je aktuálně ve verzi Preview.
Aspire můžete nakonfigurovat tak, aby se nasadil do aplikace funkcí pomocí integrace služby Aspire Azure App Service. Vzhledem k tomu, že Aspire publikuje projekt Functions jako kontejner, musí plán hostování vaší aplikace funkcí podporovat nasazování kontejnerizovaných aplikací.
Pokud chcete publikovat projekt Aspire Functions jako aplikaci funkcí, postupujte takto:
- Přidejte do hostitelského projektu aplikace odkaz na balíček NuGet Aspire.Hosting.Azure.AppService .
- V souboru
AppHost.cszavolejteAddAzureAppServiceEnvironment()na instanciIDistributedApplicationBuilder, abyste vytvořili plán služby App Service. Všimněte si, že bez ohledu na název to nezřizuje prostředek služby App Service Environment. - Na zdroji projektu Functions volejte
.WithExternalHttpEndpoints(). To se vyžaduje pro nasazení s integrací služby Aspire Azure App Service. - Na zdroji projektu Functions zavolejte
.PublishAsAzureAppServiceWebsite((infra, app) => app.Kind = "functionapp,linux"), aby se projekt publikoval do plánu.
Důležité
Ujistěte se, že nastavíte vlastnost app.Kind na "functionapp,linux". Toto nastavení zajistí, že se prostředek vytvoří jako aplikace funkcí, což má vliv na prostředí pro práci s vaší aplikací.
Následující příklad ukazuje minimální AppHost.cs soubor pro hostitelský projekt aplikace, který publikuje projekt Functions jako aplikaci funkcí:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureAppServiceEnvironment("functions-env");
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithExternalHttpEndpoints()
.PublishAsAzureAppServiceWebsite((infra, app) => app.Kind = "functionapp,linux");
Tato konfigurace vytvoří plán Premium V3. Pokud používáte skladovou položku vyhrazeného plánu služby App Service, škálování není založené na událostech. Škálování se místo toho spravuje prostřednictvím nastavení plánu služby App Service.
Důležité informace a osvědčené postupy
Při vyhodnocování integrace azure Functions s Aspire zvažte následující body:
Konfigurace triggerů a vazeb prostřednictvím Aspire se momentálně omezuje na konkrétní integrace. Podrobnosti najdete v části Konfigurace připojení s Aspire v tomto článku.
Soubor
ve vašem projektu funkce by měl používat verzi pro spuštění instance hostitele . IHostApplicationBuilderumožňuje volat funkcibuilder.AddServiceDefaults()pro přidání výchozích hodnot služby Aspire do projektu Function.Aspire používá k monitorování OpenTelemetry. Aspire můžete nakonfigurovat tak, aby exportoval data do služby Azure Monitor prostřednictvím výchozího projektu služby.
V mnoha dalších kontextech Azure Functions můžete zahrnout přímou integraci s Application Insights registrací pracovní služby. Tento druh integrace do Aspire nedoporučujeme. Může vést k chybám za běhu verze 2.22.0 z
Microsoft.ApplicationInsights.WorkerService, i když verze 2.23.0 tento problém řeší. Pokud používáte Aspire, odeberte z projektu Functions všechny přímé integrace Application Insights.U projektů Functions zařazených do orchestrace Aspire by většina konfigurace aplikace měla pocházet z hostitelského projektu aplikace Aspire. Vyhněte se nastavování položek v
local.settings.json, kromě nastaveníFUNCTIONS_WORKER_RUNTIME. Pokud nastavíte stejnou proměnnou prostředí vlocal.settings.jsona Aspire, systém použije verzi Aspire.Nenakonfigurujte emulátor služby Azure Storage pro žádná připojení v
local.settings.json. Mnoho úvodních šablon Functions zahrnuje emulátor jako výchozí nastavení proAzureWebJobsStorage. Konfigurace emulátoru ale může vyzvat některé vývojářské nástroje ke spuštění verze emulátoru, která může být v konfliktu s verzí, kterou Aspire používá.