Udostępnij za pośrednictwem


Omówienie integracji .NET AspireAzure

Azure jest najpopularniejszą platformą w chmurze do tworzenia i wdrażania aplikacji .NET. Zestaw SDK Azure dla .NET umożliwia łatwe zarządzanie usługami Azure i korzystanie z nich. .NET Aspire zapewnia zestaw integracji z usługami Azure, w których możesz dodawać nowe zasoby lub łączyć się z istniejącymi. Ten artykuł zawiera szczegółowe informacje o niektórych typowych aspektach wszystkich integracji Azure w .NET Aspire i ma na celu ułatwienie zrozumienia sposobu ich używania.

Dodaj zasoby Azure

Wszystkie integracje hostingowe .NET AspireAzure udostępniają zasoby Azure i zgodnie z konwencją są dodawane przy użyciu interfejsów API AddAzure*. Po dodaniu tych zasobów do hosta aplikacji .NET Aspire reprezentują one usługę Azure. Interfejs API AddAzure* zwraca IResourceBuilder<T>, w którym T jest typem zasobu Azure. Te interfejsy IResourceBuilder<T> (konstruktora) zapewniają płynny interfejs API, który umożliwia skonfigurowanie bazowego zasobu Azure w ramach modelu aplikacji . Istnieją interfejsy API służące do dodawania nowych zasobów Azure, oznaczania zasobów jako istniejących i konfigurowania zachowania zasobów w różnych kontekstach wykonywania.

Typowe środowisko deweloperskie

Gdy host aplikacji .NET Aspire zawiera zasoby Azure i jest uruchamiany lokalnie (zazwyczaj deweloper F5 lub środowisko dotnet run), zasoby Azure są aprowizowane w ramach subskrypcji Azure. To pozwala Tobie jako deweloperowi debugować je lokalnie w kontekście Twojego hosta aplikacji.

.NET .NET Aspire ma na celu zminimalizowanie kosztów, domyślnie wybierając Basic lub StandardStock Keeping Unit (SKU) dla swoich integracji z Azure. Chociaż te rozsądne wartości domyślne są dostępne, można dostosować zasoby Azure zgodnie z potrzebami. Ponadto niektóre integracje obsługują emulatory lub kontenery , które są przydatne w przypadku lokalnego programowania, testowania i debugowania. Domyślnie po uruchomieniu aplikacji lokalnie zasoby Azure używają rzeczywistej usługi Azure. Można je jednak skonfigurować tak, aby korzystały z lokalnych emulatorów lub kontenerów, unikając kosztów związanych z rzeczywistą usługą Azure podczas programowania lokalnego.

Lokalne emulatory

Niektóre usługi Azure można emulować w celu lokalnego uruchamiania. Obecnie .NET Aspire obsługuje następujące emulatory Azure:

Integracja hostingu Opis
Azure Cosmos DB Wywołaj AzureCosmosExtensions.RunAsEmulator na IResourceBuilder<AzureCosmosDBResource>, aby skonfigurować zasób Cosmos DB, który ma być emulowany z użyciem NoSQL API.
Azure Event Hubs Wywołaj AzureEventHubsExtensions.RunAsEmulator na IResourceBuilder<AzureEventHubsResource>, aby skonfigurować zasób usługi Event Hubs do emulacji .
Azure Service Bus Wywołaj AzureServiceBusExtensions.RunAsEmulator na IResourceBuilder<AzureServiceBusResource>, aby skonfigurować zasób usługi Service Bus do emulowania za pomocą emulatora Service Bus.
Azure SignalR Service Wywołaj AzureSignalRExtensions.RunAsEmulator na IResourceBuilder<AzureSignalRResource>, aby skonfigurować zasób SignalR do emulacji z użyciem emulatora AzureSignalR.
Azure Przechowywanie Wywołaj AzureStorageExtensions.RunAsEmulator na IResourceBuilder<AzureStorageResource>, aby skonfigurować zasób magazynu, który ma być emulowany za pomocąAzurite.

Aby zasoby Azure używały lokalnych emulatorów, wywołaj metodę RunAsEmulator łańcuchowo na konstruktorze zasobów Azure. Ta metoda konfiguruje zasób Azure do używania lokalnego emulatora zamiast rzeczywistej usługi Azure.

Ważny

Wywoływanie dowolnego z dostępnych interfejsów API RunAsEmulator w konstruktorze zasobów Azure nie ma skutku na manifest publikowania . Podczas publikowania aplikacji wygenerowany plik Bicep odzwierciedla rzeczywistą usługę Azure, a nie emulator lokalny.

Kontenery lokalne

Niektóre zasoby Azure można zastąpić lokalnie przy użyciu kontenerów typu open source lub lokalnych. Aby zastąpić zasób Azure lokalnie w kontenerze, zastosuj wywołanie metody RunAsContainer na konstruktorze zasobów Azure. Ta metoda konfiguruje zasób Azure do używania konteneryzowanej wersji usługi na potrzeby programowania i testowania lokalnego, a nie rzeczywistej usługi Azure.

Obecnie usługa .NET Aspire obsługuje następujące usługi Azure jako kontenery:

Integracja hostingu Szczegóły
Azure Cache for Redis Aby skonfigurować IResourceBuilder<AzureRedisCacheResource> do uruchamiania lokalnie w kontenerze, wywołaj AzureRedisExtensions.RunAsContainer na bazie obrazu docker.io/library/redis.
Azure PostgreSQL elastyczne Server Wywołaj AzurePostgresExtensions.RunAsContainer w IResourceBuilder<AzurePostgresFlexibleServerResource>, aby skonfigurować go do lokalnego uruchamiania w kontenerze na podstawie obrazu docker.io/library/postgres.
Azure SQL Server Wywołaj AzureSqlExtensions.RunAsContainer na IResourceBuilder<AzureSqlServerResource>, aby skonfigurować go do lokalnego uruchamiania w kontenerze, korzystając z obrazu mcr.microsoft.com/mssql/server.

Notatka

Podobnie jak emulatory, wywoływanie RunAsContainer w konstruktorze zasobów Azure nie wpływa na manifest publikowania . Podczas publikowania aplikacji, wygenerowany plik Bicep odzwierciedla rzeczywistą usługę Azure, a nie lokalny kontener.

Zrozumienie interfejsów API integracji Azure

