The old ways
Up until now I’ve been using the reference function fetch a registration token. It’s possible to specify an explicit api-version:
output token1 object = reference(hostPool.id, '2023-09-05').registrationInfo.token
output token2 string = reference(hostPool.id).registrationInfo.token
The bicep compiles to this json:
"[reference(resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostpoolName')), '2023-09-05').registrationInfo.token]"
"[reference(resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostpoolName'))).registrationInfo.token)]"
Recent errors
Recently these deployments has began to fail in some envornments, with the errors:
-
…The language expression property ’token’ can’t be evaluated.
-
…Expected a value of type ‘String, Uri’ but received a value of type ‘Null’.
Introducing listRegistrationTokens()
In GitHub issue Azure/bicep-types-az/issues/2023 Microsoft FTE @shenglol shows the new resource function listRegistrationTokens()
. The function is as of 2024.08.12 not yet documented in the bicep documentation or outside of the API spec, to the best of my knowledge… The API-call is documented here
The function returns object with a list of objects with a token and the expirationTime:
{
"value": [
{
"expirationTime": "2024-08-13T00:00:00Z",
"token": "eyJh[REDACTED].eyJS[REDACTED].Kii[REDACTED]"
}
]
}
Here is some usage with it:
output tokenRootObject object = hostpool.listRegistrationTokens()
output tokenList array = hostpool.listRegistrationTokens().value
output tokenInnerObj object = hostpool.listRegistrationTokens().value[0]
output token string = first(hostpool.listRegistrationTokens().value).token
Linter support
Usage of any list*
function allows the linter to know this is a secret, and give recommendations based on that. In the old ways, the api-versions had the token
property not marked as a secret, thus allowing it to be fetched though GET requests.
Full Bicep example
Full bicep example (CLICK TO EXPAND)
@description('The name of the hostpool')
param hostpoolName string = 'vdpool-listregtoken-001'
@description('Location for all resources to be created in.')
param location string = resourceGroup().location
param tokenExpirationTime string = dateTimeAdd(utcNow('yyyy-MM-dd T00:00:00'), 'P1D', 'o')
resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' = {
name: hostpoolName
location: location
properties: {
hostPoolType: 'Pooled'
loadBalancerType: 'BreadthFirst'
maxSessionLimit: 5
description: 'first avd host pool'
friendlyName: 'friendly name'
preferredAppGroupType: 'Desktop'
registrationInfo: {
expirationTime: tokenExpirationTime
registrationTokenOperation: 'Update'
}
}
}
// old
// output registrationInfo object = reference(hostPool.id).registrationInfo
// output token object = reference(hostPool.id).registrationInfo.token
// new
output registrationTokens object = first(hostPool.listRegistrationTokens().value)
output token object = first(hostPool.listRegistrationTokens().value).token