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 @@ -38,57 +38,68 @@ public static IResourceBuilder<AzureApplicationInsightsResource> AddAzureApplica

var configureInfrastructure = (AzureResourceInfrastructure infrastructure) =>
{
var appTypeParameter = new ProvisioningParameter("applicationType", typeof(string))
{
Value = "web"
};
infrastructure.Add(appTypeParameter);
var appInsights = AzureProvisioningResource.CreateExistingOrNewProvisionableResource(infrastructure,
(identifier, name) =>
{
var resource = ApplicationInsightsComponent.FromExisting(identifier);
resource.Name = name;
return resource;
},
(infrastructure) =>
{
var appTypeParameter = new ProvisioningParameter("applicationType", typeof(string))
{
Value = "web"
};
infrastructure.Add(appTypeParameter);

var kindParameter = new ProvisioningParameter("kind", typeof(string))
{
Value = "web"
};
infrastructure.Add(kindParameter);
var kindParameter = new ProvisioningParameter("kind", typeof(string))
{
Value = "web"
};
infrastructure.Add(kindParameter);

var appInsights = new ApplicationInsightsComponent(infrastructure.AspireResource.GetBicepIdentifier())
{
ApplicationType = appTypeParameter,
Kind = kindParameter,
Tags = { { "aspire-resource-name", name } }
};
infrastructure.Add(appInsights);
var appInsights = new ApplicationInsightsComponent(infrastructure.AspireResource.GetBicepIdentifier())
{
ApplicationType = appTypeParameter,
Kind = kindParameter,
Tags = { { "aspire-resource-name", name } }
};

if (logAnalyticsWorkspace != null)
{
// If someone provides a workspace via the extension method we should use it.
appInsights.WorkspaceResourceId = logAnalyticsWorkspace.Resource.WorkspaceId.AsProvisioningParameter(infrastructure, AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId);
}
else if (builder.ExecutionContext.IsRunMode)
{
// ... otherwise if we are in run mode, the provisioner expects us to create one ourselves.
var autoInjectedLogAnalyticsWorkspaceName = $"law_{appInsights.BicepIdentifier}";
var autoInjectedLogAnalyticsWorkspace = new OperationalInsightsWorkspace(autoInjectedLogAnalyticsWorkspaceName)
{
Sku = new OperationalInsightsWorkspaceSku()
if (logAnalyticsWorkspace != null)
{
// If someone provides a workspace via the extension method we should use it.
appInsights.WorkspaceResourceId = logAnalyticsWorkspace.Resource.WorkspaceId.AsProvisioningParameter(infrastructure, AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId);
}
else if (builder.ExecutionContext.IsRunMode)
{
// ... otherwise if we are in run mode, the provisioner expects us to create one ourselves.
var autoInjectedLogAnalyticsWorkspaceName = $"law_{appInsights.BicepIdentifier}";
var autoInjectedLogAnalyticsWorkspace = new OperationalInsightsWorkspace(autoInjectedLogAnalyticsWorkspaceName)
{
Sku = new OperationalInsightsWorkspaceSku()
{
Name = OperationalInsightsWorkspaceSkuName.PerGB2018
},
Tags = { { "aspire-resource-name", autoInjectedLogAnalyticsWorkspaceName } }
};
infrastructure.Add(autoInjectedLogAnalyticsWorkspace);

// If the user does not supply a log analytics workspace of their own we still create a parameter on the Aspire
// side and the CDK side so that AZD can fill the value in with the one it generates.
appInsights.WorkspaceResourceId = autoInjectedLogAnalyticsWorkspace.Id;
}
else
{
Name = OperationalInsightsWorkspaceSkuName.PerGB2018
},
Tags = { { "aspire-resource-name", autoInjectedLogAnalyticsWorkspaceName } }
};
infrastructure.Add(autoInjectedLogAnalyticsWorkspace);
// If the user does not supply a log analytics workspace of their own, and we are in publish mode
// then we want AZD to provide one to us.
var logAnalyticsWorkspaceParameter = new ProvisioningParameter(AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId, typeof(string));
infrastructure.Add(logAnalyticsWorkspaceParameter);
appInsights.WorkspaceResourceId = logAnalyticsWorkspaceParameter;
}

// If the user does not supply a log analytics workspace of their own we still create a parameter on the Aspire
// side and the CDK side so that AZD can fill the value in with the one it generates.
appInsights.WorkspaceResourceId = autoInjectedLogAnalyticsWorkspace.Id;
}
else
{
// If the user does not supply a log analytics workspace of their own, and we are in publish mode
// then we want AZD to provide one to us.
var logAnalyticsWorkspaceParameter = new ProvisioningParameter(AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId, typeof(string));
infrastructure.Add(logAnalyticsWorkspaceParameter);
appInsights.WorkspaceResourceId = logAnalyticsWorkspaceParameter;
}
return appInsights;
});

