Azure / bicep

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

False Positive 'use-resource-id-functions' when using complex params #10732

Open dciborow opened 1 year ago

dciborow commented 1 year ago

Describe the bug Per this new Module: https://github.com/Azure/bicep-registry-modules/pull/345

The following code causes the issue use-resource-id-functions, when using endpoint.subnetId, even though it is coming from parameter.

privateEndpoint.bicep

param privateEndpoints privateEndpointsType[]

@batchSize(1)
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2022-05-01' = [for endpoint in privateEndpoints: {
  name: '${endpoint.name}-${uniqueString(endpoint.name, endpoint.subnetId, endpoint.privateLinkServiceId)}'
  location: location
  tags: tags
  properties: {
    privateLinkServiceConnections: endpoint.manualApprovalEnabled
    manualPrivateLinkServiceConnections: endpoint.manualApprovalEnabled
    subnet: {
      id: endpoint.subnetId
    }
    customNetworkInterfaceName: endpoint.?customNetworkInterfaceName ?? null
  }
}]

privateEndpoint.bicep(11,7) : Warning use-resource-id-functions: If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. [https://aka.ms/bicep/linter/use-resource-id-functions]

StephenWeatherford commented 12 months ago

Seems to only repro with user-defined types (experimental):

type virtualNetworkRuleType = {
  @minLength(1)
  @maxLength(128)
  @description('The resource name.')
  name: string
  @description('Create firewall rule before the virtual network has vnet service endpoint enabled.')
  ignoreMissingVnetServiceEndpoint: bool
  @description('The ARM resource id of the virtual network subnet.')
  virtualNetworkSubnetId: string
}

param virtualNetworkRules virtualNetworkRuleType[] = []

resource mysqlServerVirtualNetworkRules 'Microsoft.DBforMySQL/servers/virtualNetworkRules@2017-12-01' = [for virtualNetworkRule in virtualNetworkRules: {
  name: virtualNetworkRule.name
  properties: {
    ignoreMissingVnetServiceEndpoint: virtualNetworkRule.ignoreMissingVnetServiceEndpoint
    virtualNetworkSubnetId: virtualNetworkRule.virtualNetworkSubnetId       // FALSE POSITIVE
  }
}]

With untyped arrays/objects, doesn't repro (likely we're just giving up):

// DOES NOT REPRO
param virtualNetworkRules_SimpleArray array = []

resource mysqlServerVirtualNetworkRules2 'Microsoft.DBforMySQL/servers/virtualNetworkRules@2017-12-01' = [for virtualNetworkRule in virtualNetworkRules_SimpleArray: {
  name: virtualNetworkRule.name
  properties: {
    ignoreMissingVnetServiceEndpoint: virtualNetworkRule.ignoreMissingVnetServiceEndpoint
    virtualNetworkSubnetId: virtualNetworkRule.virtualNetworkSubnetId
  }
}]

param virtualNetworkRule_SimpleObject object

resource mysqlServerVirtualNetworkRules3 'Microsoft.DBforMySQL/servers/virtualNetworkRules@2017-12-01' = {
  name: virtualNetworkRule_SimpleObject.name
  properties: {
    ignoreMissingVnetServiceEndpoint: virtualNetworkRule_SimpleObject.ignoreMissingVnetServiceEndpoint
    virtualNetworkSubnetId: virtualNetworkRule_SimpleObject.virtualNetworkSubnetId
  }
}
tehho commented 3 weeks ago

Suggestion to introduce a new variable type called resouceId that is typed as a resouceId.

Ex:

type subnet = {
  name: string
  nsgId: resouceId
}

This would validate nsgId to be compliant as a resouceId