-
Notifications
You must be signed in to change notification settings - Fork 760
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
Ability to iterate over object keys #1427
Comments
@alex-frankel has this been triaged? Can it be bound to a particular release? |
Related to #1853 |
@stan-sz - can you expand on your use case for this one? |
Our region configuration files are stored as dictionaries ( |
@stan-sz - Can you double-click on that a bit? e.g. what's actually in the properties body and how you would iterate over it in bicep? Sounds like you're storing something as a dictionary when the platform models it as an array? |
The config can be represented as: <region name>:
azureResources:
storages:
storage01:
name: ...
sku: ...
...
storage02:
name: ...
sku: ...
...
containerRegistries:
acr01:
name: ...
sku: ...
...
acr02:
name: ...
sku: ...
... We are currently transforming these dicts into arrays and pass them to Bicep. The point of this issue is if we could just pass |
Understood - though that would also work as an array right? It sounds like you just have a different data model of a resources array. I'm trying to gauge whether this is preference (which is fine if it is) or if there's some broader scenario that need more thought overall... |
@stan-sz - I think the question we have is why is the input data shaped the way that it is? What system is it coming from that you are working with a dictionary and need to do the transform in the first place? |
We use yaml template rendering engine that allows us to cross-link values in the file using the {{-notation. Having the data stored as dictionaries allows to reference some values from other resources. E.g.:
We'd like to transfer that relationship information to Bicep, but our yaml dictionaries are large and distributed across several git repos, so a conversion to array representation is out of scope. We do, though prepare the data as arrays in the ARM parameters files, but the point of this issue is to avoid exactly that. Given that the |
We had a discussion on this, and closed on the following:
So for example, the following two are equivalent: var result = items({
key1: 'val1'
key2: 'val2'
}) var result = [
{
key: 'key1'
value: 'val1'
}
{
key: 'key2'
value: 'val2'
}
] Some example usages: var myObj = {
key1: 'val1'
key2: 'val2'
}
// get the number of elements
var itemCount = length(items(myObj))
// get the keys
var keys = [for item in items(myObj): item.key]
// get the values
var values = [for item in items(myObj): item.value]
// using keys & values in a resource deployment
resource myRgs 'Microsoft.Resources/resourceGroups@2021-04-01' = [for item in items(myObj): {
name: item.key
location: 'West US'
tags: {
value: item.value
}
}] |
I've implemented the above in the deployments engine, so it should be rolled out to production environments within the next couple of weeks. I'll update this thread when done, and we can then expose the function in Bicep. |
I'm happy to hear about the progress and eagerly waiting for the news. Thanks a lot! |
nice. |
Btw, the array returned from the |
The ARM Deployment engine code unfortunately doesn't have any guarantees about preserving order, so we felt the safest option would be to order consistently (alphabetically), rather than have people take a dependency on a potentially false assumption about ordering. |
Hey @anthony-c-martin, I can find this new |
@slavizh yeah, it's documented here: https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-array#items |
Run |
@bmoore-msft here's what I've got "variables": {
"copy": [
{
"name": "modifiedListOfEntities",
"count": "[length(items(variables('entities')))]",
"input": {
"key": "[items(variables('entities'))[copyIndex('modifiedListOfEntities')].key]",
"fullName": "[items(variables('entities'))[copyIndex('modifiedListOfEntities')].value.displayName]",
"itemEnabled": "[items(variables('entities'))[copyIndex('modifiedListOfEntities')].value.enabled]"
}
}
],
"entities": {
"item002": {
"enabled": false,
"displayName": "Example item 2",
"number": 200
},
"item001": {
"enabled": true,
"displayName": "Example item 1",
"number": 300
}
}
} Does it mean that |
Correct. If you see anything in the emitted ARM template from a |
ping @mumian / @stephaniezyen on missing docs. |
@abatishchev - I will add the function to the ARM documentation. |
@mumian I still don't see the function |
@abatishchev - sorry, I will work on it next Monday. |
@abatishchev - the items() function has been added to the article. |
@mumian awesome, thanks! |
Excude me, but this
|
Yes. The |
This is pretty good but I wish you could pass in the key name like |
@RiverHeart consider opening a new issue and reference this one for visibility and triage. |
Is your feature request related to a problem? Please describe.
I need to pass an object of objects as a parameter and iterate over keys and values to create resources (yes, blocked on #469). Example (modified from ARM docs):
Describe the solution you'd like
The last two lines of the example above demonstrate the ability to get the sub object through name index or as a named property (same for ARM JSON). The
length
function is key-aware as it properly returns4
as the number of items at the top level ofobjectToTest
(third line from the bottom), so dictionary awareness is already partially available. Two ideas come to my mind:copyIndex()
; a syntax to retrieve the current key is also needed[{key1: value1}, ..., {keyN: valueN}]
for the current level in the objectThe text was updated successfully, but these errors were encountered: