Open dciborow opened 1 year ago
@jeskew fyi
Azure resource types can distinguish between 'open' and 'closed' enums, so the Bicep type system would be able to handle this change pretty easily. For example, in a Microsoft.KeyVault/vaults
's sku
property, family
is an 'open' enum (in that it will autocomplete the known value of 'A'
but will also permit any string), and name
is a 'closed' enum (in that only 'standard'
or 'premium'
is accepted; all other strings are considered a type mismatch).
The Bicep syntax for this should be pretty straightforward. We can either allow non-literal members in unions:
param os 'win10' | string
or have a special decorator:
@openEnum()
param os 'win10'
The bigger question would be how to represent this in an ARM template. An open enum by definition won't have any runtime validation behavior, so it should probably be metadata, e.g.,
{
"os": {
"type": "string",
"metadata": {
"description": "Create new or use existing Public IP resource",
"_bicep_autocomplete_suggestions": [
"new",
"existing"
]
}
}
}
The bigger question would be how to represent this in an ARM template. An open enum by definition won't have any runtime validation behavior, so it should probably be metadata, e.g.,
Could we put it in the ARM template similar to how the custom types are done? Using a similar notation to required
, perhaps something like this, where these both compile to the same ARM template.
@recommend(['win10', 'linux'])
type osRecommend string
param os osRecommend
@recommended(['win10', 'linux'])
param os string
can we add 'Allowed' annotation here with the list of "kinds". Even though the kinds are not defined in the public swagger.
(totally optional, but perhaps a good place to create a user-defined type)
@allowed(['CognitiveServices', 'ComputerVision', 'CustomVision.Prediction', 'CustomVision.Training', 'Face', 'FormRecognizer', 'SpeechServices', 'LUIS', 'QnAMaker', 'TextAnalytics', 'TextTranslation', 'AnomalyDetector', 'ContentModerator', 'Personalizer', 'OpenAI'])
param kind string
_Originally posted by @dciborow in https://github.com/Azure/bicep-registry-modules/pull/404#discussion_r1237284170_
This would be an really nice feature. It's a super common use case that platform teams want to provide recommendations for developers without enforcing them.
Is there a workaround for this?
Is your feature request related to a problem? Please describe.
Users should be able to pass in values even if their are not 'allowed'.
The
allowed
has many benefits, such as improving the user experience when writing a Bicep template. But there are cases where all of the allowed values cannot be known. It may be that some allowed values are secrets that can't be initially shared. (I ran into this issue for GameDev VM, where we had to remove our allowed values to let some users try "win11-unreal-engine").vm.bicep
This module is an example, and is not configurable by the user. It could be in a public registry.
main.bicep
This module is written by the end-user, who is provided a option which has been made to them before the module was updated.
This will help to enable advanced use cases for user-defined types, like a
Location
type which is difficult to fully capture in a allowed Values field, but could be created that at least covers a majority of use cases.Describe the solution you'd like
I should be able to deploy the above example. This should still initially raise errors, and the user should have to perform some action to suppress this. This should then produce a warning. The warning should explain that the error is being suppressed, and that the user is trying to use a value that is not allowed. That could also be suppressed by the user.
This could be done entirely in bicep, where the error suppression is detected and casts instances of os to simple strings without any restrictions on the values.
The main.json would either no longer contain the allowedValues, or they would be commented out explaining they have been suppressed.
main.json