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. 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 hostowane integracje .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 .
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 Basic lub StandardStock Keeping Unit (SKU) na potrzeby 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.
Emulatory lokalne
Niektóre usługi Azure można uruchamiać lokalnie w emulatorach. 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 przy użyciu interfejsu API NoSQL. |
Azure Event Hubs | Wywołaj AzureEventHubsExtensions.RunAsEmulator na IResourceBuilder<AzureEventHubsResource> , aby skonfigurować zasób usługi Event Hubs do emulacji . |
Azure Storage | 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 łańcuchowo metodę RunAsEmulator
na konstruktorze Azure zasobów. 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 wpływa na manifest publikowania . Podczas publikowania aplikacji wygenerowany plik Bicep odzwierciedla rzeczywistą usługę Azure, a nie emulator lokalny.
Kontenery lokalne
Niektóre usługi Azure można uruchamiać lokalnie w kontenerach. Aby uruchomić usługę Azure lokalnie w kontenerze, połącz wywołanie metody RunAsContainer
w konstruktorze zasobów Azure. Ta metoda konfiguruje zasób Azure do uruchamiania lokalnego w kontenerze zamiast 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 | Wywołaj AzureRedisExtensions.RunAsContainer na IResourceBuilder<AzureRedisCacheResource> , aby skonfigurować go do uruchamiania lokalnego w kontenerze na podstawie obrazu docker.io/library/redis . |
Azure PostgreSQL elastyczne Server | Wywołaj AzurePostgresExtensions.RunAsContainer na 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 z wykorzystaniem obrazu mcr.microsoft.com/mssql/server . |
Notatka
Podobnie jak w przypadku emulatorów, wywoływanie RunAsContainer
na 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.
Omówienie 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 pracy | Tryb publikowania |
---|---|---|
AddAzureRedis("redis"). RunAsContainer() | Lokalny kontener Redis | Azure Cache for Redis |
AddRedis("redis") | Kontener lokalny Redis | Azure aplikacja kontenerowa z obrazem Redis |
To samo dotyczy usług SQL i PostgreSQL:
API | Tryb pracy | Tryb publikowania |
---|---|---|
AddAzurePostgresFlexibleServer("postgres").RunAsContainer() | Lokalny kontener PostgreSQL | Azure PostgreSQL elastyczne Server |
AddPostgres("postgres") | Lokalny kontener PostgreSQL | Azure aplikacja kontenera 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.
Infrastruktura jako kod
Zestaw SDK Azure dla .NET udostępnia 📦Azure. Pakiet NuGet do aprowizacji oraz zestaw pakietów do aprowizacji 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 interfejsy API są dostępne jako metody rozszerzeń w .NET AspireAzure bibliotek hostingu, rozszerzając 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 prowizjonowania.
Ponieważ modele .NET Aspire zasoby Azure w integracjach hostingu Azure, zestaw SDK Azure służy do aprowizowania zasobów. Pliki Bicep są generowane, które definiują potrzebne zasoby Azure. Wygenerowane pliki Bicep są tworzone razem z plikiem manifestu podczas publikowania aplikacji.
Istnieje kilka sposobów wpływania na wygenerowane pliki Bicep:
-
Azure.dostosowywania aprowizacji:
- 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.
- odniesienie Bicep wbudowane: Dodaj wbudowany szablon Bicep.
Lokalne zaopatrzenie i Azure.Provisioning
Aby uniknąć mieszania terminów i pomóc w uściślaniu "przygotowania", ważne jest, aby zrozumieć rozróżnienie pomiędzy aprowizacją lokalną i Azure aprowizacją:
Lokalne dostarczanie:
Domyślnie podczas wywoływania dowolnego z Azure hostowania interfejsów API integracji w celu dodania Azure zasobów interfejs API AddAzureProvisioning(IDistributedApplicationBuilder) jest wywoływany niejawnie. Ten interfejs API rejestruje usługi w kontenerze wstrzykiwania zależności (DI), używane do przygotowywania zasobów Azure podczas startu hosta aplikacji. Ta koncepcja jest znana jako lokalne zaopatrzenie. Aby uzyskać więcej informacji, zobacz local Azure provisioning.
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 w tle do generowania plików Bicep, które definiują zasoby Azure, których potrzebujesz. Aby uzyskać więcej informacji, zobaczAzure.Provisioning
dostosowywanie.
dostosowywanie 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 generycznymi typami do tego typu, korzystanie z płynnego interfejsu API do dostosowywania infrastruktury do własnych potrzeb. Mimo że .NETi.NET Aspire udostępniają wartości domyślne, możesz wpływać na wygenerowany Bicep, korzystając z tych interfejsów API.
Konfigurowanie infrastruktury
Niezależnie od zasobu Azure, z którym pracujesz, aby skonfigurować jego podstawową infrastrukturę, należy utworzyć połączenie z 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:- Nowe wystąpienie StorageSku ma przypisaną właściwość
Name
z wyniku interfejsu API AsProvisioningParameter.
- Nowe wystąpienie StorageSku ma przypisaną 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 serwis pracownika odpowiedzialny 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 wystąpienie ContainerRegistryService o nazwie
acr
i standardowej jednostce 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 wystąpienie ContainerRegistryService o nazwie
- Dodaje projekt o nazwie
worker
do konstruktora. - Powiązuje wywołanie do WithEnvironment, aby ustawić zmienną środowiskową
ACR_REGISTRY_NAME
w projekcie na wartość wynikuregistryName
.
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 interfejsie API AddAzureInfrastructure
.
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 podczas wywoływania dowolnego API związanego z Bicepem, również wykonywane jest wywołanie do AddAzureProvisioning, które dodaje wsparcie dla generowania zasobów Azure dynamicznie podczas uruchamiania aplikacji. Aby uzyskać więcej informacji, zobacz Local provisioning and Azure.Provisioning
.
Odwołania do plików 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 być względem 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ępnianie zasobu sztucznej inteligencji Azure.
Przekazywanie parametrów 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, łańcuch wywołań metody WithParameter, jak pokazano 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 rozwiązywany za pomocą standardowej metody rozwiązywania parametrów. - Przekazuje parametr
do szablonu Bicep z zakodowaną na stałe wartością . - 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, zobacz dane wyjściowe Bicepa.
Uzyskaj tajne 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 tajny wpis w Azure Key Vaulto nazwie connectionString
, który reprezentuje w pełni określony ł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
. Tajne dane wyjściowe connectionString
są pobierane z szablonu Bicep i przechowywane 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łania do wpisów tajnych 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 wpis tajny jest wyodrębniany z usługi Key Vault i ustawiany w zmiennej środowiskowej. Aby uzyskać więcej informacji, zobacz local Azure provisioning.
Publikacja
Podczas publikowania aplikacji Azure aprowizacja wygenerowana przez aplikację Bicep jest używana przez Azure Developer CLI do tworzenia zasobów Azure w ramach 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).