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
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:
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
, RunAsExisting
i 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
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ówserviceBus
, przekazując parametrexistingServiceBusName
— alternatywnie można użyć przeciążenia parametrustring
. - Dodaje kolejkę o nazwie
queue
do zasobuserviceBus
.
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ówserviceBus
, przekazując parametrexistingServiceBusName
— alternatywnie można użyć przeciążenia parametrustring
. - Dodaje kolejkę o nazwie
queue
do zasobuserviceBus
.
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ówserviceBus
, przekazując parametrexistingServiceBusName
. - Dodaje kolejkę o nazwie
queue
do zasobuserviceBus
.
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 zasobustorage
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ą:
- ContainerResource: reprezentuje określony kontener.
- ExecutableResource: reprezentuje określony proces wykonywalny.
- ProjectResource: reprezentuje określony projekt .NET.
Aby opublikować te zasoby, użyj następujących interfejsów API:
- AzureContainerAppContainerExtensions.PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>)
- AzureContainerAppExecutableExtensions.PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>)
- AzureContainerAppProjectExtensions.PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>)
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ówapi
, przekazując wyrażenie lambda, które konfiguruje infrastrukturę aplikacji kontenerowej Azure—gdzieinfra
jest AzureResourceInfrastructure, aapp
jest ContainerApp.- Dodaje zmienną środowiskową o nazwie
Hello
do aplikacji kontenera przy użyciu parametruenv
. - Metoda
AsProvisioningParameter
jest używana do traktowaniaenv
jako nowego ProvisioningParameter w infrastrukturze lub ponownego użycia istniejącego parametru bicep, jeśli taki o tej samej nazwie już istnieje.
- Dodaje zmienną środowiskową o nazwie
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:
-
AzureDostosowywanie konfigurowania:
- Konfiguruj infrastrukturę: Dostosuj infrastrukturę zasobów Azure.
- Dodaj infrastrukturę Azure: ręcznie dodaj infrastrukturę Azure do hosta aplikacji.
-
Użyj niestandardowych szablonów Bicep:
- Odwołania do plików Bicep: Dodaj odwołanie do pliku Bicep na dysku.
- Referencja Bicep inline: Dodaj szablon Bicep inline.
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, zobaczAzure.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:- Pobiera zasoby możliwe do przydzielenia.
- Filtruje do jednego StorageAccount.
- Przypisuje parametr
storage-sku
do właściwości StorageAccount.Sku:- Nowa instancja StorageSku ma właściwość
Name
przypisaną na podstawie wyniku z interfejsu API AsProvisioningParameter.
- Nowa instancja StorageSku ma właściwość
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 typiestring
i o wartości odpowiadającej nazwie rejestru kontenerów Azure. - Dodaje dane wyjściowe do zmiennej
infra
.
- Tworzy instancję ContainerRegistryService o nazwie
- 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ąpieniabuilder
. - 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
, principalType
i 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 dobuilder
. - 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
iprincipalType
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).