Udostępnij przez


Zdeponować projekt do Aspire na Azure Container Apps używając Azure Developer CLI (szczegółowy przewodnik)

Element Azure Developer CLI (azd) został rozszerzony do obsługi wdrażania projektów Aspire. Skorzystaj z tego przewodnika, aby przeprowadzić proces tworzenia i wdrażania projektu Aspire do Azure Container Apps za pomocą Azure Developer CLI. W tym samouczku poznasz następujące pojęcia:

  • Dowiedz się, jak azd działa integracja z projektami Aspire
  • Aprowizuj i wdrażaj zasoby Azure dla projektu Aspire przy użyciu azd
  • Generowanie infrastruktury Bicep i innych plików szablonów przy użyciu azd

Wymagania wstępne

Do pracy z Aspireprogramem potrzebne są następujące elementy zainstalowane lokalnie:

Aby uzyskać więcej informacji, zobacz Aspire konfigurowanie i narzędzia oraz Aspire zestaw SDK.

Konieczne będzie również Azure Developer CLIzainstalowanie na lokalnym komputerze. Typowe opcje instalacji obejmują następujące elementy:

winget install microsoft.azd

Jak Azure Developer CLI działa integracja

Przepływ pracy azd init zapewnia dostosowaną obsługę projektów Aspire. Na poniższym diagramie pokazano, jak działa ten przepływ koncepcyjnie oraz jak azd i Aspire są zintegrowane.

Ilustracja przedstawiająca wewnętrzne przetwarzanie

  1. Gdy azd obiektem docelowym Aspire jest projekt, uruchamia host AppHost za pomocą specjalnego polecenia (dotnet run --project AppHost.csproj --output-path manifest.json --publisher manifest), które generuje Aspire.
  2. Plik manifestu jest przesłuchiwany przez logikę podrzędnego azd provision polecenia w celu wygenerowania plików Bicep tylko w pamięci (domyślnie).
  3. Po wygenerowaniu plików Bicep wdrożenie jest wyzwalane przy użyciu interfejsów API usługi ARM Azure, które są przeznaczone dla subskrypcji i wcześniej określonej grupy zasobów.
  4. Po skonfigurowaniu zasobów bazowych Azure jest wykonywana logika azd deploy podrzędnego polecenia, która używa tego samego Aspire pliku manifestu.
  5. W ramach wdrażania azd wykonuje połączenie z dotnet publish przy użyciu wbudowanego wsparcia .NET do publikowania kontenerów w celu generowania obrazów kontenerów.
  6. Po zbudowaniu obrazów kontenerów azd wprowadza je do rejestru ACR utworzonego w fazie aprowizacji.
  7. Gdy obraz kontenera znajdzie się w usłudze ACR, azd aktualizuje zasób przy użyciu ARM, aby rozpocząć korzystanie z nowej wersji obrazu kontenera.

Uwaga / Notatka

azd umożliwia również zapisanie wygenerowanego Bicepu do folderu infra w projekcie, o czym można przeczytać więcej w sekcji Generowanie Bicep z Aspire modelu aplikacji.

Aprowizuj i wdróż aplikację startową Aspire

W kolejnych krokach przedstawiono, jak utworzyć aplikację startową Aspire i zarządzać aprowizowaniem oraz wdrażaniem zasobów aplikacji do Azure przy użyciu azd.

Tworzenie aplikacji startowej Aspire

Utwórz nowy Aspire projekt przy użyciu polecenia dotnet new. Projekt można również utworzyć przy użyciu polecenia Visual Studio.

dotnet new aspire-starter --use-redis-cache -o AspireSample
cd AspireSample
dotnet run --project AspireSample.AppHost\AspireSample.AppHost.csproj

Poprzednie polecenia tworzą nowy Aspire projekt na podstawie szablonu aspire-starter , który zawiera zależność od Redis pamięci podręcznej. Uruchamia Aspire projekt, który sprawdza, czy wszystko działa prawidłowo.

