Not able to deploy AKS image from ACR from pipeline 2

Diptesh Kumar 331 Reputation points
2025-04-27T06:42:23.2166667+00:00

I am using pipeline 1 as below ( which is building the image and pushing the image to ACR )

Pipeline1:

trigger:
- none

variables:
  imageName: 'aksimage'
  dockerfilePath: 'Dockerfile'
  buildContext: '.'
  acrLoginServer:: 'acrnnn.azurecr.io'
  dockerRegistryServiceConnection: 'April27ACR'

parameters:
- name: testtag
  displayName: 'Tag to Build and Deploy'
  type: string
  default: 'latest'

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and Push Docker Image
  jobs:
  - job: BuildJob
    steps:
    - checkout: self

    - task: Docker@2
      displayName: 'Build and Push Docker Image to ACR'
      inputs:
        containerRegistry: '$(dockerRegistryServiceConnection)' # <- not hardcoded 'scn'
        repository: '$(imageName)'    # just aksimage
        command: 'buildAndPush'
        Dockerfile: '$(dockerfilePath)'
        buildContext: '$(buildContext)'
        tags: |
          ${{ parameters.testtag }}  



    - task: PublishPipelineArtifact@1
      displayName: 'Publish deployment.yaml as Artifact'
      inputs:
        targetPath: '$(Build.SourcesDirectory)'
        artifactName: 'deployment-files'

and below is the deployment file :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aks-agent-deployment
  labels:
    app: aks-agent-deployment
spec:
  replicas: 10
  selector:
    matchLabels:
      app: aks-agent-deployment
  template:
    metadata:
      labels:
        app: aks-agent-deployment
    spec:
      imagePullSecrets:
      - name: acr-secret  # Used to pull from ACR
      containers:
      - name: azp-agent
        image: acrnnn.azurecr.io/aksimage:__IMAGETAG__
        ports:
        - containerPort: 80
        env:
        - name: AZP_URL
          value: "https://dev.azure.com/nextops123/"
        - name: AZP_POOL
          value: "AKSPool"
        - name: AZP_TOKEN
          valueFrom:
            secretKeyRef:
              name: azp-secret
              key: AZP_TOKEN


and below is pipeline2:

resources:
  pipelines:
    - pipeline: pipelineA      # alias you’ll use
      source: AKSAGENT-publish
      project: aus
      trigger:
        branches:
          include:
            - main

stages:
  - stage: UseArtifact
    jobs:
      - job: DownloadAndUse
        steps:
          - download: pipelineA
            artifact: deployment-files   # correct artifact name here!
          - script: |
              echo "Listing EVERYTHING under workspace"
              find $(Pipeline.Workspace)
            displayName: 'Full Tree Listing'

          - script: |
              echo "Here is deployment.yaml"
              cat $(Pipeline.Workspace)/pipelineA/deployment-files/deployment.yaml
            displayName: 'Show deployment.yaml'
          - task: Kubernetes@1
            displayName: 'Deploy to AKS'
            inputs:
              connectionType: 'Kubernetes Service Connection'
              kubernetesServiceEndpoint: 'AKSApril27'
              namespace: 'default'
              command: 'apply'
              useConfigurationFile: true
              configuration: '$(Pipeline.Workspace)/pipelineA/deployment-files/deployment.yaml'
              secretType: 'dockerRegistry'
              containerRegistry: 'acrnnn.azurecr.io'  # ACR URL
              image: 'acrnnn.azurecr.io/aksimage:$(imageTag)'  # Use the resolved tag here
  










And below is the error I am seeing the in the POD logs:

  ContainersReady             False
  PodScheduled                True
Volumes:
  kube-api-access-hww2c:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason         Age                 From               Message
  ----     ------         ----                ----               -------
  Normal   Scheduled      2m2s                default-scheduler  Successfully assigned default/aks-agent-deployment-6f764799b4-4d224 to aks-tt-60570973-vmss000001
  Warning  InspectFailed  9s (x11 over 2m1s)  kubelet            Failed to apply default image tag "acrnnn.azurecr.io/aksimage:$(imageTag)": couldn't parse image name "acrnnn.azurecr.io/aksimage:$(imageTag)": invalid reference format
  Warning  Failed         9s (x11 over 2m1s)  kubelet            Error: InvalidImageName

I am trying to generate artifact having deployment file in the pipeline 1 and I am trying to download and use in pipeline 2 but I am getting error as below , so AKS deployment is failing , Please suggest fix and let me know what could be the issue , Thank you

Azure DevOps
{count} votes

1 answer

Sort by: Most helpful
  1. Bheemani Anji Babu 5 Reputation points Microsoft External Staff
    2025-05-02T14:41:03.6166667+00:00

    To build the image and push it to ACR then deploy the image into AKS. Follow the below steps: I tried this in my test environment in two ways and succeeded.

    1. The one approach is simple and clear way to do this job from ACR to AKS, using service connection. without PAT.
    2. Another approach is yours's I successfully achieve this too, with PAT

    I will demonstrate both methods to help you understand and resolve your case.

    1. Approach:

    create the service connection in azure DevOps to enable secure connection b/w your subscription

    Recommended:
    
    App registration (automatic)
    Work identity federation
    Subscription level
    

    create Docker file and index.html

    in my case I used below simple docker file and html

    Simple Docker file:

    FROM nginx:alpine
    COPY index.html /usr/share/nginx/html/index.html
    EXPOSE 80
    

    Simple html file:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Welcome to Nginx</title>
    </head>
    <body>
      <h1>Hello from Nginx on Alpine!</h1>
      <p>This is a simple static HTML page.</p>
    </body>
    </html>
    

    Create Resource Group:

    az group create -l centralindia -n anji-rg
    

    create Container registry:

    az acr create -g anji-rg -n acranji2654 --sku Basic
    

    Create aks cluster by attaching the acr in-order to communicate:

    az aks create -g anji-rg -n aksanji2654 -c 2 --attach-acr acranji2654
    

    Configure AKS to communicate with clusters:

    az aks get-credentials -g anji-rg -n aksanji2654 --overwrite-existing
    

    Later create new pipeline by selecting Deploy to azure Kubernetes service by choosing your subscription then it will open configuration page then give your cluster name along with your registry details. Then it will generate pipeline file.

    After pipeline got succeeded you will get two manifest files like deployment.yml & service.yml

    Note: For the first time, you should grant permission to deploy the environment by opening another tab on the pipeline page.

    The above process is usually followed. However, you can also create your own HTML file and custom Docker file using this same approach. It is easy to reuse and modify any files.

    Screenshot 2025-05-02 173827

    1. Approach:

    Regarding your approach, ensure you grant the correct permissions to your PAT and then save it in the pipeline variables.

    Code: Read & Write
    Build: Read & Execute
    

    I will share my files to help you understand. You can configure your files by referring to these examples.

    Make sure to update each service connection name separately. For example, the AKS service connection has one AKS service connection created, and similarly for ACR. Please refer to the details below.

    Azure-pipeline.yml

    trigger:
    - main
    
    variables:
      dockerRegistryServiceConnection: 'acranji2654'  
      imageRepository: 'tesproject'
      containerRegistry: 'acranji2654.azurecr.io'
      dockerfilePath: '**/Dockerfile'
      tag: '$(Build.BuildId)'
      imagePullSecret: 'acranji2654f506-auth'
      vmImageName: 'ubuntu-latest'
    
    stages:
    - stage: Build
      displayName: Build and Push Image
    
      jobs:
      - job: Build
        displayName: Build
        pool:
          vmImage: $(vmImageName)
    
        steps:
        - task: Docker@2
          displayName: Build and Push Docker Image
          inputs:
            command: buildAndPush
            repository: $(imageRepository)
            dockerfile: $(dockerfilePath)
            containerRegistry: $(dockerRegistryServiceConnection)
            tags: |
              $(tag)
        - publish: manifests
          artifact: manifests
    - stage: Deploy
      displayName: Deploy to AKS
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy to AKS Cluster
        pool:
          vmImage: $(vmImageName)
        environment: 'Tesproject.default'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: manifests
              - task: KubernetesManifest@0
                displayName: Create imagePullSecret
                inputs:
                  action: createSecret
                  secretName: $(imagePullSecret)
                  dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
                  kubernetesServiceConnection: 'aksanji2654-default'
                  namespace: 'default'
              - task: KubernetesManifest@0
                displayName: Create AZP_TOKEN Secret
                inputs:
                  action: deploy
                  kubernetesServiceConnection: 'aksanji2654-default'
                  namespace: 'default'
                  manifests: |
                    $(Pipeline.Workspace)/manifests/azp-secret.yaml
              - task: KubernetesManifest@0
                displayName: Deploy App to AKS
                inputs:
                  action: deploy
                  kubernetesServiceConnection: 'aksanji2654-default'
                  namespace: 'default'
                  manifests: |
                    $(Pipeline.Workspace)/manifests/deployment.yml
                    $(Pipeline.Workspace)/manifests/service.yml
                  imagePullSecrets: |
                    $(imagePullSecret)
                  containers: |
                    $(containerRegistry)/$(imageRepository):$(tag)
    

    deployment.yml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tesproject
      labels:
        app: tesproject
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: tesproject
      template:
        metadata:
          labels:
            app: tesproject
        spec:
          containers:
          - name: tesproject
            image: acranji2654.azurecr.io/tesproject:$(Build.BuildId)
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: acranji2654f506-auth
    

    service.yml

    apiVersion: v1
    kind: Service
    metadata:
        name: tesproject
    spec:
        type: LoadBalancer
        ports:
        - port: 80 
        selector:
            app: tesproject
    

    Make sure you have to create a file called azp-secret.yaml

    It keeps your PAT securely stored in the Kubernetes cluster, also the agent reads this secret via environment variable or volume mount when it starts up.

    azp-secret.yaml

    apiVersion: v1
    kind: Secret
    metadata:
      name: azp-token-secret
    type: Opaque
    stringData:
      AZP_TOKEN: $(AZP_TOKEN)
    

    2025-05-02 19_35_00-

    2025-05-02 18_21_52-● test - test - Visual Studio Code

    2025-05-02 18_24_16-Welcome to Nginx and 15 more pages - Work - Microsoft​ Edge
    Please let me know how these approaches work for you. If you need any further clarity, please feel free to reach out to me.

    1 person found this answer helpful.

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.