.NET .NET Aspiresiła leży w jego zdolności do zapewnienia niesamowitej wewnętrznej pętli deweloperów. Integracje Azure niczym się nie różnią. Udostępniają zestaw typowych interfejsów API i wzorców, które są współużytkowane we wszystkich zasobach Azure. Te interfejsy API i wzorce zostały zaprojektowane tak, aby ułatwić pracę z zasobami Azure w spójny sposób.

W poprzedniej sekcji kontenerów pokazano, jak uruchamiać usługi Azure lokalnie w kontenerach. Jeśli znasz .NET.NET Aspire, możesz się zastanawiać, jak wywoływanie AddAzureRedis("redis").RunAsContainer() w celu uzyskania kontenera docker.io/library/redis lokalnego różni się od AddRedis("redis")— ponieważ oba te elementy powodują ten sam kontener lokalny.

Odpowiedź to, że przy lokalnym uruchomieniu nie ma różnicy. Jednak po ich opublikowaniu otrzymujesz różne zasoby:

Interfejs Programowania Aplikacji (API) Tryb działania Tryb publikowania
AddAzureRedis("redis").RunAsContainer() Lokalny kontener Redis Azure Cache for Redis
AddRedis("redis") Lokalny kontener Redis Azure kontenerowa aplikacja z obrazem Redis

To samo dotyczy usług SQL i PostgreSQL:

Interfejs Programowania Aplikacji (API) Tryb pracy Tryb publikowania
AddAzurePostgresFlexibleServer("postgres").RunAsContainer() Lokalny kontener PostgreSQL Azure PostgreSQL elastyczne Server
addPostgres("postgres") Lokalny kontener PostgreSQL Azure aplikacja kontenerowa z obrazem PostgreSQL
AddAzureSqlServer("sql").RunAsContainer() Lokalny kontener SQL Server Azure SQL Server
AddSqlServer("sql") Lokalny kontener SQL Server Azure aplikacja kontenerowa z obrazem SQL Server

Aby uzyskać więcej informacji na temat różnicy między trybami uruchamiania i publikowania, zobacz .NET.NET Aspire host aplikacji: kontekst wykonywania.

API do przedstawiania zasobów Azure w różnych trybach

Konstruktor aplikacji rozproszonych, będący częścią hosta aplikacji , używa wzorca konstruktora do dodania zasobów do modelu aplikacji . Deweloperzy mogą konfigurować te zasoby i definiować ich zachowanie w różnych kontekstach wykonywania. Integracje hostingu Azure oferują interfejsy API, aby określić, w jaki sposób te zasoby powinny być „opublikowane” i „uruchamiane”.

Gdy host aplikacji jest wykonywany, kontekst wykonywania służy do określania, czy host aplikacji znajduje się w trybie Run czy Publish. Konwencje nazewnictwa dla tych interfejsów API wskazują na akcję przeznaczoną dla zasobu.

Poniższa tabela zawiera podsumowanie konwencji nazewnictwa używanych do wyrażania Azure zasobów:

Operacja Interfejs Programowania Aplikacji (API) Opis
Opublikuj PublishAsConnectionString<T>(IResourceBuilder<T>) Zmienia zasób, który ma zostać opublikowany jako odwołanie do parametrów połączenia w manifeście.
Opublikuj PublishAsExisting Używa istniejącego zasobu Azure podczas wdrażania aplikacji zamiast tworzenia nowego zasobu.
Biegnij AzureSqlExtensions.RunAsContainer(IResourceBuilder<AzureSqlServerResource>, Action<IResourceBuilder<SqlServerServerResource>>)
AzureRedisExtensions.RunAsContainer(IResourceBuilder<AzureRedisCacheResource>, Action<IResourceBuilder<RedisResource>>)
RunAsContainer(IResourceBuilder<AzurePostgresFlexibleServerResource>, Action<IResourceBuilder<PostgresServerResource>>)
Konfiguruje równoważny kontener do uruchamiania lokalnego. Aby uzyskać więcej informacji, zobacz Kontenery lokalne.
Biegnij AzureCosmosExtensions.RunAsEmulator(IResourceBuilder<AzureCosmosDBResource>, Action<IResourceBuilder<AzureCosmosDBEmulatorResource>>)
AzureSignalRExtensions.RunAsEmulator(IResourceBuilder<AzureSignalRResource>, Action<IResourceBuilder<AzureSignalREmulatorResource>>)
AzureStorageExtensions.RunAsEmulator(IResourceBuilder<AzureStorageResource>, Action<IResourceBuilder<AzureStorageEmulatorResource>>)
AzureEventHubsExtensions.RunAsEmulator(IResourceBuilder<AzureEventHubsResource>, Action<IResourceBuilder<AzureEventHubsEmulatorResource>>)
AzureServiceBusExtensions.RunAsEmulator(IResourceBuilder<AzureServiceBusResource>, Action<IResourceBuilder<AzureServiceBusEmulatorResource>>)
Konfiguruje zasób Azure do emulowania. Aby uzyskać więcej informacji, zobacz Lokalne emulatory.
Biegnij RunAsExisting Używa istniejącego zasobu, gdy aplikacja jest uruchomiona, zamiast tworzyć nowe.
Opublikuj i uruchom AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) Używa istniejącego zasobu niezależnie od operacji.

Notatka

Nie wszystkie interfejsy API są dostępne we wszystkich zasobach Azure. Na przykład niektóre zasoby Azure mogą być konteneryzowane lub emulowane, a inne nie mogą.

Aby uzyskać więcej informacji na temat trybów wykonywania, zobacz Kontekst wykonywania.

Ogólne przypadki użycia interfejsu API w trybie uruchomienia

Użyj RunAsExisting, gdy musisz dynamicznie korzystać z istniejącego zasobu w czasie wykonywania bez konieczności wdrażania lub aktualizowania go. Użyj PublishAsExisting podczas deklarowania istniejących zasobów w ramach konfiguracji wdrożenia, zapewniając stosowanie prawidłowych zakresów i uprawnień. Na koniec należy użyć AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) podczas deklarowania istniejących zasobów w obu konfiguracjach, z wymogiem sparametryzowania odwołań.

Możesz wykonać zapytanie o to, czy zasób jest oznaczony jako istniejący zasób, wywołując metodę rozszerzenia IsExisting(IResource) w IResource. Aby uzyskać więcej informacji, zobacz Użyj istniejących Azure zasobów.

Użyj istniejących zasobów Azure

.NET Aspire zapewnia obsługę odwoływania się do istniejących zasobów Azure. Istniejący zasób można oznaczyć za pomocą interfejsów API PublishAsExisting, RunAsExistingi AsExisting. Te interfejsy API umożliwiają deweloperom odwołowanie się do już wdrożonych zasobów Azure, ich konfigurowanie i generowanie odpowiednich manifestów wdrażania przy użyciu szablonów Bicep.

Istniejące zasoby, do których odwołują się te interfejsy API, można wzbogacić poprzez przypisania ról oraz inne dostosowania, które są dostępne dzięki możliwościom infrastruktury jako kodu oferowanym przez . Te interfejsy API są ograniczone do zasobów Azure, które można wdrożyć za pomocą szablonów Bicep.

Konfigurowanie istniejących zasobów Azure dla trybu uruchamiania

Metoda RunAsExisting jest używana, gdy aplikacja rozproszona jest uruchamiana w trybie "uruchom". W tym trybie przyjęto założenie, że przywołany zasób Azure już istnieje i integruje się z nim podczas wykonywania bez przygotowywania tego zasobu. Aby oznaczyć zasób Azure jako istniejący, wywołaj metodę RunAsExisting w konstruktorze zasobów. Rozważmy następujący przykład:

var builder = DistributedApplication.CreateBuilder();

var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");

var serviceBus = builder.AddAzureServiceBus("messaging")
                        .RunAsExisting(existingServiceBusName, existingServiceBusResourceGroup);

serviceBus.AddServiceBusQueue("queue");

Powyższy kod:

  • Tworzy nowy obiekt builder.
  • Dodaje do konstruktora parametr o nazwie existingServiceBusName.
  • Dodaje do konstruktora zasób Azure Service Bus o nazwie messaging.
  • Wywołuje metodę RunAsExisting w konstruktorze zasobów serviceBus, przekazując parametr existingServiceBusName — alternatywnie można użyć przeciążenia parametru string.
  • Dodaje kolejkę o nazwie queue do zasobu serviceBus.

Domyślnie przyjmuje się, że odwołanie do parametrów usługi Service Bus znajduje się w tej samej grupie zasobów Azure. Jeśli jednak znajduje się w innej grupie zasobów, możesz jawnie przekazać grupę zasobów jako parametr, aby poprawnie określić odpowiednie grupowanie zasobów.

Konfigurowanie istniejących zasobów Azure dla trybu publikowania

Metoda PublishAsExisting jest używana w trybie "publikowania", gdy intencją jest zadeklarowanie i odwołanie do istniejącego zasobu Azure w trybie publikowania. Ten interfejs API ułatwia tworzenie manifestów i szablonów, które zawierają definicje zasobów odpowiadające istniejącym zasobom w Bicep.

Aby oznaczyć zasób Azure jako istniejący w trybie "publikowania", wywołaj metodę PublishAsExisting w konstruktorze zasobów. Rozważmy następujący przykład:

var builder = DistributedApplication.CreateBuilder();

var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");

var serviceBus = builder.AddAzureServiceBus("messaging")
                        .PublishAsExisting(existingServiceBusName, existingServiceBusResourceGroup);

serviceBus.AddServiceBusQueue("queue");

Powyższy kod:

  • Tworzy nowy obiekt builder.
  • Dodaje do konstruktora parametr o nazwie existingServiceBusName.
  • Dodaje do konstruktora zasób Azure Service Bus o nazwie messaging.
  • Wywołuje metodę PublishAsExisting w konstruktorze zasobów serviceBus, przekazując parametr existingServiceBusName — alternatywnie można użyć przeciążenia parametru string.
  • Dodaje kolejkę o nazwie queue do zasobu serviceBus.

Po uruchomieniu hosta aplikacji w trybie publikowania wygenerowany plik manifestu będzie zawierać parametr existingResourceName, który może być użyty do odwołania się do istniejącego zasobu Azure. Rozważmy następujący wygenerowany fragment pliku manifestu:

"messaging": {
  "type": "azure.bicep.v0",
  "connectionString": "{messaging.outputs.serviceBusEndpoint}",
  "path": "messaging.module.bicep",
  "params": {
    "existingServiceBusName": "{existingServiceBusName.value}",
    "principalType": "",
    "principalId": ""
  }
},
"queue": {
  "type": "value.v0",
  "connectionString": "{messaging.outputs.serviceBusEndpoint}"
}

Aby uzyskać więcej informacji na temat pliku manifestu, zobacz .NET.NET Aspire format manifestu dla konstruktorów narzędzi wdrażania.

Ponadto wygenerowany szablon Bicep zawiera parametr existingResourceName, który może służyć do odwołowania się do istniejącego zasobu Azure. Rozważmy następujący wygenerowany szablon Bicep:

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

param existingServiceBusName string

param principalType string

param principalId string

resource messaging 'Microsoft.ServiceBus/namespaces@2024-01-01' existing = {
  name: existingServiceBusName
}

resource messaging_AzureServiceBusDataOwner 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(messaging.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419'))
  properties: {
    principalId: principalId
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')
    principalType: principalType
  }
  scope: messaging
}

resource queue 'Microsoft.ServiceBus/namespaces/queues@2024-01-01' = {
  name: 'queue'
  parent: messaging
}

output serviceBusEndpoint string = messaging.properties.serviceBusEndpoint

Aby uzyskać więcej informacji na temat wygenerowanych szablonów Bicep, zapoznaj się z Infrastruktura jako kod oraz rozważ inne interfejsy API do publikowania.

Ostrzeżenie

Podczas interakcji z istniejącymi zasobami, które wymagają uwierzytelniania, upewnij się, że strategia uwierzytelniania konfigurowana w modelu aplikacji .NET.NET Aspire jest zgodna ze strategią uwierzytelniania dozwoloną przez istniejący zasób. Na przykład nie można używać tożsamości zarządzanej względem istniejącego zasobu AzurePostgreSQL, który nie jest skonfigurowany do zezwalania na tożsamość zarządzaną. Podobnie jeśli istniejący zasób AzureRedis wyłączył klucze dostępu, nie można użyć uwierzytelniania klucza dostępu.