Inicjowanie szablonu

  1. Otwórz nowe okno terminalu i cd przejdź do katalogu swojego rozwiązania Aspire.

  2. Wykonaj polecenie azd init, aby zainicjować projekt przy użyciu azd, co spowoduje sprawdzenie struktury katalogów lokalnych i określenie typu aplikacji.

    azd init
    

    Aby uzyskać więcej informacji na temat polecenia azd init, zobacz azd init.

  3. Wybierz Użyj kodu w bieżącym kataloguazd, gdy zostanie wyświetlony monit z trzema opcjami inicjowania aplikacji.

    ? How do you want to initialize your app?  [Use arrows to move, type to filter]
    > Use code in the current directory
      Select a template
      Create a minimal project
    
  4. Po przeskanowaniu katalogu azd zostanie wyświetlony monit o potwierdzenie znalezienia poprawnego Aspire projektu AppHost. Wybierz opcję Potwierdź i kontynuuj inicjowanie mojej aplikacji.

    Detected services:
    
      .NET (Aspire)
      Detected in: D:\source\repos\AspireSample\AspireSample.AppHost\AspireSample.AppHost.csproj
    
    azd will generate the files necessary to host your app on Azure using Azure Container Apps.
    
    ? Select an option  [Use arrows to move, type to filter]
    > Confirm and continue initializing my app
      Cancel and exit
    
  5. Wprowadź nazwę środowiska, która będzie używana do nazywania aprowizowanych zasobów w Azure oraz zarządzania różnymi środowiskami, takimi jak dev i prod.

    Generating files to run your app on Azure:
    
      (✓) Done: Generating ./azure.yaml
      (✓) Done: Generating ./next-steps.md
    
    SUCCESS: Your app is ready for the cloud!
    You can provision and deploy your app to Azure by running the azd up command in this directory. For more information on configuring your app, see ./next-steps.md
    

azd generuje wiele plików i umieszcza je w katalogu roboczym. Są to następujące pliki:

  • azure.yaml: opisuje usługi aplikacji, takie jak projekt Aspire AppHost, i mapuje je na zasoby Azure.
  • .azure/config.json: plik konfiguracyjny informujący azd, jakie jest bieżące aktywne środowisko.
  • .azure/aspireazddev/.env: zawiera przesłonięcia specyficzne dla środowiska.

Plik azure.yaml ma następującą zawartość:

# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: AspireSample
services:
  app:
    language: dotnet
    project: .\AspireSample.AppHost\AspireSample.AppHost.csproj
    host: containerapp

Nazewnictwo zasobów

Podczas tworzenia nowych Azure zasobów ważne jest, aby spełnić wymagania dotyczące nazewnictwa. W przypadku Azure Container Appsparametru nazwa musi mieć długość od 2 do 32 znaków i składać się z małych liter, cyfr i łączników. Nazwa musi zaczynać się literą i kończyć znakiem alfanumerycznym.

Aby uzyskać więcej informacji, zobacz Naming rules and restrictions for resources (Reguły i ograniczenia nazewnictwa zasobówAzure).

Początkowe wdrożenie

  1. Aby wdrożyć Aspire projekt, uwierzytelnij się w Azure usłudze AD w celu wywołania Azure interfejsów API zarządzania zasobami.

    azd auth login
    

    Poprzednie polecenie spowoduje uruchomienie przeglądarki w celu uwierzytelnienia sesji wiersza polecenia.

  2. Po uwierzytelnieniu uruchom następujące polecenie z katalogu projektu AppHost , aby aprowizować i wdrożyć aplikację.

    azd up
    

    Ważne

    Aby przesłać obrazy kontenerów do Azure Container Registry (ACR), musisz mieć Microsoft.Authorization/roleAssignments/write dostęp. Można to osiągnąć, włączając użytkownika administratora w rejestrze. Azure Otwórz portal, przejdź do zasobu usługi ACR / Ustawienia / Klucze dostępu, a następnie zaznacz pole wyboru Administrator. Aby uzyskać więcej informacji, zobacz Włączanie użytkownika administracyjnego.

  3. Po wyświetleniu monitu wybierz subskrypcję i lokalizację, do których mają zostać wdrożone zasoby. Po wybraniu Aspire tych opcji projekt zostanie wdrożony.

    By default, a service can only be reached from inside the Azure Container Apps environment it is running in. Selecting a service here will also allow it to be reached from the Internet.
    ? Select which services to expose to the Internet webfrontend
    ? Select an Azure Subscription to use:  1. <YOUR SUBSCRIPTION>
    ? Select an Azure location to use: 1. <YOUR LOCATION>
    
    Packaging services (azd package)
    
    
    Provisioning Azure resources (azd provision)
    Provisioning Azure resources can take some time.
    
    Subscription: <YOUR SUBSCRIPTION>
    Location: <YOUR LOCATION>
    
      You can view detailed progress in the Azure Portal:
      <LINK TO DEPLOYMENT>
    
      (✓) Done: Resource group: <YOUR RESOURCE GROUP>
      (✓) Done: Container Registry: <ID>
      (✓) Done: Log Analytics workspace: <ID>
      (✓) Done: Container Apps Environment: <ID>
    
    SUCCESS: Your application was provisioned in Azure in 1 minute 13 seconds.
    You can view the resources created under the resource group <YOUR RESOURCE GROUP> in Azure Portal:
    <LINK TO RESOURCE GROUP OVERVIEW>
    
    Deploying services (azd deploy)
    
      (✓) Done: Deploying service apiservice
      - Endpoint: <YOUR UNIQUE apiservice APP>.azurecontainerapps.io/
    
      (✓) Done: Deploying service webfrontend
      - Endpoint: <YOUR UNIQUE webfrontend APP>.azurecontainerapps.io/
    
    Aspire Dashboard: <LINK TO DEPLOYED Aspire DASHBOARD>
    
    SUCCESS: Your up workflow to provision and deploy to Azure completed in 3 minutes 50 seconds.
    

    Ostatnim wierszem danych wyjściowych azd polecenia jest link do Azure portalu, który zawiera wszystkie Azure wdrożone zasoby:

    Azure Zrzut ekranu portalu przedstawiający wdrożone zasoby.

