Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambdas do not support resource references #14106

Open
anthony-c-martin opened this issue May 17, 2024 · 4 comments
Open

Lambdas do not support resource references #14106

anthony-c-martin opened this issue May 17, 2024 · 4 comments
Assignees
Milestone

Comments

@anthony-c-martin
Copy link
Member

anthony-c-martin commented May 17, 2024

@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 #13658 (comment)

@anthony-c-martin
Copy link
Member Author

anthony-c-martin commented May 17, 2024

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.

@slavizh
Copy link
Contributor

slavizh commented May 18, 2024

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.

@cedricbraekevelt
Copy link

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

@slavizh
Copy link
Contributor

slavizh commented Oct 8, 2024

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

No branches or pull requests

5 participants