azureazure-resource-managerazure-bicepazure-container-registry

Referencing an existing resource which is present in a bicep module


I am new to bicep so I am might be missing something simple here. I have a container registry resource in subscription 'sub1' and resource group 'rg1'. I created a bicep module which looks like below:

@description('Name of the registry.')
param regName string

targetScope = 'subscription'

resource myreg 'Microsoft.ContainerRegistry/registries@2023-01-01' existing = {
  name: regName
  scope: resourceGroup('reg1')
}

output acrResource resource = myreg (NOTE: this is asking me to enable experimental features...which I want to avoid)
output acrId string = myreg.id
output acrName string = myreg.name

I am using this bicep template like below:

module myreg 'myreg.bicep'= {
  name: 'myreg'
  params: {
    regName: 'foo'
  }
  scope: subscription('sub1')
}


resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' {
  name: 'guid-here'
  properties: {
    roleDefinitionId: acrPullRoleDefinitionId
    principalId: 'principa-id-here'
  }
  scope: myreg.outputs.acrResource (this one does not work as I need to enable experimental feature to make the module file error go away)
}

Questions: How is an existing resource from different sub and resource group referenced in general? I could not find examples online too. This should be straight forward but I am stuck here. Any ideas on how I can get unblocked?

Thanks for your help.


Solution

  • You can reference a resource from a different sub/rg like that (see documentation)

    resource myreg 'Microsoft.ContainerRegistry/registries@2023-01-01' existing = {
      name: regName
      scope: resourceGroup('sub1', 'reg1')
    }
    

    For role assignment, because the scope is the container registry, your module needs to be scoped to this specific resource.

    container-registry-role-assignment.bicep:

    param containerRegistryName string
    param principalId string
    param roleId string
    
    // Get a reference to the existing container registry
    resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-11-01-preview' existing = {
      name: containerRegistryName
    }
    
    // Create the role assignment
    resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
      name: guid(containerRegistry.id, roleId, principalId)
      scope: containerRegistry
      properties: {
        roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleId)
        principalId: principalId
      }
    }
    

    Then from the parent module, you can invoke it like that:

    @description('Name of the registry.')
    param regName string
    
    targetScope = 'subscription'
    
    module containerRegistryRbac 'container-registry-role-assignment.bicep' = {
      scope: resourceGroup('sub1', 'reg1') // scope of the sub-deployment
      name: 'name-of-the-deployment'
      params: {
        containerRegistryName: regName
        principalId: 'principa-id-here'
        roleId: '7f951dda-4ed3-4680-a7ca-43fe172d538d' // AcrPull
      }
    }