Trzy kontenery są wdrażane w tej aplikacji:

  • webfrontend: zawiera kod z projektu internetowego w szablonie startowym.
  • apiservice: zawiera kod z projektu usługi interfejsu API w szablonie startowym.
  • cache: obraz kontenera Redis, aby dostarczyć cache do frontendu.

Podobnie jak w przypadku programowania lokalnego konfiguracja parametrów połączenia została obsłużona automatycznie. W takim przypadku azd był odpowiedzialny za interpretowanie modelu aplikacji i tłumaczenie go na odpowiednie kroki wdrażania. Rozważmy na przykład parametry połączenia i zmienne odnajdywania usługi, które są wstrzykiwane do webfrontend kontenera, aby wiedzieć, jak nawiązać połączenie z pamięcią podręczną Redis i apiservice.

Zrzut ekranu przedstawiający zmienne środowiskowe w aplikacji kontenera webfrontend.

Aby uzyskać więcej informacji na temat obsługi Aspire ciągów połączeń i odnajdywania usług w projektach, zobacz Aspire omówienie orkiestracji.

Wdrażanie aktualizacji aplikacji

Po wykonaniu azd up polecenia zasoby bazowe Azure są aprowizowane , a obraz kontenera jest kompilowany i wdrażany w aplikacjach kontenera hostowanych projekt Aspire . Zwykle po rozpoczęciu prac rozwojowych i wdrożeniu zasobów nie będzie konieczne konfigurowanie zasobów za każdym razem, gdy kod jest aktualizowany, co szczególnie dotyczy pętli wewnętrznej dewelopera.

Aby przyspieszyć wdrażanie zmian kodu, azd obsługuje wdrażanie aktualizacji kodu w obrazie kontenera. Odbywa się to przy użyciu azd deploy polecenia :

azd deploy
Deploying services (azd deploy)

  (✓) Done: Deploying service apiservice
  - Endpoint: <YOUR UNIQUE apiservice APP>.azurecontainerapps.io/

  (✓) Done: Deploying service webfrontend
  - Endpoint: <YOUR UNIQUE webfrontend APP>.azurecontainerapps.io/

Aspire Dashboard: <LINK TO DEPLOYED Aspire DASHBOARD>

Nie trzeba wdrażać wszystkich usług za każdym razem. azd Aspire rozumie model projektu, można wdrożyć tylko jedną z usług określonych przy użyciu następującego polecenia:

azd deploy webfrontend

Aby uzyskać więcej informacji, zobacz Azure Developer CLI dokumentację: azd deploy.

Wdrażanie aktualizacji infrastruktury

Za każdym razem, gdy struktura zależności w projekcie Aspire ulegnie zmianie, trzeba ponownie aprowizować zasoby podstawowe azd. Polecenie azd provision służy do stosowania tych zmian w infrastrukturze.

Aby zobaczyć to w akcji, zaktualizuj plik AppHost.cs w projekcie AppHost do następującej zawartości:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

// Add the locations database.
var locationsdb = builder.AddPostgres("db").AddDatabase("locations");

