Difficulty Creating Container App Job with bicep: Accessing Image from Registry with Managed Identity

Deepankur Rana 20 Reputation points
2024-04-05T09:18:32.8933333+00:00

Our objective is to deploy a container app job using Bicep. While we have successfully created all other resources, we are encountering difficulties in provisioning the container app job. The job is designed to fetch image details from a container registry using managed identity. However, each deployment attempt results in a failure with the following error message:

  "code": "InvalidParameterValueInContainerTemplate",
        "message": "The following field(s) are either invalid or missing. Field 'template.containers.acruksdataacadev.image' is invalid with details: 'Invalid value: \"acruksdataacadev.azurecr.io/hello-world:latest\": GET https:?scope=repository%3Ahello-world%3Apull&service=acruksdataacadev.azurecr.io: UNAUTHORIZED: authentication required, visit https://aka.ms/acr/authorization for more information.';."
      }
Azure Container Registry
Azure Container Registry
An Azure service that provides a registry of Docker and Open Container Initiative images.
508 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Deepanshukatara-6769 16,565 Reputation points Moderator
    2024-04-05T10:44:58.1533333+00:00

    Hi Deepankur, Welcome to MS Q&A

    Can you please verify that the managed identity assigned to your container app job has the necessary permissions to pull images from the Azure Container Registry. The managed identity should have the "AcrPull" role assignment on the ACR

    Please check this img and doc for more details--> https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli

    User's image

    Kindly accept answer , if it help and works, Thanks!


  2. Deepanshukatara-6769 16,565 Reputation points Moderator
    2024-04-08T06:13:06.1333333+00:00

    Ok ,If you've confirmed that MI used for authentication has both ACR pull and reader access over the Azure Container Registry (ACR), and you're still encountering authentication errors, there are a few additional steps you can take to troubleshoot the issue:

    1. Verify Authentication Method: Ensure that you're using the correct authentication method supported by Azure Container Registry. Azure supports several authentication methods, including Azure Active Directory (AAD) authentication, service principals, and admin account credentials. Make sure you're using the appropriate method and that it's configured correctly.
    2. Review Network Configuration: Check if there are any network configurations (such as firewalls or network security groups) that might be blocking the authentication request to the Azure Container Registry. Ensure that the necessary network configurations are in place to allow traffic to and from the registry.
    3. Inspect Error Logs: Review any error logs or diagnostic information provided by Azure Container Registry or the container runtime environment. These logs may provide more detailed information about the authentication failure and can help pinpoint the underlying issue.

    Kindly share the error logs to investigate further, Thanks!

    0 comments No comments

  3. Anveshreddy Nimmala 3,550 Reputation points Microsoft External Staff Moderator
    2024-04-08T06:32:21.1866667+00:00

    Hello Deepankur Rana,

    Use a user-assigned identity:

    Create a user assigned identity with required permissions and assign it to the container -app.

    # container-registry-role-assignment.bicep
    param registryName string
    param roleId string
    param principalId string
    // Get a reference to the existing registry
    resource registry 'Microsoft.ContainerRegistry/registries@2021-06-01-preview' existing = {
      name: registryName
    }
    // Create role assignment
    resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
      name: guid(registry.id, roleId, principalId)
      scope: registry
      properties: {
        roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleId)
        principalId: principalId
        principalType: 'ServicePrincipal'
      }
    }
    

    Then from your main:

    param name string
    param identityName string
    param environmentName string
    param containerImage string
    param location string = resourceGroup().location
    param containerRegistrySubscriptionId string = subscription().subscriptionId
    param containerRegistryResourceGroupName string = resourceGroup().name
    param containerRegistryName string
    // Create identtiy
    resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview'  = {
      name: identityName
      location: location
    }
    // Assign AcrPull permission
    module roleAssignment 'container-registry-role-assignment.bicep' = {
      name: 'container-registry-role-assignment'
      scope: resourceGroup(containerRegistrySubscriptionId, containerRegistryResourceGroupName)
      params: {
        roleId: '7f951dda-4ed3-4680-a7ca-43fe172d538d' // AcrPull
        principalId: identity.properties.principalId
        registryName: containerRegistryName
      }
    }
    // Get a reference to the container app environment
    resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-03-01' existing = {
      name: environmentName
    }
    // create the container app
    resource containerapp 'Microsoft.App/containerApps@2022-03-01' = {
      dependsOn:[
        roleAssignment
      ]
      name: name
      ...
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '${identity.id}': {}
        }
      }
      properties: {
        managedEnvironmentId: managedEnvironment.id
        configuration: {
          ...
          registries: [
            {
              server: '${containerRegistryName}.azurecr.io'
              identity: identity.id
            }
          ]
        }
        template: {
          ...
          containers: [
            {
              name: name
              image: '${containerRegistryName}.azurecr.io/${containerImage}'
              ...
            }
          ]
        }
      }
    

    hope this helps you,If an answer has been helpful, please consider accepting the answer to help increase visibility of this question for other members of the Microsoft Q&A community. If not, please let us know what is still needed in the comments so the question can be answered. Thank you for helping to improve Microsoft Q&A!

    c947b109-2f3b-4468-8639-cb6c3bea645c


  4. Alexis Lessard 0 Reputation points
    2025-05-09T17:54:49.1833333+00:00

    We've had an issue like this as well, because we want to use the system-assigned managed identity. Here's the issue:

    Our bicep module creates a container app job, and then, creates a role assignement to the registry using an output from the container app job.

    However, when creating a container app job, the deployment won't complete until the image pull has been tested. Since the role assignement depends on the container app job's creation, and thus does not exist yet, it is impossible for the deployment to finish. The system-assigned identity does not have permissions to pull yet, and the permissions won't be assigned until the container app can pull an image.

    Workaround:

    We've implemented a trigger that checks if an image is passed to our module. If it's not, then we use the default hello-world image, which is public on docker hub. The deployment will complete and the role assignement will be created. Then, we redeploy, passing the image we need to the job. The pull will then succeed.

    The following code has been abreviated to highlight the relevant configuration:

    var defaultContainerAppJobImage = 'hello-world'
    resource containerAppJobsResources 'Microsoft.App/jobs@2024-03-01' =
    {
        name: jobName
        location: resourceGroup().location
        identity: {
          type: 'SystemAssigned'
        }
        properties: {
          configuration: {
            registries: containerAppJobImage == ''
              ? null
              : [
                  {
                    server: containerRegistryServer
                    identity: 'system'
                  }
                ]
          }
          template: {
            containers: [
              {
                image: containerAppJobImage == '' ? defaultContainerAppJobImage : containerAppJobImage
              }
            ]
          }
        }
      }  
    

    Recommendations:

    For a container app job's deployment, testing the pull should be optional to account for this situation. Maybe the deployment could complete with a warning? Or maybe it should be possible to specify that we do not want to test the pull to confirm that the job has been deployed correctly.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.