bicep
bicep copied to clipboard
Allow targeting multiple scopes in a single file with `targetScope`
Implementation for the syntax discussed e.g.
targetScope = [
'tenant'
'subscription'
]
Can plan to use the symbolic name when that is implemented for ARM Template JSON
@alex-frankel do we have "soon" plans of doing this? How might this interface with the right click deploy command?
Not soon, but I still feel we should do it. Right click deploy would need to somehow allow you to choose which scope "type" you want to use prior to loading the list of the list of those scopes.
I would like to be able to parameterize this as well. i.e. pass in the scope to a template
@jongio how would you use that (parameterization)?
We have a scenario where we want to allow the user to deploy to either a sub or to an existing rg. As some users will have access to sub deployments and others to rgs level and we won't know which level until they deploy.
got it - wouldn't the proposal in the OP allow for that though? e.g.
targetScope = [
'subscription'
'resourceGroup'
]
The file can then be used at either scope...
Gotcha, I didn't realize that we're proposing that when the scope is specified then the scope would be adjusted. Does that mean that the calling code needs to either call sub deployment or rg deployment commands?
if so, It would be nice if we had one CLI command that could work with any scope.
targetScope
is really just for tooling to go grab proper context when validating the template...
if so, It would be nice if we had one CLI command that could work with any scope.
And I really like this... we've talked about it in the past and it's tricky due to parametersets changing... TBH I don't recall too much more than that but certainly interested in feedback as to whether a single deployment cmd resonates with folks...
It does with me as I now need to have a conditional and some sort of user interaction for them to choose which one. But it's not a P0.
@jongio curious what your thoughts are on my ramblings under https://github.com/Azure/bicep/issues/399#issuecomment-936054550 - specifically the "Setting other deployment properties" section.
adjacent scenario for different scopes, though this is on the resource itself....
I want a module for a roleAssignment. A module is needed because the name for a roleAssignment needs to be unqiue based on principalId, roleDef and scope of the assignment. When the principalId is from an MSI in the same deployment, a runtime function is needed to retrieve it. The runtime function cannot be used in the name property unless that resource is nested in a module. When I go through a dev/test cycle with an MSI, everytime the MSI is created a new principalId is used... but in a template, to avoid nesting, the roleAssignment name uses the resourceId of the MSI. Since the roleAssignment is not cleaned up, you can only deploy said template once.
In JSON you can do this because the scope property need not be known until deploy time. In bicep this needs to be known at compile time.
Also, the scope property in bicep is strongly typed (cannot be a string), IOW must be a resource. The type of a resource must be known at compile time.
In JSON I would do:
{
"scope": "[if(equals(parameters('scope'), resourceGroup().id), json('null'), variables('roleScope'))]",
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2022-01-01-preview",
"name": "[variables('roleAssignmentName')]",
"properties": {
"roleDefinitionId": "[variables('roleDefinitionId')]",
"principalId": "[parameters('principalId')]",
"principalType": "[parameters('principalType')]"
}
}
Where variables('roleScope')
is the back half of a resourceId.
via decompile this would be:
resource roleAssignmentName 'Microsoft.Authorization/roleAssignments@2022-01-01-preview' = {
scope: ((scope == resourceGroup().id) ? json('null') : roleScope)
name: roleAssignmentName_var
properties: {
roleDefinitionId: roleDefinitionId
principalId: principalId
principalType: principalType
}
}
Which is not allowed.
Some ideas - allow the scope
to be a string... or allow an existing resource declaration to be dynamic, e.g.
resource storageAccount existing = {
id: resourceId('blah')
}
@bmoore-msft - my understanding is this will be enabled with #2245/#2246
I think one difference may be that in roleAssignment
case, the type is not known at compile time... so in 2245/2246 the type declaration would be parameterized.
My understanding is the resource
parameter type can be generic, so you can have a module like:
param myRes resource // can be any resource type
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
scope: myRes
...
}
Does that cover it?
As long as the type can be specified at deploy time (not compile time) - yes, that would cover it. I didn't see anything that suggested that would be the case though.
Very much like the idea!
Although modules are a great way of structuring your deployments, it would be a great advantage to have all the deployment definitions for all target scopes in a single file. This would greatly improve sharing Bicep code, e.g. in tutorials etc.
/ref #7860
Just like Terraform Plan and Apply on a whole project regardless of the scope resources being provisioned belong to, as long there's authorization for it, I was attempting to have a single bicep orchestration file that would call all the modules that provision those resources in different scopes for my ALZ (RGs, policies, VNETs, KeyVault, etc). With that a single 'what-if' call to validate the entire orchestration plan and later a deploy if all modifications are approved. It would streamline the process, reduce the number of artifacts to manage and increase visibility
Did we start consider about this implementation so far?
There is a lot of duplication for basic tasks like assigning policies or role assignments based on having to provide the single targetScope
.
This is "not as fast as you would like", however it would be ideal to get this in by v1.0.1?
Also, there were some comments about this being enabled with preview feature resourceTypedParamsAndOutputs
that is now available, so perhaps there is some testing around this that I can consider...?!
It appears that we have both of below, so perhaps we can consolidate to track in single issue?
- https://github.com/Azure/bicep/issues/4698
- https://github.com/Azure/bicep/issues/10131
It would be nice if the Module simply inherited the Scope from the parent Module as the default.
Then you only specify targetScope =
when you are changing scope when calling a Module or for any Top Level Module.