// Add the locations database reference to the API service.
var apiservice = builder.AddProject<Projects.AspireSample_ApiService>("apiservice")
    .WithReference(locationsdb);

builder.AddProject<Projects.AspireSample_Web>("webfrontend")
    .WithReference(cache)
    .WithReference(apiservice);

builder.Build().Run();

Zapisz plik i wydaj następujące polecenie:

azd provision

Polecenie azd provision aktualizuje infrastrukturę, tworząc aplikację kontenera do hostowania Postgres bazy danych. Polecenie azd provision nie zaktualizowało parametrów połączenia dla kontenera apiservice . Aby parametry połączenia zostały zaktualizowane, aby wskazywały nowo aprowizowaną Postgres bazę danych, azd deploy należy ponownie wywołać polecenie. W razie wątpliwości użyj azd up, aby przydzielić zasoby i wdrażać.

Uprzątnij zasoby

Pamiętaj, aby wyczyścić Azure zasoby utworzone podczas tego przewodnika. Ponieważ azd zna grupę zasobów, w której utworzyła zasoby, można ją wykorzystać do zamknięcia środowiska za pomocą następującego polecenia:

azd down

Wykonanie poprzedniego polecenia może zająć trochę czasu, ale po zakończeniu grupy zasobów i wszystkich jej zasobów należy usunąć.

Deleting all resources and deployed code on Azure (azd down)
Local application code is not deleted when running 'azd down'.

  Resource group(s) to be deleted:

    • <YOUR RESOURCE GROUP>: <LINK TO RESOURCE GROUP OVERVIEW>

? Total resources to delete: 7, are you sure you want to continue? Yes
Deleting your resources can take some time.

  (✓) Done: Deleting resource group: <YOUR RESOURCE GROUP>

SUCCESS: Your application was removed from Azure in 9 minutes 59 seconds.

Generowanie Bicep na podstawie Aspire modelu projektu

Mimo że zespoły programistyczne mogą używać azd up poleceń (lub azd provision i azd deploy) dla swoich wdrożeń zarówno w celach programistycznych, jak i produkcyjnych, niektóre zespoły mogą generować pliki Bicep, które mogą przeglądać i zarządzać w ramach kontroli wersji (pozwala to również na odwołowanie się do tych plików Bicep w ramach większego bardziej złożonego Azure wdrożenia).

Aby uzyskać kompleksowe wskazówki dotyczące dostosowywania wygenerowanej infrastruktury dla scenariuszy produkcyjnych, zobacz Dostosowywanie AspireAzure wdrożeń.

azd Program zawiera możliwość wyprowadzania danych wyjściowych używanych przez element Bicep do aprowizacji za pomocą następującego polecenia:

azd config set alpha.infraSynth on
azd infra gen

Po wykonaniu tego polecenia w przykładzie szablonu początkowego użytego w tym przewodniku w katalogu projektu AppHost są tworzone następujące pliki:

  • infra/main.bicep: reprezentuje główny punkt wejścia dla wdrożenia.
  • infra/main.parameters.json: używane jako parametry głównego Bicepu (odpowiadają zmiennym środowiskowym zdefiniowanym w folderze .azure).
  • infra/resources.bicep: definiuje Azure zasoby wymagane do obsługi Aspire modelu projektu.
  • AspireSample.Web/manifests/containerApp.tmpl.yaml: definicja aplikacji kontenera dla elementu webfrontend.
  • AspireSample.ApiService/manifests/containerApp.tmpl.yaml: definicja aplikacji kontenera dla elementu apiservice.

Plik infra\resources.bicep nie zawiera żadnej definicji aplikacji kontenera (z wyjątkiem aplikacji kontenera, które są zależnościami, takimi jak Redis i Postgres):

@description('The location used for all deployed resources')
param location string = resourceGroup().location

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

var resourceToken = uniqueString(resourceGroup().id)

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: 'mi-${resourceToken}'
  location: location
  tags: tags
}

resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
  name: replace('acr-${resourceToken}', '-', '')
  location: location
  sku: {
    name: 'Basic'
  }
  tags: tags
}

resource caeMiRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(containerRegistry.id, managedIdentity.id, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d'))
  scope: containerRegistry
  properties: {
    principalId: managedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId:  subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
  }
}

resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
  name: 'law-${resourceToken}'
  location: location
  properties: {
    sku: {
      name: 'PerGB2018'
    }
  }
  tags: tags
}

resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {
  name: 'cae-${resourceToken}'
  location: location
  properties: {
    appLogsConfiguration: {
      destination: 'log-analytics'
      logAnalyticsConfiguration: {
        customerId: logAnalyticsWorkspace.properties.customerId
        sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
      }
    }
  }
  tags: tags
}

resource cache 'Microsoft.App/containerApps@2023-05-02-preview' = {
  name: 'cache'
  location: location
  properties: {
    environmentId: containerAppEnvironment.id
    configuration: {
      service: {
        type: 'redis'
      }
    }
    template: {
      containers: [
        {
          image: 'redis'
          name: 'redis'
        }
      ]
    }
  }
  tags: union(tags, {'aspire-resource-name': 'cache'})
}

resource locations 'Microsoft.App/containerApps@2023-05-02-preview' = {
  name: 'locations'
  location: location
  properties: {
    environmentId: containerAppEnvironment.id
    configuration: {
      service: {
        type: 'postgres'
      }
    }
    template: {
      containers: [
        {
          image: 'postgres'
          name: 'postgres'
        }
      ]
    }
  }
  tags: union(tags, {'aspire-resource-name': 'locations'})
}
output MANAGED_IDENTITY_CLIENT_ID string = managedIdentity.properties.clientId
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.properties.loginServer
output AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID string = managedIdentity.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_ID string = containerAppEnvironment.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN string = containerAppEnvironment.properties.defaultDomain

Aby uzyskać więcej informacji na temat używania Bicep do automatyzowania wdrożeń Azure, zobacz Co to jest Bicep?

Definicja aplikacji kontenerowych z .NET projektów usługowych jest zawarta w plikach containerApp/tmpl.yaml w katalogu manifests w każdym projekcie odpowiednio. Oto przykład z webfrontend projektu:

location: {{ .Env.AZURE_LOCATION }}
identity:
  type: UserAssigned
  userAssignedIdentities:
    ? "{{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}"
    : {}
properties:
  environmentId: {{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_ID }}
  configuration:
    activeRevisionsMode: single
    ingress:
      external: true
      targetPort: 8080
      transport: http
      allowInsecure: false
    registries:
    - server: {{ .Env.AZURE_CONTAINER_REGISTRY_ENDPOINT }}
      identity: {{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}
  template:
    containers:
    - image: {{ .Env.SERVICE_WEBFRONTEND_IMAGE_NAME }}
      name: webfrontend
      env:
      - name: AZURE_CLIENT_ID
        value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
      - name: ConnectionStrings__cache
        value: {{ connectionString "cache" }}
      - name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES
        value: "true"
      - name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES
        value: "true"
      - name: APISERVICE_HTTP
        value: http://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
      - name: APISERVICE_HTTPS
        value: https://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
      - name: services__apiservice__http__0
        value: http://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
      - name: services__apiservice__https__0
        value: https://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
tags:
  azd-service-name: webfrontend
  aspire-resource-name: webfrontend

Po wykonaniu azd infra gen polecenia, gdy azd provision i azd deploy są wywoływane, używają Bicep i pomocniczych wygenerowanych plików.

Ważne

Jeśli azd infra gen zostanie wywołana ponownie, zastępuje wszelkie zmodyfikowane pliki świeżo wygenerowanymi i monituje o potwierdzenie przed wykonaniem tej czynności.

Środowiska izolowane na potrzeby debugowania

Ponieważ azd ułatwia aprowizację nowych środowisk, każdy członek zespołu może mieć izolowane środowisko hostowane w chmurze do debugowania kodu w ustawieniu, które ściśle pasuje do środowiska produkcyjnego. W tym celu każdy członek zespołu powinien utworzyć własne środowisko przy użyciu następującego polecenia:

azd env new

Spowoduje to ponowne wezwanie użytkownika do podania informacji o subskrypcji i grupie zasobów, a kolejne wywołania azd up, azd provision i azd deploy będą korzystać z tego nowego środowiska domyślnie. Przełącznik --environment można zastosować do tych poleceń, aby przełączać się między środowiskami.

Uprzątnij zasoby

Uruchom następujące polecenie interfejsu wiersza polecenia Azure, aby usunąć grupę zasobów, gdy zasoby, które utworzyłeś Azure, przestały być potrzebne. Usunięcie grupy zasobów powoduje również usunięcie zawartych w niej zasobów.

az group delete --name <your-resource-group-name>

Aby dowiedzieć się więcej, zobacz Czyszczenie zasobów w Azure.