Skonfiguruj istniejące zasoby Azure we wszystkich trybach

Metoda AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) jest używana, gdy aplikacja rozproszona jest uruchomiona w trybie "run" lub "publish". Ponieważ metoda AsExisting działa w obu scenariuszach, obsługuje tylko sparametryzowane odwołanie do nazwy zasobu lub nazwy grupy zasobów. Takie podejście pomaga zapobiegać używaniu tego samego zasobu zarówno w środowiskach testowych, jak i produkcyjnych.

Aby oznaczyć zasób Azure jako istniejący, wywołaj metodę AsExisting w konstruktorze zasobów. Rozważmy następujący przykład:

var builder = DistributedApplication.CreateBuilder();

var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");

var serviceBus = builder.AddAzureServiceBus("messaging")
                        .AsExisting(existingServiceBusName, existingServiceBusResourceGroup);

serviceBus.AddServiceBusQueue("queue");

Powyższy kod:

  • Tworzy nowy obiekt builder.
  • Dodaje do konstruktora parametr o nazwie existingServiceBusName.
  • Dodaje do konstruktora zasób Azure Service Bus o nazwie messaging.
  • Wywołuje metodę AsExisting w konstruktorze zasobów serviceBus, przekazując parametr existingServiceBusName.
  • Dodaje kolejkę o nazwie queue do zasobu serviceBus.

Dodawanie istniejących zasobów Azure z parametrami połączenia

.NET .NET Aspire umożliwia nawiązywanie połączenia z istniejącymi zasobami, w tym z zasobami Azure. Wyrażanie parametrów połączenia jest przydatne, gdy masz istniejące zasoby Azure, które mają być używane w aplikacji .NET Aspire. Interfejs API AddConnectionString jest używany z kontekstem wykonywania hosta aplikacji w celu dodania łańcucha połączenia do modelu aplikacji pod określonymi warunkami.

Notatka

Parametry połączenia służą do reprezentowania szerokiego zakresu informacji o połączeniu, w tym połączeń z bazą danych, brokerów komunikatów, identyfikatorów URI punktów końcowych i innych usług. W .NET.NET Aspire nomenklaturze termin "parametry połączenia" służy do reprezentowania wszelkich informacji o połączeniu.

Rozważmy poniższy przykład, w którym w trybie publikowania dodaj zasób Azure Storage, podczas gdy w trybie uruchamiania należy dodać ciąg połączenia do istniejącego Azure magazynu:

var builder = DistributedApplication.CreateBuilder(args);

var storage = builder.ExecutionContext.IsPublishMode
    ? builder.AddAzureStorage("storage")
    : builder.AddConnectionString("storage");

builder.AddProject<Projects.Api>("api")
       .WithReference(storage);

// After adding all resources, run the app...

Powyższy kod:

  • Tworzy nowy obiekt builder.
  • Dodaje zasób usługi Azure Storage o nazwie storage w trybie publikacji.
  • Dodaje ciąg połączenia do istniejącego magazynu Azure o nazwie storage w trybie pracy.
  • Dodaje projekt o nazwie api do konstruktora.
  • Projekt api odwołuje się do zasobu storage niezależnie od trybu.

Projekt korzystający z interfejsu API używa informacji o parametrach połączenia bez wiedzy o tym, jak host aplikacji go skonfigurował. W trybie "publikowania" kod dodaje nowy zasób usługi Storage Azure — który zostanie odzwierciedlony w manifeście wdrożenia odpowiednio. W trybie "uruchom" parametry połączenia odpowiadają wartości konfiguracji widocznej dla hosta aplikacji. Przyjmuje się, że wszystkie przypisania ról dla zasobu docelowego są skonfigurowane. Oznacza to, że prawdopodobnie skonfigurujesz zmienną środowiskową lub tajny klucz użytkownika w celu przechowywania łańcucha połączenia. Konfiguracja jest rozpoznawana z klucza konfiguracji ConnectionStrings__storage (lub ConnectionStrings:storage). Te wartości konfiguracji można wyświetlić po uruchomieniu aplikacji. Aby uzyskać więcej informacji, zobacz szczegóły zasobu.

W przeciwieństwie do istniejących zasobów, które są modelowane za pomocą pierwszej klasy interfejsu API AsExisting, istniejące zasoby modelowane jako parametry połączenia nie mogą być ulepszane poprzez dodatkowe przypisania ról ani dostosowania infrastruktury.

Opublikuj jako aplikacja kontenera Azure

.NET .NET Aspire pozwala publikować zasoby prymitywne jako Azure Container Apps, bezserwerową platformę, która zmniejsza konieczność zarządzania infrastrukturą. Obsługiwane typy zasobów obejmują:

Aby opublikować te zasoby, użyj następujących interfejsów API:

Te interfejsy API umożliwiają skonfigurowanie zasobu do opublikowania jako aplikacji kontenera Azure i niejawne wywołanie AddAzureContainerAppsInfrastructure(IDistributedApplicationBuilder) w celu dodania niezbędnej infrastruktury i plików Bicep do hosta aplikacji. Rozważmy na przykład następujący kod:

var builder = DistributedApplication.CreateBuilder();

var env = builder.AddParameter("env");

var api = builder.AddProject<Projects.AspireApi>("api")
                 .PublishAsAzureContainerApp<Projects.AspireApi>((infra, app) =>
                 {
                     app.Template.Containers[0].Value!.Env.Add(new ContainerAppEnvironmentVariable
                     {
                         Name = "Hello",
                         Value = env.AsProvisioningParameter(infra)
                     });
                 });

Powyższy kod:

  • Tworzy nowy obiekt builder.
  • Dodaje do konstruktora parametr o nazwie env.
  • Dodaje projekt o nazwie api do kompilatora.
  • Wywołuje metodę PublishAsAzureContainerApp w konstruktorze zasobów api, przekazując wyrażenie lambda, które konfiguruje infrastrukturę aplikacji kontenerowej Azure—gdzie infra jest AzureResourceInfrastructure, a app jest ContainerApp.
    • Dodaje zmienną środowiskową o nazwie Hello do aplikacji kontenera przy użyciu parametru env.
    • Metoda AsProvisioningParameter jest używana do traktowania env jako nowego ProvisioningParameter w infrastrukturze lub ponownego użycia istniejącego parametru bicep, jeśli taki o tej samej nazwie już istnieje.

