Open davidfowl opened 3 months ago
For this I think we would need to change when the callback is evaluated. At the moment the callback is evaluated AFTER the internal one, at which point the KeyVaultSecret is already created. What we are really trying to accomplish here is replacing the default KeyVaultSecret creation behavior instead of adding onto the overall resource construction.
Right now if an azure resource declares a
BicepSecretOutputReference
the system will create a keyvault per azure resource to isolate the secrets within that keyvault for that specific resource. We want to allow a model where keyvault is shared so that means being able to carve out a unique prefix for secrets instead of a keyvault. To make this more generic, anAzureBicepResource
should expose a method to enable specifying a keyvault to store secrets.The empty keyvault name tells azd and the azure provisioning logic to create a keyvault for the
cache
resource and store the connection string (which contains secrets) in key vault.The other important part is that the bicep generated references the specified keyvault, and assumes that it can use the secret name
connectionString
which also maps to the secret output name.AzureRedisResource
```C# // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Hosting.ApplicationModel; namespace Aspire.Hosting.Azure; ////// Represents an Azure Redis resource. ///
/// The inner resource. /// Callback to populate the construct with Azure resources. public class AzureRedisResource(RedisResource innerResource, Action/// Gets the "connectionString" output reference from the bicep template for the Azure Redis resource. ///
public BicepSecretOutputReference ConnectionString => new("connectionString", this); ////// Gets the connection string template for the manifest for the Azure Redis resource. ///
public ReferenceExpression ConnectionStringExpression => ReferenceExpression.Create($"{ConnectionString}"); ///Bicep
```bicep targetScope = 'resourceGroup' @description('') param location string = resourceGroup().location @description('') param keyVaultName string resource keyVault_IeF8jZvXV 'Microsoft.KeyVault/vaults@2022-07-01' existing = { name: keyVaultName } resource redisCache_enclX3umP 'Microsoft.Cache/Redis@2020-06-01' = { name: toLower(take('cache${uniqueString(resourceGroup().id)}', 24)) location: location tags: { 'aspire-resource-name': 'cache' } properties: { enableNonSslPort: false minimumTlsVersion: '1.2' sku: { name: 'Basic' family: 'C' capacity: 1 } } } resource keyVaultSecret_Ddsc3HjrA 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = { parent: keyVault_IeF8jZvXV name: 'connectionString' location: location properties: { value: '${redisCache_enclX3umP.properties.hostName},ssl=true,password=${redisCache_enclX3umP.listKeys(redisCache_enclX3umP.apiVersion).primaryKey}' } } ```We want to allow the user to specify their own keyvault. To make this work, we should provide either a global way, or a per resource way for that to be specified e.g:
This method would set the keyvault name and it would generate a unique prefix for this resource to isolate secrets from other resources.