bicep
bicep copied to clipboard
Enabling languageVersion v2 breaks references to resource typed parameters by removing API versions
Bicep version Bicep CLI version 0.26.54 (5e20b29b58)
Describe the bug
Using the experimental feature resourceTypedParamsAndOutputs
alone with the following templates works fine:
// main.bicep
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'st${uniqueString(deployment().name)}'
location: 'westeurope'
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
properties: {
accessTier: 'Hot'
allowBlobPublicAccess: false
publicNetworkAccess: 'Disabled'
}
}
module myModule 'module.bicep' = {
name: 'myModule'
params: {
storageAccount: storageAccount
}
}
// module.bicep
param storageAccount resource 'Microsoft.Storage/storageAccounts@2023-01-01'
output blobEndpoint string = storageAccount.properties.primaryEndpoints.blob
However, if we start using user defined types or explicitly enable the experimental feature symbolicNameCodegen
to generate ARM templates with languageVersion: 2.0
, the same deployment fails with the error:
{"code": "InvalidTemplate", "target": "
", "message": "Deployment template validation failed: 'The resource 'Microsoft.Storage/storageAccounts/st5o3ihl5d3qzhs' referenced in output is not defined in the template. Please specify resource identifier and api version if the resource is outside of the template. Please see https://aka.ms/arm-function-reference for usage details.'.", "additionalInfo": [{"type": "TemplateViolation", "info": {"lineNumber": 0, "linePosition": 0, "path": ""}}]}
To Reproduce
Using the Bicep templates above, here is the ARM template generated with the "old" language version:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "11676319683145003944"
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[format('st{0}', uniqueString(deployment().name))]",
"location": "westeurope",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
},
"properties": {
"accessTier": "Hot",
"allowBlobPublicAccess": false,
"publicNetworkAccess": "Disabled"
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "myModule",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"storageAccount": {
"value": "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', uniqueString(deployment().name)))]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "14104008023461642064"
}
},
"parameters": {
"storageAccount": {
"type": "string",
"metadata": {
"resourceType": "Microsoft.Storage/storageAccounts@2023-01-01"
}
}
},
"resources": [],
"outputs": {
"blobEndpoint": {
"type": "string",
"value": "[reference(parameters('storageAccount'), '2023-01-01').primaryEndpoints.blob]"
}
}
}
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', uniqueString(deployment().name)))]"
]
}
]
}
This one deploys without issues.
If we then enable symbolicNameCodegen
and generate the ARM template anew, we get the following result with language version 2.0:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "17784816660608002450"
}
},
"resources": {
"storageAccount": {
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[format('st{0}', uniqueString(deployment().name))]",
"location": "westeurope",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
},
"properties": {
"accessTier": "Hot",
"allowBlobPublicAccess": false,
"publicNetworkAccess": "Disabled"
}
},
"myModule": {
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "myModule",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"storageAccount": {
"value": "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', uniqueString(deployment().name)))]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "16648886737782780637"
}
},
"parameters": {
"storageAccount": {
"type": "string",
"metadata": {
"resourceType": "Microsoft.Storage/storageAccounts@2023-01-01"
}
}
},
"resources": {},
"outputs": {
"blobEndpoint": {
"type": "string",
"value": "[reference(parameters('storageAccount')).primaryEndpoints.blob]"
}
}
}
},
"dependsOn": [
"storageAccount"
]
}
}
}
Comparing these ARM templates, we see that the API version is dropped from the reference
function when using language version 2.0.
Additional context
This issue also occurs in other cases where a resource typed parameter is referenced inside a module using languageVersion: 2.0
. For instance, we have a federated identity credential in one of our deployments:
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
...
resource hostFederation 'federatedIdentityCredentials' = {
name: serviceAccountName
properties: {
issuer: aksCluster.properties.oidcIssuerProfile.issuerURL
subject: 'system:serviceaccount:${namespace}:${serviceAccountName}'
audiences: [
'api://AzureADTokenExchange'
]
}
}
}
This deployment similarly fails, albeit with a slightly different message:
'The template resource 'Microsoft.ManagedIdentity/userAssignedIdentities/
/federatedIdentityCredentials/ ' reference to 'Microsoft.ContainerService/managedClusters/ ' requires an API version. Please see https://aka.ms/arm-syntax for usage details.'. (Code:InvalidTemplate)
This is because the generated ARM template contains the following reference:
"issuer": "[reference(parameters('aksCluster')).oidcIssuerProfile.issuerURL]",
Which should instead be:
"issuer": "[reference(parameters('aksCluster'), '2023-07-01').oidcIssuerProfile.issuerURL]",