Aby uzyskać więcej informacji, zobacz ContainerApp oraz AsProvisioningParameter.

Infrastruktura jako kod

Zestaw Azure SDK dla .NET dostarcza pakiet NuGet 📦Azure.Provisioning oraz zestaw pakietów aprowizacyjnych specyficznych dla usług Azure. Te biblioteki aprowizacyjne Azure ułatwiają deklaratywne definiowanie infrastruktury Azure natywnie w .NET. Ich API umożliwiają pisanie infrastruktury zorientowanej obiektowo w języku C#, w wyniku czego powstaje Bicep. Bicep to język specyficzny dla domeny (DSL) do deklaratywnego wdrażania zasobów Azure.

Chociaż można aprowizować zasoby Azure ręcznie, .NET Aspire upraszcza proces, udostępniając zestaw interfejsów API do wyrażania Azure zasobów. Te API są dostępne jako metody rozszerzeń w .NET AspireAzure bibliotekach hostujących, rozszerzających interfejs IDistributedApplicationBuilder. Gdy dodasz zasoby Azure do hosta aplikacji, automatycznie zostaje dodana odpowiednia funkcja aprowizacji. Innymi słowy, nie musisz bezpośrednio wywoływać żadnych interfejsów API do konfigurowania.

Ponieważ modele .NET Aspire zasoby Azure w integracjach hostingu Azure, zestaw SDK Azure służy do aprowizowania zasobów. Generowane są pliki Bicep, które definiują zasoby potrzebne do Azure. Wygenerowane pliki Bicep są generowane razem z plikiem manifestu przy publikowaniu aplikacji.

Istnieje kilka sposobów wpływania na wygenerowane pliki Bicep:

Lokalne zaopatrzenie i Azure.Provisioning

Aby uniknąć mieszania terminów i pomóc w doprecyzowaniu "konfiguracji," ważne jest, aby zrozumieć różnicę między lokalnym a Azure provisioningiem:

  • Lokalne dostarczanie:

    Domyślnie podczas wywoływania dowolnego z hostujących API integracji, aby dodać zasoby, wywołuje się niejawnie interfejs API . API rejestruje usługi w kontenerze wstrzykiwania zależności (DI), które są używane do konfigurowania zasobów Azure gdy host aplikacji się uruchamia. Ta koncepcja jest znana jako lokalne zaopatrzenie. Aby uzyskać więcej informacji, zobacz lokalne Azure udostępnianie.

  • Azure.Provisioning:

    Azure.Provisioning odnosi się do pakietu NuGet i jest zestawem bibliotek, które umożliwiają generowanie Bicep za pomocą języka C#. Azure integracje hostingowe w .NET Aspire używają tych bibliotek niezauważalnie do generowania plików Bicep, które definiują zasoby Azure, jakich potrzebujesz. Aby uzyskać więcej informacji, zobacz Azure.Provisioning dostosowywanie.

personalizacja Azure.Provisioning

Wszystkie integracje hostingu .NET AspireAzure uwidaczniają różne zasoby Azure i wszystkie są podklasami typu AzureProvisioningResource — który dziedziczy AzureBicepResource. To umożliwia rozszerzeniom, które są ograniczone do tego typu poprzez generyczne typy, korzystanie z płynnego i intuicyjnego interfejsu API, aby dostosować infrastrukturę do własnych potrzeb. Mimo że .NET i .NET Aspire udostępniają wartości domyślne, masz możliwość wpływania na wygenerowany Bicep za pomocą tych interfejsów API.

Konfigurowanie infrastruktury

Niezależnie od tego, z jakim zasobem Azure pracujesz, aby skonfigurować jego podstawową infrastrukturę, wywołujesz metodę rozszerzenia ConfigureInfrastructure. Ta metoda umożliwia personalizację infrastruktury zasobu Azure przez przekazanie delegata configure typu Action<AzureResourceInfrastructure>. Typ AzureResourceInfrastructure jest podklasą Azure.Provisioning.Infrastructure. Ten typ uwidacznia ogromny obszar powierzchni interfejsu API na potrzeby konfigurowania podstawowej infrastruktury zasobu Azure.

Rozważmy następujący przykład:

var sku = builder.AddParameter("storage-sku");

var storage = builder.AddAzureStorage("storage")
    .ConfigureInfrastructure(infra =>
    {
        var resources = infra.GetProvisionableResources();

        var storageAccount = resources.OfType<StorageAccount>().Single();

        storageAccount.Sku = new StorageSku
        {
            Name = sku.AsProvisioningParameter(infra)
        };
    });

Powyższy kod:

  • Dodaje parametr o nazwie storage-sku.
  • Dodaje usługę Azure Storage przy użyciu interfejsu API AddAzureStorage o nazwie storage.
  • Połączenie wywołania do ConfigureInfrastructure w celu dostosowania infrastruktury przechowywania Azure:

Spowoduje to przepływ parametru zewnętrznego do infrastruktury magazynu Azure, co spowoduje, że wygenerowany plik Bicep odzwierciedla żądaną konfigurację.

Dodaj infrastrukturę Azure

Nie wszystkie usługi Azure są udostępniane jako integracje .NET Aspire. Choć mogą być dostępne później, nadal można świadczyć usługi, które są dostępne w bibliotekach Azure.Provisioning.*. Wyobraź sobie scenariusz, w którym masz usługę roboczą odpowiedzialną za zarządzanie rejestrem kontenerów Azure. Teraz wyobraź sobie, że projekt hosta aplikacji przyjmuje zależność od 📦Azure.Provisioning.ContainerRegistry pakietu NuGet.

Interfejs API AddAzureInfrastructure umożliwia dodanie infrastruktury usługi Azure Container Registry do hosta aplikacji:

var acr = builder.AddAzureInfrastructure("acr", infra =>
{
    var registry = new ContainerRegistryService("acr")
    {
        Sku = new()
        {
            Name = ContainerRegistrySkuName.Standard
        },
    };
    infra.Add(registry);

    var output = new ProvisioningOutput("registryName", typeof(string))
    {
        Value = registry.Name
    };
    infra.Add(output);
});

builder.AddProject<Projects.WorkerService>("worker")
       .WithEnvironment(
            "ACR_REGISTRY_NAME",
            new BicepOutputReference("registryName", acr.Resource));

