Allow limited recursive module calls (with use-case)
- Dominant language
- Bicep
- Stars
- 3.6k
- Forks
- 830
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 79
Description
**Is your feature request related to a problem? Please describe.**
I think it would be beneficial to be able to allow a restricted number of recursive module calls in order to allow some interesting use-cases. Currently you are not allowed to have a module who creates another module of itself. I'll describe what I was trying to do to illustrate what I want to achieve:
In order to set up a complex structure of management groups I wanted to define the hierarchy in a YAML-file (note this is just a small sample example hierarchy, in reality it could be much larger):
```yaml
root:
id: tenant-root-group
name: Tenant Root Group
children:
- id: landing-zone
name: Landing Zone Root
children:
- id: production
name: Production
children:
- id: swedencentral
name: Sweden Central
- id: westeurope
name: West Europe
- id: staging
name: Staging
- id: development
name: Development
- id: connectivity
name: Connectivity
```
I would then have a `main.bicep` file:
```bicep
targetScope = 'tenant'
var data = loadYamlContent('data.yaml')
resource root 'Microsoft.Management/managementGroups@2021-04-01' existing = {
name: data.root.id
}
module children './recursive.bicep' = [for (child, index) in data.root.children: {
name: 'recursive-call-${index}'
params: {
mg: child
parentId: root.id
}
}]
```
And the `recursive.bicep` file:
```bicep
targetScope = 'tenant'
param mg object
param parentId string
resource mgResource 'Microsoft.Management/managementGroups@2023-04-01' = {
name: mg.id
properties: {
displayName: mg.name
details: {
parent: {
id: parentId
}
}
}
}
module childMgs './recursive.bicep' = [for (child, index) in mg.children: {
name: 'recursive-call-${index}'
params: {
mg: child
parentId: mgResource.id
}
}]
```
I am aware of the issue with module names, they would need to be constructed in a way to not make them collide. Let's ignore that for now!
**Describe the solution you'd like**
To continue the example above, I would like to be able to add a decorator to the initial module declaration to say that I allow recursive calls to a level of X calls. Example, in `main.bicep`:
```bicep
@recursive(5)
module children './recursive.bicep' = [for (child, index) in data.root.children: {
name: 'recursive-call-${index}'
params: {
mg: child
parentId: root.id
}
}]
```
The `recursive(5)` decorator tells Bicep that I am aware I am making a recursive call, but please restrict it to `5` levels.
Perhaps there should be a global max for the amount of recursive calls I can make, but I guess this depends on the size of the template (i.e. to not hit the max size of an ARM-template)
Contributor guide
Research direction
Start with the main.bicep and recursive.bicep examples in the issue to understand the proposed bounded recursive module-call scenario. Then locate the repository's handling of module declarations and recursion validation; done should include accepting an explicitly limited recursion depth while still rejecting unbounded or over-limit recursive calls. No test file or implementation entry point is named in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure
- Domain
- cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100