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

Module scope recognizing scope function as bicep reference #1195

Closed
miqm opened this issue Dec 19, 2020 · 9 comments
Closed

Module scope recognizing scope function as bicep reference #1195

miqm opened this issue Dec 19, 2020 · 9 comments
Labels
question Further information is requested

Comments

@miqm
Copy link
Collaborator

miqm commented Dec 19, 2020

Bicep version
Bicep CLI version 0.2.217 (1c7a300b9a)

Describe the bug
A clear and concise description of what the bug is vs what you expected to happen
When we use for module (or resource) name managementGroup or resourceGroup or subscription, and then we use module with scope, instead using function it tries to use that resource.

To Reproduce
Steps to reproduce the behavior:

targetScope = 'tenant'

resource resourceGroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'rg1'
  location: 'westeurope'
  properties: {
    
  }
}

module managementGroup 'managementGroup.bicep' = {
  name: 'managementGroup'
  scope: managementGroup('c78eeaf5-617d-4733-a597-08646541a46')
}

module rgModule 'resourceGroup.bicep' = {
  name: 'resourceGroup'
  scope: resourceGroup('c78eeaf5-617d-4733-a597-08646541a462')
}

output:

main.bicep(13,10) : Error BCP079: This expression is referencing its own declaration, which is not allowed.
main.bicep(13,10) : Error BCP113: Unsupported scope for module deployment in a "tenant" target scope. Omit this property to inherit the current scope, or specify a valid scope. Permissible scopes include tenant: tenant(), named management group: managementGroup(<name>), or named subscription: subscription(<subId>).
main.bicep(18,10) : Error BCP059: The name "resourceGroup" is not a function.
main.bicep(18,10) : Error BCP113: Unsupported scope for module deployment in a "tenant" target scope. Omit this property to inherit the current scope, or specify a valid scope. Permissible scopes include tenant: tenant(), named management group: managementGroup(<name>), or named subscription: subscription(<subId>).

Additional context
Add any other context about the problem here.

@ghost ghost added the Needs: Triage 🔍 label Dec 19, 2020
@anthony-c-martin
Copy link
Member

Bicep doesn't block you from declaring symbols with the same name as built-in functions - instead you need to disambiguate using namespaces. I realize now that this is completely undocumented so I've added task #1196 to make sure we document it.

Here's how you would need to update your example to use namespaces:

targetScope = 'tenant'

resource resourceGroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'rg1'
  location: 'westeurope'
  properties: {
    
  }
}

module managementGroup 'managementGroup.bicep' = {
  name: 'managementGroup'
  scope: az.managementGroup('c78eeaf5-617d-4733-a597-08646541a46')
}

module rgModule 'resourceGroup.bicep' = {
  name: 'resourceGroup'
  scope: az.resourceGroup('c78eeaf5-617d-4733-a597-08646541a462')
}

@miqm
Copy link
Collaborator Author

miqm commented Dec 20, 2020

Thanks. Besides updating docs, perhaps we could include this hint in error messages?

@miqm
Copy link
Collaborator Author

miqm commented Dec 20, 2020

@anthony-c-martin I give it a try and it does not work for managementGroup, as there is no managementGroup function in az namespace.

Also, it would be nice if we could reference resource group directly, instead needing go through function:

from this:

resource resourceGroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'common-rg'
  location: 'westeurope'
}
module resourceGroupModule 'resourceGroup.bicep' = {
  name: 'RG Module'
  scope: az.resourceGroup(resourceGroup.name)
}

to this:

resource resourceGroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'common-rg'
  location: 'westeurope'
}
module resourceGroupModule 'resourceGroup.bicep' = {
  name: 'RG Module'
  scope: resourceGroup
}

@miqm
Copy link
Collaborator Author

miqm commented Dec 20, 2020

On the second thought - why do we even need to specify scope type for module resource? We provide targetScope in the module we're including and if we give wrong scope in calling module - we get BCP036.
So when building output ARM JSON, we could just take module type from module itself instead from the function name in the scope property and use scope to provide management or resource group name or subscription guid or reference to created resource (management or resource group) .