Powyższy kod:

  • Wywołuje AddAzureInfrastructure z nazwą acr.
  • Udostępnia delegata configureInfrastructure w celu dostosowania infrastruktury usługi Azure Container Registry:
    • Tworzy instancję ContainerRegistryService o nazwie acr i standardowym SKU.
    • Dodaje usługę Azure Container Registry do zmiennej infra.
    • Tworzy wystąpienie ProvisioningOutput o nazwie registryName, o typie stringi o wartości odpowiadającej nazwie rejestru kontenerów Azure.
    • Dodaje dane wyjściowe do zmiennej infra.
  • Dodaje projekt o nazwie worker do narzędzia budującego.
  • Łączy wywołanie do WithEnvironment, by ustawić zmienną środowiskową ACR_REGISTRY_NAME w projekcie na wartość wyjściową registryName.

Funkcja pokazuje, jak dodać infrastrukturę Azure do projektu hosta aplikacji, nawet jeśli usługa Azure nie jest bezpośrednio uwidoczniona jako integracja z .NET Aspire. Dodatkowo pokazano, jak kierować wyniki rejestru kontenerów Azure do środowiska projektu zależnego.

Przeanalizuj wynikowy plik Bicep:

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
  name: take('acr${uniqueString(resourceGroup().id)}', 50)
  location: location
  sku: {
    name: 'Standard'
  }
}

output registryName string = acr.name

Plik Bicep odzwierciedla żądaną konfigurację Azure Container Registry, zgodnie z definicją w AddAzureInfrastructure API.

Użyj niestandardowych szablonów Bicep

Jeśli jako docelowego dostawcę usług w chmurze wybierzesz Azure, możesz użyć narzędzia Bicep do definiowania infrastruktury jako kodu. Ma ona na celu drastyczne uproszczenie środowiska tworzenia przy użyciu czystszej składni i lepszej obsługi modułowości i ponownego użycia kodu.

Chociaż .NET.NET Aspire udostępnia zestaw wstępnie utworzonych szablonów Bicep, mogą wystąpić czasy, kiedy chcesz dostosować szablony lub utworzyć własne. W tej sekcji opisano pojęcia i odpowiednie interfejsy API, których można użyć do dostosowywania szablonów Bicep.

Ważny

Ta sekcja nie jest przeznaczona do nauki Bicep, ale raczej do zapewnienia wskazówek dotyczących sposobu tworzenia niestandardowych szablonów Bicep do użycia z .NET.NET Aspire.

W ramach scenariusza wdrażania Azure dla .NET Aspireprogram Azure Developer CLI (azd) dostarcza wgląd w projekt .NET Aspire oraz umożliwia jego wdrażanie do Azure. Interfejs wiersza polecenia azd używa szablonów Bicep w celu wdrożenia aplikacji do Azure.

Instalowanie pakietu Aspire.Hosting.Azure

Jeśli chcesz odwołać się do plików Bicep, możliwe, że nie korzystasz z żadnej z integracji hostingowych Azure. W takim przypadku nadal można odwoływać się do plików Bicep, instalując pakiet Aspire.Hosting.Azure. Ten pakiet udostępnia niezbędne interfejsy API do odwoływania się do plików Bicep i dostosowywania zasobów Azure.

Napiwek

Jeśli używasz dowolnej z Azure integracji hostingu, nie musisz instalować pakietu Aspire.Hosting.Azure, ponieważ jest to zależność przechodnia.

Aby użyć dowolnej z tych funkcji, należy zainstalować pakiet NuGet: 📦Aspire.Hosting.Azure

dotnet add package Aspire.Hosting.Azure

Aby uzyskać więcej informacji, zobacz dotnet add package lub Zarządzaj zależnościami pakietów w aplikacjach .NET.

Czego można oczekiwać na podstawie przykładów

We wszystkich przykładach w tej sekcji założono, że używasz przestrzeni nazw Aspire.Hosting.Azure. Ponadto w przykładach założono, że masz wystąpienie IDistributedApplicationBuilder:

using Aspire.Hosting.Azure;

var builder = DistributedApplication.CreateBuilder(args);

// Examples go here...

builder.Build().Run();

Domyślnie, gdy wywołujesz dowolne API związane z Bicepem, również wykonywane jest żądanie do AddAzureProvisioning, które dodaje wsparcie dla dynamicznego generowania zasobów Azure przy uruchamianiu aplikacji. Aby uzyskać więcej informacji, zobacz lokalne zaopatrzenie Azure.Provisioning.

Pliki referencyjne Bicep

Załóżmy, że masz szablon Bicep w pliku o nazwie storage.bicep, który tworzy konto magazynowe Azure.

param location string = resourceGroup().location
param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

Aby dodać odwołanie do pliku Bicep na dysku, wywołaj metodę AddBicepTemplate. Rozważmy następujący przykład:

builder.AddBicepTemplate(
    name: "storage",
    bicepFile: "../infra/storage.bicep");

Powyższy kod dodaje odwołanie do pliku Bicep znajdującego się w ../infra/storage.bicep. Ścieżki plików powinny odnosić się do projektu hosta aplikacji. Ta referencja powoduje dodanie AzureBicepResource do kolekcji zasobów aplikacji z nazwą "storage", a interfejs API zwraca instancję klasy IResourceBuilder<AzureBicepResource>, której można użyć do dalszego dostosowywania zasobu.

Odwołanie do elementu Bicep w tekście

Posiadanie pliku Bicep na dysku jest najczęstszym scenariuszem, ale można również dodać szablony Bicep w trybie inline. Szablony wbudowane mogą być przydatne, gdy chcesz zdefiniować szablon w kodzie lub gdy chcesz dynamicznie wygenerować szablon. Aby dodać wbudowany szablon Bicep, wywołaj metodę AddBicepTemplateString, używając szablonu Bicep jako string. Rozważmy następujący przykład:

builder.AddBicepTemplateString(
        name: "ai",
        bicepContent: """
        @description('That name is the name of our application.')
        param cognitiveServiceName string = 'CognitiveService-${uniqueString(resourceGroup().id)}'

        @description('Location for all resources.')
        param location string = resourceGroup().location

        @allowed([
          'S0'
        ])
        param sku string = 'S0'

        resource cognitiveService 'Microsoft.CognitiveServices/accounts@2021-10-01' = {
          name: cognitiveServiceName
          location: location
          sku: {
            name: sku
          }
          kind: 'CognitiveServices'
          properties: {
            apiProperties: {
              statisticsEnabled: false
            }
          }
        }
        """
    );

