Bicep snapshot inaccuracies and validation crashes with microsoftGraphV1
- Dominant language
- Bicep
- Stars
- 3.6k
- Forks
- 830
- Avg merge
- 1d 21m
- Merged PRs (30d)
- 79
Description
**Bicep version**
Bicep CLI version 0.39.26 (1e90b06e40)
**Describe the bug**
Conditionally created objects generates `null`s instead of `[reference('...').appId]`
As a result bicep snapshot --mode validate fails:
command: `bicep snapshot bug-report.bicepparam --mode validate`
```
Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Text.Json.JsonElement.GetProperty(String)
at Bicep.Cli.Helpers.Snapshot.SnapshotDiffer.ConvertToWhatIfResource(JsonElement resource)
at System.Linq.Enumerable.SelectArrayIterator`2.Fill(ReadOnlySpan`1, Span`1, Func`2)
at System.Linq.Enumerable.SelectArrayIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1)
at Bicep.Cli.Helpers.Snapshot.SnapshotDiffer.CalculateChanges(Snapshot source, Snapshot target)
at Bicep.Cli.Commands.SnapshotCommand.RunAsync(SnapshotArguments args, CancellationToken cancellationToken)
at Bicep.Cli.Program.RunAsync(String[] args, CancellationToken cancellationToken)
at Bicep.Cli.Program.<>c__DisplayClass3_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Bicep.Cli.Program.RunWithCancellationAsync(Func`2 runFunc)
at Bicep.Cli.Program.Main(String[] args)
at Bicep.Cli.Program.(String[] args)
```
**To Reproduce**
bug-report.bicep:
```
extension microsoftGraphV1
param clientAppName string?
param clientAppName2 string = ''
param signInAudience string = 'AzureADMyOrg'
param appRoleId string = ''
param assignClientToResource bool = true
resource clientAppWorking 'Microsoft.Graph/applications@v1.0' = {
displayName: 'clientAppWorking'
uniqueName: 'clientAppWorking'
signInAudience: signInAudience
}
resource clientAppWorkingSp 'Microsoft.Graph/servicePrincipals@v1.0' = {
appId: clientAppWorking.appId
appRoleAssignmentRequired: true
}
resource clientApp 'Microsoft.Graph/applications@v1.0' = if (clientAppName != null) {
displayName: clientAppName!
uniqueName: clientAppName!
signInAudience: signInAudience
}
resource clientSp 'Microsoft.Graph/servicePrincipals@v1.0' = if (clientAppName != null) {
appId: clientApp.?appId!
appRoleAssignmentRequired: true
}
resource clientApp2 'Microsoft.Graph/applications@v1.0' = if (!empty(clientAppName2)) {
displayName: clientAppName2
uniqueName: clientAppName2
signInAudience: signInAudience
}
resource clientSp2 'Microsoft.Graph/servicePrincipals@v1.0' = if (!empty(clientAppName2)) {
appId: clientApp2.?appId!
appRoleAssignmentRequired: true
}
resource appRoleAssigment 'Microsoft.Graph/appRoleAssignedTo@v1.0' = if (clientAppName != null && assignClientToResource) {
appRoleId: appRoleId
principalId: clientSp.?id!
resourceId: '1a134043-d9f0-4e50-be25-12a81c6e6c7b'
}
output clientAppId string = clientApp.?appId ?? 'N/A'
output clientAppOid string = clientApp.?id ?? 'N/A'
output clientSpOid string = clientSp.?id ?? 'N/A'
```
bug-report.bicepparam
```
using './bug-report.bicep'
param clientAppName = 'asbasasaqiuhd'
param clientAppName2 = 'aasasaas'
```
Following snapshot is being generated:
```
{
"predictedResources": [
{
"properties": {
"displayName": "clientAppWorking",
"uniqueName": "clientAppWorking",
"signInAudience": "AzureADMyOrg"
},
"type": "Microsoft.Graph/applications@v1.0"
},
{
"properties": {
"appId": "[reference('clientAppWorking').appId]",
"appRoleAssignmentRequired": true
},
"type": "Microsoft.Graph/servicePrincipals@v1.0"
},
{
"properties": {
"displayName": "asbasasaqiuhd",
"uniqueName": "asbasasaqiuhd",
"signInAudience": "AzureADMyOrg"
},
"type": "Microsoft.Graph/applications@v1.0"
},
{
"properties": {
"appId": null,
"appRoleAssignmentRequired": true
},
"type": "Microsoft.Graph/servicePrincipals@v1.0"
},
{
"properties": {
"displayName": "aasasaas",
"uniqueName": "aasasaas",
"signInAudience": "AzureADMyOrg"
},
"type": "Microsoft.Graph/applications@v1.0"
},
{
"properties": {
"appId": null,
"appRoleAssignmentRequired": true
},
"type": "Microsoft.Graph/servicePrincipals@v1.0"
},
{
"properties": {
"appRoleId": "",
"principalId": null,
"resourceId": "1a134043-d9f0-4e50-be25-12a81c6e6c7b"
},
"type": "Microsoft.Graph/appRoleAssignedTo@v1.0"
}
],
"diagnostics": []
}
```
Notice how `appId` and `principalId`are being set to null on resources using conditionally created resources
**Additional context**
This is extracted from bigger template
Contributor guide
Research direction
Reproduce the issue with bug-report.bicep and bug-report.bicepparam, then start at SnapshotCommand.RunAsync and SnapshotDiffer.ConvertToWhatIfResource in the stack trace. Trace how conditional resource references become null in the generated predictedResources and how validation expects those entries. Done means the snapshot preserves the expected reference expressions and bicep snapshot --mode validate completes without the KeyNotFoundException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure
- Domain
- cli, compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100