bicep icon indicating copy to clipboard operation
bicep copied to clipboard

Lambdas do not support resource references

Open anthony-c-martin opened this issue 1 year ago • 4 comments

@anthony-c-martin I could not find the documentation for the new function features published yet but there are examples here in this PR. However for one of the main reasons to have index for lambda functions was to be able to access resource arrays and I have found out that this is not possible. Any idea why this was not done? It seems only half of the job was done.

properties: {
      actionGroups: map(eventSubscription.destination.actionGroups, (actionGroup, i) => actionGroups[i].id)
    }

shows error:


Using lambda variables inside resource or module array access is not currently supported. Found the following lambda variable(s) being accessed: "i".bicep(BCP247)

Originally posted by @slavizh in https://github.com/Azure/bicep/issues/13658#issuecomment-2117258414

anthony-c-martin avatar May 17 '24 16:05 anthony-c-martin

The challenge originally was that the deployment engine requires the reference() function parameters to be evaluable at the start of the deployment, in order to accurately build the deployment graph.

Now that we have symbolic names, it may be possible to revisit and relax this requirement, because there is no ambiguity about what a reference function call refers to, and Bicep will also emit the correct dependsOn statement.

For example:

param account {
  name: string
}

resource loop 'Microsoft.Storage/storageAccounts@2022-09-01' = [for i in range(0, 10): {
  name: 'loop${i}'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {}
}]

resource sa 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: account.name
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    // would result in the following dependsOn: "[format('loop[{0}]', 0)]"
    test: loop[0].properties.test
    // could result in the following dependsOn: "loop"
    test2: map(loop, x => x.properties.test)
  }
}

As long as Bicep builds the correct dependency graph, all good. If it doesn't, then things will fail in a very cryptic way. I do think this is something we could enforce during codegen however, so the cryptic failures would be limited to people authoring lambdas in ARM JSON templates.

There is a similar problem with list function calls - this is more tricky, because there is no symbolic reference to a "list". I don't think we'd be able to remove the restriction here.

anthony-c-martin avatar May 17 '24 16:05 anthony-c-martin

I think at least this should be allowed for properties like .id and .name as they do not require reference() they only need resourceId(). Symbolic naming seems good only when it relates to using reference() in the past but it somehow creates more pain when it is used only for the .id. At least that is my impression.

slavizh avatar May 18 '24 11:05 slavizh

This would make us less dependent on foreach for referencing outputs. Would be a great improvement if possible!

cedricbraekevelt avatar May 22 '24 08:05 cedricbraekevelt

@anthony-c-martin any chance this gets fixed soon? It would open quite the cases with being able to loop over Key Vault secrets and convert the array to object as currently you have secure decorator only on objects and strings. Quite often we have resources that have array properties and within array you need to put a secret from key vault. In such cases you either need to ask the secret to be passed in plain text which is not good or ask for one secret for which the value is stored as json object so you can get the secret as string, convert it to json and use it within the array.

slavizh avatar Oct 08 '24 07:10 slavizh

@anthony-c-martin checking again?

slavizh avatar Nov 07 '24 08:11 slavizh