W tym przykładzie szablon Bicep jest definiowany jako element wbudowany string i dodawany do kolekcji zasobów aplikacji pod nazwą "ai". W tym przykładzie udostępnia się zasób sztucznej inteligencji Azure.

Przekaż parametry do szablonów Bicep

Bicep obsługuje akceptowanie parametrów, które mogą służyć do dostosowywania zachowania szablonu. Aby przekazać parametry do szablonu Bicep z .NET.NET Aspire, należy wywołać metodę WithParameter w sposób pokazany w poniższym przykładzie:

var region = builder.AddParameter("region");

builder.AddBicepTemplate("storage", "../infra/storage.bicep")
       .WithParameter("region", region)
       .WithParameter("storageName", "app-storage")
       .WithParameter("tags", ["latest","dev"]);

Powyższy kod:

  • Dodaje parametr o nazwie "region" do wystąpienia builder.
  • Dodaje odniesienie do pliku Bicep znajdującego się w ../infra/storage.bicep.
  • Przekazuje parametr "region" do szablonu Bicep, który jest rozstrzygany za pomocą standardowej metody rozstrzygania parametrów.
  • Przekazuje parametr "storageName" do szablonu Bicep z wartością na stałe określoną.
  • Przekazuje parametr "tags" do szablonu Bicep z tablicą ciągów.

Aby uzyskać więcej informacji, zobacz Parametry zewnętrzne.

Dobrze znane parametry

.NET .NET Aspire udostępnia zestaw dobrze znanych parametrów, które można przekazać do szablonów Bicep. Te parametry służą do dostarczania informacji o aplikacji i środowisku do szablonów Bicep. Dostępne są następujące dobrze znane parametry:

Pole Opis Wartość
AzureBicepResource.KnownParameters.KeyVaultName Nazwa zasobu magazynu kluczy używana do przechowywania tajnych danych wyjściowych. "keyVaultName"
AzureBicepResource.KnownParameters.Location Lokalizacja zasobu. Jest to wymagane dla wszystkich zasobów. "location"
AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId Identyfikator zasobu obszaru roboczego usługi Log Analytics. "logAnalyticsWorkspaceId"
AzureBicepResource.KnownParameters.PrincipalId Identyfikator główny bieżącego użytkownika lub tożsamości zarządzanej. "principalId"
AzureBicepResource.KnownParameters.PrincipalName Główna nazwa bieżącego użytkownika lub tożsamości zarządzanej. "principalName"
AzureBicepResource.KnownParameters.PrincipalType Typ główny obecnego użytkownika lub tożsamości zarządzanej. User lub ServicePrincipal. "principalType"

Aby użyć dobrze znanego parametru, przekaż nazwę parametru do metody WithParameter, takiej jak WithParameter(AzureBicepResource.KnownParameters.KeyVaultName). Nie przekazujesz wartości dla dobrze znanych parametrów, ponieważ .NET.NET Aspire rozpoznaje je w Twoim imieniu.

Rozważmy przykład, w którym chcesz skonfigurować webhook Azure usługi Event Grid. Szablon Bicep można zdefiniować w następujący sposób:

param topicName string
param webHookEndpoint string
param principalId string
param principalType string
param location string = resourceGroup().location

// The topic name must be unique because it's represented by a DNS entry. 
// must be between 3-50 characters and contain only values a-z, A-Z, 0-9, and "-".

resource topic 'Microsoft.EventGrid/topics@2023-12-15-preview' = {
  name: toLower(take('${topicName}${uniqueString(resourceGroup().id)}', 50))
  location: location

  resource eventSubscription 'eventSubscriptions' = {
    name: 'customSub'
    properties: {
      destination: {
        endpointType: 'WebHook'
        properties: {
          endpointUrl: webHookEndpoint
        }
      }
    }
  }
}

resource EventGridRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(topic.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7'))
  scope: topic
  properties: {
    principalId: principalId
    principalType: principalType
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7')
  }
}

output endpoint string = topic.properties.endpoint

Ten szablon Bicep definiuje kilka parametrów, w tym topicName, webHookEndpoint, principalId, principalTypei opcjonalny location. Aby przekazać te parametry do szablonu Bicep, możesz użyć następującego fragmentu kodu:

var webHookApi = builder.AddProject<Projects.WebHook_Api>("webhook-api");

var webHookEndpointExpression = ReferenceExpression.Create(
        $"{webHookApi.GetEndpoint("https")}/hook");

builder.AddBicepTemplate("event-grid-webhook", "../infra/event-grid-webhook.bicep")
       .WithParameter("topicName", "events")
       .WithParameter(AzureBicepResource.KnownParameters.PrincipalId)
       .WithParameter(AzureBicepResource.KnownParameters.PrincipalType)
       .WithParameter("webHookEndpoint", () => webHookEndpointExpression);
  • Projekt webHookApi jest dodawany jako odwołanie do builder.
  • Parametr topicName jest przekazywany jako wartość nazwy zakodowanej na stałe.
  • Parametr webHookEndpoint jest przekazywany jako wyrażenie rozpoznawane jako adres URL z punktu końcowego "https" api projektu z trasą /hook.
  • Parametry principalId i principalType są przekazywane jako dobrze znane parametry.

Dobrze znane parametry są oparte na konwencji i nie powinny być dołączone do odpowiedniej wartości podczas przekazywania przy użyciu interfejsu API WithParameter. Znane parametry upraszczają niektóre typowe funkcje, takie jak przypisania ról, gdy są dodane do szablonów Bicep, co pokazano w poprzednim przykładzie. Przypisania ról są wymagane, aby webhook usługi Event Grid mógł wysyłać zdarzenia do określonego punktu końcowego. Aby uzyskać więcej informacji, zobacz przypisanie roli nadawcy danych w Event Grid.

Pobieranie danych wyjściowych z odwołań Bicep

Oprócz przekazywania parametrów do szablonów Bicep można również uzyskać dane wyjściowe z szablonów Bicep. Rozważmy następujący szablon Bicep, który definiuje output o nazwie endpoint:

param storageName string
param location string = resourceGroup().location

