Azure / Azure/bicep

Allow limited recursive module calls (with use-case)

Open
#12,211 0 comments 0 reactions 0 assignees View on GitHub
enhancement Needs: Upvote
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.