Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,33 @@ param userPrincipalId string

param tags object = { }

resource mi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: take('mi-${uniqueString(resourceGroup().id)}', 128)
resource infra_mi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: take('infra_mi-${uniqueString(resourceGroup().id)}', 128)
location: location
tags: tags
}

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

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

resource law 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: take('law-${uniqueString(resourceGroup().id)}', 63)
resource infra_law 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: take('infralaw-${uniqueString(resourceGroup().id)}', 63)
location: location
properties: {
sku: {
Expand All @@ -41,15 +41,15 @@ resource law 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
tags: tags
}

resource cae 'Microsoft.App/managedEnvironments@2024-03-01' = {
name: take('cae${uniqueString(resourceGroup().id)}', 24)
resource infra 'Microsoft.App/managedEnvironments@2024-03-01' = {
name: take('infra${uniqueString(resourceGroup().id)}', 24)
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: law.properties.customerId
sharedKey: law.listKeys().primarySharedKey
customerId: infra_law.properties.customerId
sharedKey: infra_law.listKeys().primarySharedKey
}
}
workloadProfiles: [
Expand All @@ -67,20 +67,20 @@ resource aspireDashboard 'Microsoft.App/managedEnvironments/dotNetComponents@202
properties: {
componentType: 'AspireDashboard'
}
parent: cae
parent: infra
}

resource cae_Contributor 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(cae.id, userPrincipalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c'))
resource infra_Contributor 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(infra.id, userPrincipalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c'))
properties: {
principalId: userPrincipalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
}
scope: cae
scope: infra
}

resource storageVolume 'Microsoft.Storage/storageAccounts@2024-01-01' = {
name: take('storagevolume${uniqueString(resourceGroup().id)}', 24)
resource infra_storageVolume 'Microsoft.Storage/storageAccounts@2024-01-01' = {
name: take('infrastoragevolume${uniqueString(resourceGroup().id)}', 24)
kind: 'StorageV2'
location: location
sku: {
Expand All @@ -94,7 +94,7 @@ resource storageVolume 'Microsoft.Storage/storageAccounts@2024-01-01' = {

resource storageVolumeFileService 'Microsoft.Storage/storageAccounts/fileServices@2024-01-01' = {
name: 'default'
parent: storageVolume
parent: infra_storageVolume
}

resource shares_volumes_cache_0 'Microsoft.Storage/storageAccounts/fileServices/shares@2024-01-01' = {
Expand All @@ -110,33 +110,33 @@ resource managedStorage_volumes_cache_0 'Microsoft.App/managedEnvironments/stora
name: take('managedstoragevolumescache${uniqueString(resourceGroup().id)}', 24)
properties: {
azureFile: {
accountName: storageVolume.name
accountKey: storageVolume.listKeys().keys[0].value
accountName: infra_storageVolume.name
accountKey: infra_storageVolume.listKeys().keys[0].value
accessMode: 'ReadWrite'
shareName: shares_volumes_cache_0.name
}
}
parent: cae
parent: infra
}

output volumes_cache_0 string = managedStorage_volumes_cache_0.name

output MANAGED_IDENTITY_NAME string = mi.name
output MANAGED_IDENTITY_NAME string = infra_mi.name

output MANAGED_IDENTITY_PRINCIPAL_ID string = mi.properties.principalId
output MANAGED_IDENTITY_PRINCIPAL_ID string = infra_mi.properties.principalId

output AZURE_LOG_ANALYTICS_WORKSPACE_NAME string = law.name
output AZURE_LOG_ANALYTICS_WORKSPACE_NAME string = infra_law.name

output AZURE_LOG_ANALYTICS_WORKSPACE_ID string = law.id
output AZURE_LOG_ANALYTICS_WORKSPACE_ID string = infra_law.id

output AZURE_CONTAINER_REGISTRY_NAME string = acr.name
output AZURE_CONTAINER_REGISTRY_NAME string = infra_acr.name

output AZURE_CONTAINER_REGISTRY_ENDPOINT string = acr.properties.loginServer
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = infra_acr.properties.loginServer

output AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID string = mi.id
output AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID string = infra_mi.id

output AZURE_CONTAINER_APPS_ENVIRONMENT_NAME string = cae.name
output AZURE_CONTAINER_APPS_ENVIRONMENT_NAME string = infra.name

output AZURE_CONTAINER_APPS_ENVIRONMENT_ID string = cae.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_ID string = infra.id

output AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN string = cae.properties.defaultDomain
output AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN string = infra.properties.defaultDomain
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<PackageReference Include="Azure.Provisioning.OperationalInsights" />
<PackageReference Include="Azure.Provisioning.KeyVault" />
<PackageReference Include="Azure.Provisioning.Storage" />
<ProjectReference Include="..\Aspire.Hosting.Azure\Aspire.Hosting.Azure.csproj" />
<PackageReference Include="Aspire.Hosting.Azure" VersionOverride="9.3.0-*" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace Aspire.Hosting.Azure.AppContainers;
public class AzureContainerAppEnvironmentResource(string name, Action<AzureResourceInfrastructure> configureInfrastructure) :
AzureProvisioningResource(name, configureInfrastructure), IAzureContainerAppEnvironment
{
internal bool UseAzdNamingConvention { get; set; }

/// <summary>
/// Gets the unique identifier of the Container App Environment.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon

var containerAppEnvResource = new AzureContainerAppEnvironmentResource(name, static infra =>
{
var appEnvResource = (AzureContainerAppEnvironmentResource)infra.AspireResource;
var userPrincipalId = new ProvisioningParameter("userPrincipalId", typeof(string));

infra.Add(userPrincipalId);
Expand All @@ -75,14 +76,13 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon

infra.Add(tags);

var identity = new UserAssignedIdentity("mi")
var identity = new UserAssignedIdentity(Infrastructure.NormalizeBicepIdentifier($"{appEnvResource.Name}_mi"))
{
Tags = tags
};

infra.Add(identity);

var containerRegistry = new ContainerRegistryService("acr")
var containerRegistry = new ContainerRegistryService(Infrastructure.NormalizeBicepIdentifier($"{appEnvResource.Name}_acr"))
{
Sku = new() { Name = ContainerRegistrySkuName.Basic },
Tags = tags
Expand All @@ -96,15 +96,15 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon
pullRa.Name = BicepFunction.CreateGuid(containerRegistry.Id, identity.Id, pullRa.RoleDefinitionId);
infra.Add(pullRa);

var laWorkspace = new OperationalInsightsWorkspace("law")
var laWorkspace = new OperationalInsightsWorkspace(Infrastructure.NormalizeBicepIdentifier($"{appEnvResource.Name}_law"))
{
Sku = new() { Name = OperationalInsightsWorkspaceSkuName.PerGB2018 },
Tags = tags
};

infra.Add(laWorkspace);

var containerAppEnvironment = new ContainerAppManagedEnvironment("cae")
var containerAppEnvironment = new ContainerAppManagedEnvironment(appEnvResource.GetBicepIdentifier())
{
WorkloadProfiles = [
new ContainerAppWorkloadProfile()
Expand Down Expand Up @@ -149,9 +149,10 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon

var resource = (AzureContainerAppEnvironmentResource)infra.AspireResource;

StorageAccount? storageVolume = null;
if (resource.VolumeNames.Count > 0)
{
var storageVolume = new StorageAccount("storageVolume")
storageVolume = new StorageAccount(Infrastructure.NormalizeBicepIdentifier($"{appEnvResource.Name}_storageVolume"))
{
Tags = tags,
Sku = new StorageSku() { Name = StorageSkuName.StandardLrs },
Expand Down Expand Up @@ -212,6 +213,33 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon
});
}

if (appEnvResource.UseAzdNamingConvention)
{
var resourceToken = new ProvisioningVariable("resourceToken", typeof(string))
{
Value = BicepFunction.GetUniqueString(BicepFunction.GetResourceGroup().Id)
};
infra.Add(resourceToken);

identity.Name = BicepFunction.Interpolate($"mi-{resourceToken}");
containerRegistry.Name = new FunctionCallExpression(
new IdentifierExpression("replace"),
new InterpolatedStringExpression(
[
new StringLiteralExpression("acr-"),
new IdentifierExpression(resourceToken.BicepIdentifier)
]),
new StringLiteralExpression("-"),
new StringLiteralExpression(""));
laWorkspace.Name = BicepFunction.Interpolate($"law-{resourceToken}");
containerAppEnvironment.Name = BicepFunction.Interpolate($"cae-{resourceToken}");

if (storageVolume is not null)
{
storageVolume.Name = BicepFunction.Interpolate($"vol{resourceToken}");
}
}

infra.Add(new ProvisioningOutput("MANAGED_IDENTITY_NAME", typeof(string))
{
Value = identity.Name
Expand Down Expand Up @@ -272,4 +300,21 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon

return builder.AddResource(containerAppEnvResource);
}

/// <summary>
/// Configures the container app environment resources to use the same naming conventions as azd.
/// </summary>
/// <param name="builder">The AzureContainerAppEnvironmentResource to configure.</param>
/// <returns><see cref="IResourceBuilder{T}"/></returns>
/// <remarks>
/// By default, the container app environment resources use a different naming convention than azd.
///
/// This method allows for reusing the previously deployed resources if the application was deployed using
/// azd without calling <see cref="AddAzureContainerAppEnvironment"/>
/// </remarks>
public static IResourceBuilder<AzureContainerAppEnvironmentResource> WithAzdResourceNaming(this IResourceBuilder<AzureContainerAppEnvironmentResource> builder)
{
builder.Resource.UseAzdNamingConvention = true;
return builder;
}
}
Loading
Loading