resource myStorageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: storageName
  location: location
  kind: 'StorageV2'
  sku:{
    name:'Standard_LRS'
    tier: 'Standard'
  }
  properties: {
    accessTier: 'Hot'
  }
}

output endpoint string = myStorageAccount.properties.primaryEndpoints.blob

Bicep definiuje dane wyjściowe o nazwie endpoint. Aby pobrać dane wyjściowe z szablonu Bicep, wywołaj metodę GetOutput w wystąpieniu IResourceBuilder<AzureBicepResource>, jak pokazano w poniższym fragmencie kodu języka C#:

var storage = builder.AddBicepTemplate(
        name: "storage",
        bicepFile: "../infra/storage.bicep"
    );

var endpoint = storage.GetOutput("endpoint");

W tym przykładzie dane wyjściowe z szablonu Bicep są pobierane i przechowywane w zmiennej endpoint. Zazwyczaj te dane wyjściowe są przekazywane jako zmienna środowiskowa do innego zasobu, który na nim bazuje. Jeśli na przykład masz projekt interfejsu API ASP.NET Core minimalny, który zależy od tego punktu końcowego, możesz przekazać dane wyjściowe jako zmienną środowiskową do projektu przy użyciu następującego fragmentu kodu:

var storage = builder.AddBicepTemplate(
                name: "storage",
                bicepFile: "../infra/storage.bicep"
            );

var endpoint = storage.GetOutput("endpoint");

var apiService = builder.AddProject<Projects.AspireSample_ApiService>(
        name: "apiservice"
    )
    .WithEnvironment("STORAGE_ENDPOINT", endpoint);

Aby uzyskać więcej informacji, sprawdź dane wyjściowe Bicepa.

Uzyskaj ukryte dane wyjściowe z odwołań Bicep

Ważne jest, aby unikać danych wyjściowych dla tajnych informacji podczas pracy z Bicep. Jeśli dane wyjściowe są uznawane za tajemnicę , co oznacza, że nie powinny być widoczne w dziennikach lub innych miejscach, można je traktować jako takie. Można to osiągnąć, przechowując tajemnicę w Azure Key Vault i odnosząc się do niej w szablonie Bicep. Integracja .NET AspireAzure zapewnia wzorzec bezpiecznego przechowywania danych wyjściowych z szablonu Bicep, pozwalając zasobom na użycie parametru keyVaultName do przechowywania wpisów tajnych w Azure Key Vault.

Rozważmy następujący szablon Bicep jako przykład, który pomaga zademonstrować tę koncepcję zabezpieczania tajnych danych wyjściowych:

param databaseAccountName string
param keyVaultName string

param databases array = []

@description('Tags that will be applied to all resources')
param tags object = {}

param location string = resourceGroup().location

var resourceToken = uniqueString(resourceGroup().id)

resource cosmosDb 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' = {
    name: replace('${databaseAccountName}-${resourceToken}', '-', '')
    location: location
    kind: 'GlobalDocumentDB'
    tags: tags
    properties: {
        consistencyPolicy: { defaultConsistencyLevel: 'Session' }
        locations: [
            {
                locationName: location
                failoverPriority: 0
            }
        ]
        databaseAccountOfferType: 'Standard'
    }

    resource db 'sqlDatabases@2023-04-15' = [for name in databases: {
        name: '${name}'
        location: location
        tags: tags
        properties: {
            resource: {
                id: '${name}'
            }
        }
    }]
}

var primaryMasterKey = cosmosDb.listKeys(cosmosDb.apiVersion).primaryMasterKey

resource vault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
    name: keyVaultName

    resource secret 'secrets@2023-07-01' = {
        name: 'connectionString'
        properties: {
            value: 'AccountEndpoint=${cosmosDb.properties.documentEndpoint};AccountKey=${primaryMasterKey}'
        }
    }
}

Powyższy szablon Bicep oczekuje parametru keyVaultName, wśród różnych innych parametrów. Następnie definiuje zasób Azure Cosmos DB i umieszcza tajemnicę w Azure Key Vault, o nazwie connectionString, która reprezentuje kompletny łańcuch połączenia do instancji Cosmos DB. Aby uzyskać dostęp do tej wartości tajnego ciągu połączenia, możesz użyć następującego kodu:

var cosmos = builder.AddBicepTemplate("cosmos", "../infra/cosmosdb.bicep")
    .WithParameter("databaseAccountName", "fallout-db")
    .WithParameter(AzureBicepResource.KnownParameters.KeyVaultName)
    .WithParameter("databases", ["vault-33", "vault-111"]);

var connectionString =
    cosmos.GetSecretOutput("connectionString");

builder.AddProject<Projects.WebHook_Api>("api")
    .WithEnvironment(
        "ConnectionStrings__cosmos",
        connectionString);

W poprzednim fragmencie kodu szablon cosmos Bicep jest dodawany jako odwołanie do builder. Tajny wynik connectionString jest pobierany z szablonu Bicep i przechowywany w zmiennej. Tajne dane wyjściowe są następnie przekazywane jako zmienna środowiskowa (ConnectionStrings__cosmos) do projektu api. Ta zmienna środowiskowa służy do nawiązywania połączenia z wystąpieniem Cosmos DB.

Po wdrożeniu tego zasobu, podstawowy mechanizm wdrażania automatycznie odwoła się do tajemnic z Azure Key Vault. Aby zagwarantować tajną izolację, .NET.NET Aspire tworzy Key Vault dla każdego źródła.

Notatka

W trybie lokalnej aprowizacji tajemnica jest wyodrębniana z usługi Key Vault i następnie ustawiana w zmiennej środowiskowej. Aby uzyskać więcej informacji, zobacz lokalne Azure konfigurowanie.

Publikacja

Podczas publikowania aplikacji aprowizacja wygenerowana przez Bicep jest używana przez Azure Developer CLI do tworzenia zasobów Azure w Twojej subskrypcji Azure. .NET .NET Aspire generuje manifest publikowania oznaczony jako , który jest również istotną częścią procesu publikowania. Azure Developer CLI to narzędzie wiersza polecenia, które udostępnia zestaw poleceń do zarządzania zasobami Azure.

Aby uzyskać więcej informacji na temat publikowania i wdrażania, zobacz Wdróż projekt .NET Aspire na Azure Container Apps przy użyciu Azure Developer CLI (szczegółowy przewodnik).