azureazure-container-registryazure-bicepazure-resource-group

Bicep ParentResourceNotFound for container registry in shared resource group


Via Bicep, I'm trying to setup my Azure infrastructure. Two resource groups: one for shared resources, app service plans and a container registry. The second one for a project specific resources, app services for the applications.

The container registry is linked to the appservice via linuxFxVersion. If I use the containerRegistryName, which comes from shared.bicep, I receive the error ParentResourceNotFound with the message Can not perform requested operation on nested resource. Parent resource 'crdevopstest' not found.

When I use acrResource.name as shown in the code below, the container registry is in the same resource group as the app service, it works as expected.

main.bicep

resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: 'rg-${projectName}-${env}'
  location: resourceLocation
}

resource rgShared 'Microsoft.Resources/resourceGroups@2021-04-01' = if (env != 'dev') {
  name: 'rg-${subscription}-${env}'
  location: resourceLocation
}

module appServiceShared 'shared.bicep' = if (env != 'dev') {
  name:'appShared'
  scope: rgShared
  params: {
    subscription: subscription
    env: env
    appServicePlanSku: appServicePlanSku
    crSku: crSku
  }
}

module appService 'app.bicep' = {
  name: 'app${projectName}'
  scope: rg
  params: {
    applicationName: projectName
    env: env
    appServicePlanSharedId: appServiceShared.outputs.appServicePlanSharedLinuxId
    //appServicePlanSharedName: appServiceShared.outputs.appServicePlanSharedLinuxName
    containerRegistryName: appServiceShared.outputs.containerRegistryName
  }
}

shared.bicep

resource appServicePlanSharedWindows 'Microsoft.Web/serverfarms@2021-01-15' = {
  name: 'plan-${subscription}-${env}-windows'
  location: location
  sku: {
    name: appServicePlanSku
  }
}

resource appServicePlanSharedLinux 'Microsoft.Web/serverfarms@2021-01-15' = {
  name: 'plan-${subscription}-${env}-${appService}'
  location: location
  sku: {
    name: appServicePlanSku
  }
  kind: appService
  properties: {
    reserved: true
  }
}

resource acrResource 'Microsoft.ContainerRegistry/registries@2021-06-01-preview' = {
  name: 'cr${subscription}'
  location: location
  sku: {
    name: crSku
  }
  properties: {
    adminUserEnabled: true        // TO DO - replace by identity
  }
}

output appServicePlanSharedWindowsId string = appServicePlanSharedWindows.id
output appServicePlanSharedLinuxId string = appServicePlanSharedLinux.id
//output appServicePlanSharedLinuxName string = appServicePlanSharedLinux.name
output containerRegistryName string = acrResource.name

app.bicep

resource acrResource 'Microsoft.ContainerRegistry/registries@2021-06-01-preview' = {
  name: 'crdevopsnick'
  location: location
  sku: {
    name: 'Basic'
  }
  properties: {
    adminUserEnabled: true        // TO DO - replace by identity
  }
}

resource appServiceApi 'Microsoft.Web/sites@2021-03-01' = {
  name: 'ase-${applicationName}-api-dotnet-${env}'
  location: location
  properties: {
    serverFarmId: appServicePlanSharedId
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'DOCKER|${acrResource.name}.azurecr.io/${applicationName}service:latest'
      appSettings: [
        {
          name: 'DOCKER_REGISTRY_SERVER_URL'
          value: 'https://mcr.microsoft.com'
        } 
        {
          name: 'DOCKER_REGISTRY_SERVER_USERNAME'
          value: acrResource.name
        } 
        {
          name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
          value: listCredentials(resourceId('Microsoft.ContainerRegistry/registries', acrResource.name), '2021-06-01-preview').passwords[0].value //acrResource.listCredentials().passwords[0].value
        }
        {
          name: 'WEBSITES_PORT'
          value: '7122'
        }
      ]
    }
  }
}

This StackOverflow POST it could be an issue if it is in another resource group.

Does anyone knows if it is possible to use a shared container registry from a separate resource group?


Solution

  • With the use of dependsOn and existing, I was able to deploy the Bicep.

    module appService 'app.bicep' = {
      name: 'app${projectName}'
      scope: rg
      params: {
        applicationName: projectName
        env: env
        sharedRgName: rgShared.name
        containerRegistryName: appServiceShared.outputs.containerRegistryName
      }
      dependsOn: [ appServiceShared ]
    }
    
    resource acrResource 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = {
      name: 'crtdevops'
      scope: resourceGroup(sharedRgName)
    }
    
    resource appServiceApi 'Microsoft.Web/sites@2022-03-01' = {
      name: 'ase-${applicationName}-api-dotnet-${env}'
      location: location
      properties: {
        serverFarmId: sharedPlan.id
        httpsOnly: true
        siteConfig: {
          linuxFxVersion: 'DOCKER|${containerRegistryName}.azurecr.io/${applicationName}service:latest'
          appSettings: [
            {
              name: 'DOCKER_REGISTRY_SERVER_URL'
              value: 'https://mcr.microsoft.com'
            } 
            {
              name: 'DOCKER_REGISTRY_SERVER_USERNAME'
              value: containerRegistryName
            } 
            {
              name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
              value: acrResource.listCredentials().passwords[0].value
            }
            {
              name: 'WEBSITES_PORT'
              value: '7122'
            }
          ]
        }
      }
      dependsOn: [ acrResource ]
    }