Azure / bicep

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

"The language expression property ... does not exist" despite auto completion saying it does. #2419

Open afscrome opened 3 years ago

afscrome commented 3 years ago

Bicep version Bicep CLI version 0.3.255 (589f0375df) VSCode 0.3.255

Describe the bug

Auto Completion will recommend the identity property as existing on a web app resource. However this property isn't always defined, and thus if you try and access it in an output variable, it can lead to a deployment time error.

Deployment failed. Correlation ID: f5cd8380-c1db-4288-bb5e-db69abe1e4dc. The template output 'principalId' is not valid: The language expression property 'identity' doesn't exist, available properties are 'apiVersion, location, tags, kind, properties, subscriptionId, resourceGroupName, scope, resourceId, referenceApiVersion, condition, isConditionTrue, isTemplateResource, isAction, provisioningOperation'..

Is it possible for bicep to detect this and turn this error into a compile time error/warning. (e.g. if the identity property was marked as nullable on the web apps API, could bicep present a warning on output x string = webApp.identity.principalId about trying to access the principalId property on a potentially null value?

To Reproduce

resource serverFarm 'Microsoft.Web/serverfarms@2020-12-01' = {
  name: 'foo'
  location: resourceGroup().location
  sku: {
    name: 'S1'
    tier: 'Standard'
  }
}

resource webApp 'Microsoft.Web/sites@2020-12-01' = {
  name: 'foo'
  location: resourceGroup().location
  properties: {
    httpsOnly: true
    serverFarmId: serverFarm.id
  }
}

output principalId string = webApp.identity.principalId

Additional context

The root cause here is that the web app only contains an identity property if it has an identity assigned. (In hindsight this makes sense, although the error from the ARM Api isn't particularly helpful at helping you realise the root cause)

The above template can be fixed by specifying a managed identity on the webApp resource:

identity: {
  type: 'SystemAssigned'
}
alex-frankel commented 3 years ago

Good find - it would be great if we could somehow catch this at least for new resource declarations. For an existing resource, I don't think we would be able to know if the identity property was set until runtime.