azure-dev icon indicating copy to clipboard operation
azure-dev copied to clipboard

Azd-Aspire-Cdk: Naming strategy

Open vhvb1989 opened this issue 1 year ago • 3 comments

Ideally, a decision needs to be made for Aspire GA for how resource names are generated.

From @tg-msft:

I want to have a “name strategy” that by default keeps them stable but also allows you to randomize aggressively if desired for niche scenarios. Stable requires tracking the full namespace though to use kv2 occasionally instead of kv277327222773 always. We also need to be smarter about the various lengths (i.e. using a prefix with the first 24 identical characters for two Storage accounts should throw).

azd

For naming resources, azd is following the next strategy:

    1. Creates a unique hash using the resource group:
var resourceToken = uniqueString(resourceGroup().id)
    1. Manage identity and resources which supports a name with dashes. Use a prefix depending on the resource followed by a dash and the unique hash.
name: 'mi-${resourceToken}'
    1. Container registry and resources which don't support dashes. Follow the previous rule but remove all dashes from the result name.
name: replace('acr-${resourceToken}', '-', '')
    1. Role assignments and resources which might be more than one in the same deployment. The base rule of prefix creates a collision when having more than one. The name is a uniqueId created from the resource inputs:
name: guid(containerRegistry.id, managedIdentity.id, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d'))
    1. Secure outputs. Azd creates a key vault for resources which requires to set secrets and needs to be accessible to azd for deployment. This strategy prevents from having sensitive data as bicep outputs. For example, instead of setting the connection string for a DB as a bicep output, the connection string is saved with a key vault secret. Azd defines a key vault account for each resource expressing the need of secret outputs. To name a key vaults, azd follows the next strategy:
name: replace('kv${resourceName}${resourceToken}', '-', '')

Note: if the resouceName is large enough and adding kv and ${resourceToken}' goes beyond 24 characters, deployment fails because key vault accounts names can't be greater than 24 characters. To mitigate this, azd ensures that resourceName is never greater than 12 characters, by producing a hash from the resourceName.

Aspire + Cdk

Bicep modules created by Aspire utilize the Cdk, which writes the next naming pattern:

name: toLower(take(concat('${resourceName}', uniqueString(resourceGroup().id)), 24))

while the strategy secures the names with no dashes, it is still vulnerable to long resource names.

@davidfowl @mitchdenny @JoshLove-msft

vhvb1989 avatar Mar 29 '24 22:03 vhvb1989

What happens if multiple resources of the same type are added to the same resource group - would there be a collision?

JoshLove-msft avatar Mar 30 '24 20:03 JoshLove-msft

What happens if multiple resources of the same type are added to the same resource group - would there be a collision?

There are scenarios, when thinking about adding resources:

    1. A resource referenced in the AppHost with a name. This is the case where users explicitly define a resource. For example, adding storage account, or a cosmosDB. The user must provide a unique name for each resource, and if they name two resources the same way, the program fails to compile and throw error about the duplication. Currently, all this cases are covered by using cdk to produce a bicep module for each resource.
    1. Auxiliar / auto-generated resources. This type of resources can be either explicitly referenced by the customer, but if not, Aspire is currently depending on azd (or the cloud specific publisher) to create those resources. For example, the container registry or the key vault accounts for secret outputs (mentioned in issue description). Azd uses takes the name of the resource which requires this auto-generated resource to produce a unique name. Another example is the container-volumes set up, where azd needs to create one storage account for each container that defines volumes, and then one fileShare for in the storage account for each volume.

vhvb1989 avatar Mar 30 '24 22:03 vhvb1989

I think as a general rule child resources (databases, keyvault secrets, eventhubs, queues/topics etc) just use whatever name the developer provides. We are really talking about top level DNS defining names where the potential for conflicts in Azure exists.

If the name is a hash(resourceGroup().id + aspireResourceName) then there can never be a collision. All you have to manage at that point is the naming rules for a particular resource:

  1. Typically can't have a leading number.
  2. Can't exceed some defined length.
  3. Can't use - sometimes (e.g. storage)

My strategy would be to take the most restrictive subset of names and come up with a general formula for computing the name along those lines. Historically I've just done hash(resourceGroup().id + name) and appended something short to not violate rule #1 above - then truncated the valute to meet length constraints.

mitchdenny avatar Mar 31 '24 23:03 mitchdenny

Closing this as not required anymore on the publishers model. AZD should not be generating names/resources and there will be no expectation of supporting old project versions

vhvb1989 avatar May 15 '25 00:05 vhvb1989