Azure / bicep

Bicep is a declarative language for describing and deploying Azure resources
MIT License
3.26k stars 754 forks source link

Tooling to have schema aware outputs #3196

Open nianton opened 3 years ago

nianton commented 3 years ago

It would be great when a module has a "strongly typed" object output, to be able to reference its properties from the bicep file consuming the module.

Sample module:

param message string

output foo object = {
  bar: 'xxxx'
  anotherProperty: 1234
  input: message
}

So the desired output would be to list the properties of the output object ('bar', 'anotherProperty' and 'input') in the following usage of the above module:

image

An ARM Template has the limitation of allowing only 64 outputs, and when working around this limitation by including those values to an object output, there is no intellisense/help during coding on its schema to reference the values/properties.

anthony-c-martin commented 3 years ago

This is a really good suggestion and would significantly improve the module authoring experience!

I've also been wondering the same thing about validating param inputs, but it's a little more tricky as you may end up with false positives or ambiguous cases.

For example in the following file, we know that the only properties accessed off foo are abc and def, so you could offer them as completions when validating inputs:

param foo object

var test = foo.abc
var test2 = foo.def

I imagine this could be useful in conjunction with typed resource definitions - e.g. in the following, you could offer pipPrefix and pip as completions, but you could also offer the correct set of enum values for each sku in calling modules:

param skus object

resource ipprefix 'Microsoft.Network/publicIPPrefixes@2020-05-01' = {
  sku: {
    name: skus.pipPrefix
  }
  ...
}

resource publicip 'Microsoft.Network/publicIPAddresses@2020-05-01' = {
  sku: {
    name: skus.pip
  }
  ...
}

Here's an example where it's not possible to give an accurate list of completions/validation:

// type would have to be 'any'
param unused object

// type would have to be 'any'
param runtimeAccess object
var test = runtimeAccess[resourceGroup().location]
jeskew commented 1 year ago

User-defined types can be applied to outputs, which will enable output property completions.

The team previously discussed and decided not to implement output type inference in #10421. Bicep can infer rich type information about an output in a module authored in Bicep, but the compiler's ability to do so in a JSON module (which includes any registry module) is very limited. If type inference in JSON modules improves, this can be revisited.