@alex-frankel
Copy link
Collaborator

There's a few different issues going on here:

  1. Resource groups cannot be created in a tenant scope deployment. So that should result in an invalid deployment. This should throw an error in bicep, which will be fixed as part of Show the correct set of resource types in completions / validation when a scope has been selected #774

  2. az.managementGroup worked for me. What version of bicep are you using? This is the code I was using:

main.bicep

targetScope = 'tenant'

module managementGroup './module.bicep' = {
  name: 'test'
  scope: az.managementGroup('my-mg')
}

module.bicep

targetScope = 'managementGroup'
  1. for this statement:

Also, it would be nice if we could reference resource group directly, instead needing go through function

This will be fixed by #822

  1. For BCP059 and BCP113, these need to be fixed. We recently relaxed restrictions for cross-scope deployment. At one point we did not allow going from tenant -> rg, but now we do (@anthony-c-martin, I just tested in my personal tenant). I will open a separate issue for this.

  2. I'm not sure what this last comment means:

why do we even need to specify scope type for module resource? We provide targetScope in the module we're including and if we give wrong scope in calling module - we get BCP036.
So when building output ARM JSON, we could just take module type from module itself instead from the function name in the scope property and use scope to provide management or resource group name or subscription guid or reference to created resource (management or resource group) .

The logic is that if scope is not specified for the module, we try to use the scope of the parent bicep file. If that scope is invalid, we throw an error and require you to specify scope manually.

@miqm
Copy link
Collaborator Author

miqm commented Dec 21, 2020

Ugh, I double checked now and az.managementGroup does exist and work. I must have some typo before 🤦🏻‍♂️

To sum up:

  1. Tracked in Show the correct set of resource types in completions / validation when a scope has been selected #774
  2. my mistake, it works
  3. Tracked in ResourceGroup resource creation should generate a scope for deploying resources #822
  4. Tracked in tenant -> rg and mg -> rg deployments should be allowed #1208 - BTW - I can take this one for implementation

As for the 5th: let's consider the case above with deployment from tenant to management group - why we need to explicitly specify, that module managementGroup target scope is a management group named 'my-mg'? We already know, that target is a management group since we specified that in the module (targetScope = 'managementGroup') so now we only would need to specify it's name - there's no need to specify again that we want to target management group - providing name should be enough.

If we do not provide scope - we will use default - and that is ok - included modules will target current management group, subscription, tenant, rg - and we will be able to use only modules, that has this same target scope as the module we include them from.

Specifying only name will fit nicely in #822 - you can either use bicep reference or provide a text value which will be a name/guid for the thing module is expecting (subscription/mg/rg).

Edge case would be tenant deployments called from non-tenant scope modules, as this will break the 'when scope not present - use scope from calling module' rule.

@alex-frankel
Copy link
Collaborator

Oh, I see now. So instead of having to specify managementGroup('my-mg'), you'd like to just say my-mg since the module knows that it has to be a management group. #822 will let you avoid the function as you note. Basically, as long as you have a symbolic reference to the relevant scope, you should be able to use that identifier directly. You should be able to use this in conjunction with #258 to get a scope reference beyond the specific functions. I don't think we will be able to get rid of the functions themselves when you just have the name of the scope.

Good if I close this one, since it looks we are tracking everything in other issues?

@miqm
Copy link
Collaborator Author

miqm commented Dec 21, 2020

I don't think we will be able to get rid of the functions themselves when you just have the name of the scope.

Are you sure? I don't see any case, when we have different values of targetScope in module and scope function in module call.

And if we do not provide any name or reference, we assume that we target current resourceGroup, subscription, tenant, depending on the value defined in the module itself. For management groups, when we deploy not from a managment group scope, we anyway need to provide mg name.

I think we can close this issue and eventually track relaxing the necessity of providing function in module scope in a new issue.

@alex-frankel
Copy link
Collaborator

Definitely not sure :) I will let @anthony-c-martin provide more details on the why on the new issue

@ghost ghost locked as resolved and limited conversation to collaborators May 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants