Improve Type checking on related properties
- Dominant language
- Bicep
- Stars
- 3.6k
- Forks
- 830
- Avg merge
- 1d 21m
- Merged PRs (30d)
- 79
Description
**Is your feature request related to a problem? Please describe.**
I spent a while today investigating why the following template didn't work. The problem ultimately being that the `logAnalytics` resource was using the wrong type (it should be `Microsoft.OperationalInsights/workspace`), and thus produced the wrong resource id
```bicep
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
properties: {
WorkspaceResourceId: logAnalytics.id
}
}
resource logAnalytics 'Microsoft.OperationalInsights/clusters@2021-06-01' existing = {
name: workspaceName
}
```
This feels like an error the bicep type system could capture.
**Describe the solution you'd like**
Ideally bicep should know that `WorkspaceResourceId` is looking for a resource id of a `Microsoft.OperationalInsights/workspace`. The bicep type system could then know that `logAnalytics.id` is not a resource id of `Microsoft.OperationalInsights/workspace` and produce a compile error.
This would require some kind of annotation in the API specs so that bicep would know that `WorkspaceResoruceId` maps to the resoruce id of a `Microsoft.OperationalInsights/workspace` resource. OpenApi's `format` property could be useful here e.g.
```json
"WorkspaceResourceId": {
"type": "string",
"format": "Microsoft.OperationalInsights/workspace.id",
"description": "Resource Id of the log analytics workspace which the data will be ingested to. This property is required to create an application with this API version. Applications from older versions will not have this property."
},
```
https://github.com/Azure/azure-rest-api-specs/blob/5582a35deb1bfa4aa22bac8f1d51b7934ead94ac/specification/applicationinsights/resource-manager/Microsoft.Insights/stable/2020-02-02/components_API.json#L585-L588
The problem with this solution is you still need to support arbitrary strings for backwards compatibility. This brings you back to the problem with `name` for child resources today where the compiler sometimes detects errors, but not always
An alternative solution for scenarios like this is to generate a property that takes the resource type directly.
```bicep
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
properties: {
Workspace: logAnalytics
}
}
```
The bicep compiler would ultimately lower this to use `WorkspaceResourceId`:
```bicep
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
properties: {
WorkspaceResourceId: logAnalytics.id
}
}
```
This has the advantage of knowing that when you use `Workspace`, you always get the compiler validation, and when you use `WorkspaceResourceId` you never get validation (beyond it being a `string`), but it may cause confusion now there is both `Workspace` and `WorkspaceResourceId`.
Contributor guide
Research direction
Start by reviewing the linked components_API.json section at lines 585-588 and the issue's two proposed approaches for representing related resource types. Then trace the Bicep compiler's type-checking entry point for resource properties. Done requires an agreed design that preserves arbitrary string compatibility while validating related resource references.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100