Enabling languageVersion v2 breaks references to resource typed parameters by removing API versions
- Dominant language
- Bicep
- Stars
- 3.6k
- Forks
- 830
- Avg merge
- 1d 21m
- Merged PRs (30d)
- 79
Description
**Bicep version**
Bicep CLI version 0.26.54 (5e20b29b58)
**Describe the bug**
Using the experimental feature `resourceTypedParamsAndOutputs` alone with the following templates works fine:
```bicep
// 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
}
}
```
```bicep
// 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:
```json
{
"$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:
```json
{
"$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:
```bicep
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:
```bicep
"issuer": "[reference(parameters('aksCluster')).oidcIssuerProfile.issuerURL]",
```
Which should instead be:
```bicep
"issuer": "[reference(parameters('aksCluster'), '2023-07-01').oidcIssuerProfile.issuerURL]",
```
Contributor guide
Assessment
This issue has not been assessed yet.