Set up Azure Container Registry in the AppHost
此内容尚不支持你的语言。
This article is the reference for the Aspire Azure Container Registry Hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.ts — that you use to model an Azure Container Registry resource in your AppHost project.
If you’re new to the Azure Container Registry integration, start with the Get started with Azure Container Registry integrations guide. For how the registry is consumed at deployment time — including the loginServer output — see Connect to Azure Container Registry.
Installation
Section titled “Installation”To start building an Aspire app that uses Azure Container Registry, install the 📦 Aspire.Hosting.Azure.ContainerRegistry NuGet package:
aspire add Aspire.Hosting.Azure.ContainerRegistryLearn more about aspire add in the command reference.
Or, choose a manual installation approach:
#:package Aspire.Hosting.Azure.ContainerRegistry@*<PackageReference Include="Aspire.Hosting.Azure.ContainerRegistry" Version="*" />aspire add Aspire.Hosting.Azure.ContainerRegistryLearn more about aspire add in the command reference.
This updates your aspire.config.json with the Azure Container Registry hosting integration package:
{ "packages": { "Aspire.Hosting.Azure.ContainerRegistry": "13.3.0" }}Add Azure Container Registry resource
Section titled “Add Azure Container Registry resource”Once you’ve installed the hosting integration in your AppHost project, add an Azure Container Registry resource and wire it to a compute environment:
var builder = DistributedApplication.CreateBuilder(args);
var acr = builder.AddAzureContainerRegistry("my-acr");
builder.AddAzureContainerAppEnvironment("env") .WithAzureContainerRegistry(acr);
builder.Build().Run();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const acr = await builder.addAzureContainerRegistry("my-acr");
const env = await builder.addAzureContainerAppEnvironment("env");await env.withAzureContainerRegistry(acr);
await builder.build().run();-
The registry resource is modeled as an
AzureContainerRegistryResourcein the Aspire resource graph. -
Calling
WithAzureContainerRegistry(orwithAzureContainerRegistry) on the compute environment attaches the registry and provisions the necessary role assignments and managed-identity bindings so the environment can pull images securely. -
At deployment time, the generated Bicep provisions the registry and outputs its
nameandloginServerfor use by the deployment pipeline.
Get the registry from a compute environment
Section titled “Get the registry from a compute environment”To retrieve the registry that is associated with a compute environment — for example, to add purge tasks to the auto-provisioned default registry — use GetAzureContainerRegistry (or getAzureContainerRegistry):
var builder = DistributedApplication.CreateBuilder(args);
var env = builder.AddAzureContainerAppEnvironment("env");
// Retrieve the default auto-provisioned registryvar registry = env.GetAzureContainerRegistry();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const env = await builder.addAzureContainerAppEnvironment("env");
// Retrieve the default auto-provisioned registryconst registry = await env.getAzureContainerRegistry();This returns an AzureContainerRegistryResource builder that you can use for further configuration, such as scheduling image cleanup with purge tasks.
Reference an existing container registry
Section titled “Reference an existing container registry”To reference a registry your team already manages rather than provisioning a new one, use publishAsExisting, runAsExisting, or asExisting:
Use PublishAsExisting to reference an existing registry only in publish (deployment) mode:
var builder = DistributedApplication.CreateBuilder(args);
var registryName = builder.AddParameter("registryName");var rgName = builder.AddParameter("rgName");
var acr = builder.AddAzureContainerRegistry("my-acr") .PublishAsExisting(registryName, rgName);
builder.AddAzureContainerAppEnvironment("env") .WithAzureContainerRegistry(acr);
builder.Build().Run();Use AsExisting to reference an existing registry in both run and publish modes:
var acr = builder.AddAzureContainerRegistry("my-acr") .AsExisting(name: builder.AddParameter("registryName"), options: new() { ResourceGroup = builder.AddParameter("rgName") });Use publishAsExisting to reference an existing registry only in publish (deployment) mode:
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const registryName = await builder.addParameter("registryName");const rgName = await builder.addParameter("rgName");
const acr = await builder.addAzureContainerRegistry("my-acr");await acr.publishAsExisting(registryName, { resourceGroup: rgName });
const env = await builder.addAzureContainerAppEnvironment("env");await env.withAzureContainerRegistry(acr);
await builder.build().run();Use asExisting to reference an existing registry in both run and publish modes:
const acr = await builder.addAzureContainerRegistry("my-acr");await acr.asExisting(registryName, { resourceGroup: rgName });Assign roles for access control
Section titled “Assign roles for access control”Use WithRoleAssignments (or withRoleAssignments) to grant an Azure resource fine-grained access to the registry. The ContainerRegistryBuiltInRole enum (TypeScript: AzureContainerRegistryRole) covers the standard ACR roles:
var builder = DistributedApplication.CreateBuilder(args);
var acr = builder.AddAzureContainerRegistry("my-acr");
// Grant the 'api' project permission to push imagesbuilder.AddProject<Projects.Api>("api") .WithRoleAssignments(acr, ContainerRegistryBuiltInRole.AcrPush);
builder.Build().Run();import { createBuilder, AzureContainerRegistryRole } from './.modules/aspire.js';
const builder = await createBuilder();
const acr = await builder.addAzureContainerRegistry("my-acr");
// Grant the 'api' project permission to push imagesconst api = await builder.addProject("api", "../Api/Api.csproj");await api.withRoleAssignments(acr, [AzureContainerRegistryRole.AcrPush]);
await builder.build().run();Available roles include: AcrPull, AcrPush, AcrDelete, AcrImageSigner, AcrQuarantineReader, and AcrQuarantineWriter.
Schedule image cleanup with purge tasks
Section titled “Schedule image cleanup with purge tasks”Over time, container registries accumulate old images that consume storage. Use WithPurgeTask (or withPurgeTask) to add a scheduled ACR purge task that automatically removes old or unused images:
var builder = DistributedApplication.CreateBuilder(args);
var acr = builder.AddAzureContainerRegistry("my-acr") .WithPurgeTask("0 1 * * *", ago: TimeSpan.FromDays(7), keep: 5);
builder.Build().Run();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const acr = await builder.addAzureContainerRegistry("my-acr");await acr.withPurgeTask("0 1 * * *", { ago: 7 * 24 * 60 * 60 * 1000, // 7 days in milliseconds keep: 5,});
await builder.build().run();The preceding code creates a purge task that runs daily at 1:00 AM, removing images older than 7 days while keeping the 5 most recent images per repository. The C# ago parameter accepts a TimeSpan; the TypeScript ago option accepts milliseconds.
Multiple purge tasks
Section titled “Multiple purge tasks”Add multiple purge tasks to target different repositories with different schedules:
var acr = builder.AddAzureContainerRegistry("my-acr") .WithPurgeTask("0 1 * * *", filter: "app1:.*", keep: 3) .WithPurgeTask("0 2 * * 0", filter: "app2:.*", ago: TimeSpan.FromDays(30), keep: 10);const acr = await builder.addAzureContainerRegistry("my-acr");await acr.withPurgeTask("0 1 * * *", { filter: "app1:.*", keep: 3 });await acr.withPurgeTask("0 2 * * 0", { filter: "app2:.*", ago: 30 * 24 * 60 * 60 * 1000, keep: 10,});Each purge task is given a unique name automatically. Use the taskName option to specify a custom task name.
Customize the provisioning infrastructure
Section titled “Customize the provisioning infrastructure”To make changes that go beyond what the built-in APIs expose, configure the underlying Bicep infrastructure directly via ConfigureInfrastructure (or configureInfrastructure):
var acr = builder.AddAzureContainerRegistry("my-acr") .ConfigureInfrastructure(infra => { var registry = infra.GetProvisionableResources() .OfType<ContainerRegistry>() .Single();
registry.Sku = new ContainerRegistrySku { Name = ContainerRegistrySkuName.Premium }; });const acr = await builder.addAzureContainerRegistry("my-acr");await acr.configureInfrastructure(async (infra) => { // Use the Bicep infrastructure object to customize the registry});Provisioning-generated Bicep
Section titled “Provisioning-generated Bicep”If you’re new to Bicep, it’s a domain-specific language for defining Azure resources. With Aspire, you don’t need to write Bicep by hand — the provisioning APIs generate Bicep for you. When you publish your app, the generated Bicep is output alongside the manifest file. When you add an Azure Container Registry resource, the following Bicep is generated:
@description('The location for the resource(s) to be deployed.')param location string = resourceGroup().location
resource my_acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = { name: take('myacr${uniqueString(resourceGroup().id)}', 50) location: location sku: { name: 'Basic' } tags: { 'aspire-resource-name': 'my-acr' }}
output name string = my_acr.name
output loginServer string = my_acr.properties.loginServerThe generated Bicep outputs the registry name and loginServer (the registry endpoint used for image push/pull). These outputs are referenced by the compute environment’s Bicep and by your deployment pipeline.
Attach to a compute environment (Bicep)
Section titled “Attach to a compute environment (Bicep)”When you attach a registry to an Azure Container Apps environment, the environment’s generated Bicep references the registry outputs and creates the required AcrPull role assignment on the managed identity:
param my_acr_outputs_name string
resource my_acr 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = { name: my_acr_outputs_name}
resource my_acr_env_mi_AcrPull 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(my_acr.id, env_mi.id, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')) properties: { principalId: env_mi.properties.principalId roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') principalType: 'ServicePrincipal' } scope: my_acr}The generated Bicep is a starting point and is influenced by changes to the provisioning infrastructure in C#. Customizations to the Bicep file directly are overwritten, so make changes through the C# provisioning APIs (or configureInfrastructure) to ensure they’re reflected in the generated files.