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

Unable to access resource group location through resource group scope as variable #947

Open
dgard1981 opened this issue Nov 18, 2020 · 7 comments
Labels
intermediate language Related to the intermediate language
Projects

Comments

@dgard1981
Copy link

Bicep version

Bicep CLI version 0.2.14 (0a0f974)

Describe the bug
When setting targetScope = 'subscription' I am unable to access the location of a resource group.

The type "resourceGroup" does not contain property "location".bicep(BCP052)

To Reproduce

targetScope = 'subscription'

resource transactionService_resourcegroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'bicep-test'
  location: 'UK South'
}

var resourceGroupScope = resourceGroup('transactionService_resourcegroup')
var isPrimaryRegion = resourceGroupScope.location == 'uksouth'

Additional context

Before the use of targetScope = 'subscription' I was able to use resourceGroup().location to access the resource group location. I understand why that wouldn't work when the Bicep file is scoped to a subscription, but I was expecting to be able to use the resource group scope variable that I set (resourceGroupScope) to access the location.

@ghost ghost added the Needs: Triage 🔍 label Nov 18, 2020
@alex-frankel
Copy link
Collaborator

I think the issue is that the resourceGroup() function with arguments is kind of like a "fake" function that only exists in bicep at the moment. There is no equivalent for it in ARM templates. It only works to set scopes in bicep. The right thing to do is proliferate this function to templates (the IL), at which point this should work.

Great find!

@alex-frankel alex-frankel added intermediate language Related to the intermediate language and removed Needs: Triage 🔍 labels Nov 18, 2020
@alex-frankel alex-frankel added this to the v0.3 milestone Nov 19, 2020
@miqm
Copy link
Collaborator

miqm commented Dec 21, 2020

I don't think this is the case. resourceGroup function exists in ARM, but it can be used in resource group deployments only, see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource?tabs=json#resourcegroup

Banning (throw and error) using this function in modules that don't target resource group is covered in #808 and potentially connects with #774

Although for this case, we can simply use:

targetScope = 'subscription'

resource transactionService_resourcegroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'bicep-test'
  location: 'UK South'
}

var isPrimaryRegion = transactionService_resourcegroup.location == 'uksouth'

@dgard1981
Copy link
Author

@miqm - That absolutely wont work for my use case.

We deploy the same ARM template to multiple regions, but some resources (Cosmos DB for example) only need to be deployed to our designated primary region, which we check through a condition in the ARM template (and hopefully now through Bicep as it looks like conditions have been implemented). So we can't hardcode the location in each resource - we have to use the [resourceGroup().location].

We can continue to do this in Bicep without setting the scope to subscription. I was investigating the targetScope option because it would be nice to be able to create the RG that is being updated if it doesn't already exist, but no bit deal if we can't.

@miqm
Copy link
Collaborator

miqm commented Dec 21, 2020

You will not be able to create cosmosdb in module that targets subscription - this compiles to subscription deployment where only subset of resources are valid.

When you do deployment to the resource group (module with targetScope = 'resourceGroup'), you can safely use resourceGroup().location. resourceGroup() is only forbidden for subscription/managementGroup/tenant deployments.

You can have a subscription module to create resourceGroups and then include resource group modules:
main.bicep

targetScope = 'subscription'

resource transactionService_resourcegroup 'Microsoft.Resources/resourceGroups@2020-06-01' = {
  name: 'bicep-test'
  location: 'UK South'
}

module transactionService 'group.bicep' = {
  name: 'transactionService'
  scope: resourceGroup(transactionService_resourcegroup.name)  
}

group.bicep

targetScope = 'resourceGroup'

var isPrimaryRegion = resourceGroup().location == 'uksouth'

Plus:
transactionService_resourcegroup.location - this is not hardcoding, it compiles to reference function and takes value from actual existing resource group

@dgard1981
Copy link
Author

@miqm - Apologies, I read your previous reply as you suggesting I hardcode the location of resources, whereas your example was actually showing the resource group.

What you are suggesting would probably work in most cases, however there is one (admittedly edge) case that I've come across where I still need to use resourceGroup.location() in main.bicep.

I assign RBAC roles to a Cosmos DB account to allow Function App to do certain things. Because the Cosmos DB account is only in our designated primary region (UK South), the deployments for the module in every region (UK South, UK West, North Europe, etc.) are run in the same resource group (and potentially at the same time), so need unique names.

Currently I append the resource group location, but using the example below would result in the reference() function being used in the name parameter, which isn't allowed.

Bicep
format('transaction-service--rbac--{0}--{1}', functionApps[1].mode, transactionService_resourcegroup.location)

ARM template
[format('transaction-service--rbac--{0}--{1}', parameters('functionApps')[0].mode, reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupParam').name), '2020-06-01', 'full').location)]

In short, this is a nice to have and would probably make our lives a little easier, but it's not a deal breaker.

@miqm
Copy link
Collaborator

miqm commented Dec 21, 2020

So basically your problem is not related to bicep. Using 'runtime' values in resource names is forbidden in ARM, and warning on this it's covered by #360.

But still - in subscription deployment you cannot use resourceGroup() function - even in ARM - this is reserved for resource group deployments only:

The resourceGroup() function can't be used in a template that is deployed at the subscription level. It can only be used in templates that are deployed to a resource group. You can use the resourceGroup() function in a linked or nested template (with inner scope) that targets a resource group, even when the parent template is deployed to the subscription. In that scenario, the linked or nested template is deployed at the resource group level.

@alex-frankel
Copy link
Collaborator

Adding internal tracking item (won't be visible to non-msft internal): https://msazure.visualstudio.com/One/_workitems/edit/8866613

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
intermediate language Related to the intermediate language
Projects
Development

No branches or pull requests

4 participants