infrastructure.Add(new ProvisioningOutput("appInsightsConnectionString", typeof(string)) { Value = appInsights.ConnectionString });
};
Expand Down
34 changes: 20 additions & 14 deletions src/Aspire.Hosting.Azure.CognitiveServices/AzureOpenAIExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,29 @@ public static IResourceBuilder<AzureOpenAIResource> AddAzureOpenAI(this IDistrib

var configureInfrastructure = (AzureResourceInfrastructure infrastructure) =>
{
var cogServicesAccount = new CognitiveServicesAccount(infrastructure.AspireResource.GetBicepIdentifier())
{
Kind = "OpenAI",
Sku = new CognitiveServicesSku()
var cogServicesAccount = AzureProvisioningResource.CreateExistingOrNewProvisionableResource(infrastructure,
(identifier, name) =>
{
Name = "S0"
var resource = CognitiveServicesAccount.FromExisting(identifier);
resource.Name = name;
return resource;
},
Properties = new CognitiveServicesAccountProperties()
(infrastructure) => new CognitiveServicesAccount(infrastructure.AspireResource.GetBicepIdentifier())
{
CustomSubDomainName = ToLower(Take(Concat(infrastructure.AspireResource.Name, GetUniqueString(GetResourceGroup().Id)), 24)),
PublicNetworkAccess = ServiceAccountPublicNetworkAccess.Enabled,
// Disable local auth for AOAI since managed identity is used
DisableLocalAuth = true
},
Tags = { { "aspire-resource-name", infrastructure.AspireResource.Name } }
};
infrastructure.Add(cogServicesAccount);
Kind = "OpenAI",
Sku = new CognitiveServicesSku()
{
Name = "S0"
},
Properties = new CognitiveServicesAccountProperties()
{
CustomSubDomainName = ToLower(Take(Concat(infrastructure.AspireResource.Name, GetUniqueString(GetResourceGroup().Id)), 24)),
PublicNetworkAccess = ServiceAccountPublicNetworkAccess.Enabled,
// Disable local auth for AOAI since managed identity is used
DisableLocalAuth = true
},
Tags = { { "aspire-resource-name", infrastructure.AspireResource.Name } }
});

infrastructure.Add(new ProvisioningOutput("connectionString", typeof(string))
{
Expand Down
56 changes: 42 additions & 14 deletions src/Aspire.Hosting.Azure.CosmosDB/AzureCosmosDBExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,26 +324,36 @@ public static IResourceBuilder<AzureCosmosDBResource> WithAccessKeyAuthenticatio
private static void ConfigureCosmosDBInfrastructure(AzureResourceInfrastructure infrastructure)
{
var azureResource = (AzureCosmosDBResource)infrastructure.AspireResource;
bool disableLocalAuth = !azureResource.UseAccessKeyAuthentication;

var cosmosAccount = new CosmosDBAccount(infrastructure.AspireResource.GetBicepIdentifier())
{
Kind = CosmosDBAccountKind.GlobalDocumentDB,
ConsistencyPolicy = new ConsistencyPolicy()
var cosmosAccount = AzureProvisioningResource.CreateExistingOrNewProvisionableResource(infrastructure,
(identifier, name) =>
{
DefaultConsistencyLevel = DefaultConsistencyLevel.Session
var resource = new ExistingCosmosDBAccount(identifier, disableLocalAuth)
{
Name = name,
};
return resource;
},
DatabaseAccountOfferType = CosmosDBAccountOfferType.Standard,
Locations =
(infrastructure) => new CosmosDBAccount(infrastructure.AspireResource.GetBicepIdentifier())
{
Kind = CosmosDBAccountKind.GlobalDocumentDB,
ConsistencyPolicy = new ConsistencyPolicy()
{
DefaultConsistencyLevel = DefaultConsistencyLevel.Session
},
DatabaseAccountOfferType = CosmosDBAccountOfferType.Standard,
Locations =
{
new CosmosDBAccountLocation
{
LocationName = new IdentifierExpression("location"),
FailoverPriority = 0
}
},
Tags = { { "aspire-resource-name", infrastructure.AspireResource.Name } }
};
infrastructure.Add(cosmosAccount);
DisableLocalAuth = disableLocalAuth,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this. Setting this directly on the resource instead of after the fact reads better as well.

Tags = { { "aspire-resource-name", infrastructure.AspireResource.Name } }
});

foreach (var database in azureResource.Databases)
{
Expand Down Expand Up @@ -376,8 +386,6 @@ private static void ConfigureCosmosDBInfrastructure(AzureResourceInfrastructure

if (azureResource.UseAccessKeyAuthentication)
{
cosmosAccount.DisableLocalAuth = false;

var kvNameParam = new ProvisioningParameter(AzureBicepResource.KnownParameters.KeyVaultName, typeof(string));
infrastructure.Add(kvNameParam);

Expand All @@ -398,8 +406,6 @@ private static void ConfigureCosmosDBInfrastructure(AzureResourceInfrastructure
}
else
{
cosmosAccount.DisableLocalAuth = true;

var principalTypeParameter = new ProvisioningParameter(AzureBicepResource.KnownParameters.PrincipalType, typeof(string));
infrastructure.Add(principalTypeParameter);

Expand Down Expand Up @@ -428,6 +434,28 @@ private static void ConfigureCosmosDBInfrastructure(AzureResourceInfrastructure
}
}

/// <remarks>
/// The provisioning APIs will mark the DisableLocalAuth as `ReadOnly` after the
/// `IsExistingResource` property is set, making it impossible to configure the
/// `DisableLocalAuth` property in our usual flows. This is a workaround to
/// allow us to set the property on existing resources.
/// </remarks>
internal sealed class ExistingCosmosDBAccount : CosmosDBAccount
{
public ExistingCosmosDBAccount(string bicepIdentifier, bool disableLocalAuth, string? resourceVersion = null) : base(bicepIdentifier, resourceVersion)
{
// only explicitly set DisableLocalAuth if WithAccessKeyAuthentication was called.
// We don't want to disable local auth on an existing resource if it is already enabled
// as that might break other uses of the resource.
if (disableLocalAuth is false)
{
DisableLocalAuth = false;
}

IsExistingResource = true;
}
}

// The following classes are working around https://github.com/Azure/azure-sdk-for-net/issues/47979 and can be removed once the issue is fixed.

internal class CosmosDBSqlRoleDefinition_Derived : CosmosDBSqlRoleDefinition
Expand Down
Loading
Loading