<p>I'm trying to deploy an app to AKS cluster. Everytime I push changes to my branch, I want AKS to redeploy pods and make use of the most recent tag (which I have versioned with $(Build.BuildId))</p>
<p>The problem is right now I have to manually retrieve this build version and enter it into deployment.yaml and then run <code>kubectl apply -f deployment.yaml</code> for the change to go ahead. For example, the most recent tag is 58642, so I would have to log into my Azure Container Registry, retrieve the version number, update the deployment.yaml, and then apply for changes to take effect.</p>
<p>How can I change my setup here so that the most recently built and tagged container is deployed to the AKS cluster as part of my CICD?</p>
<p>Here is my <code>deployment.yaml</code></p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: mission-model-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mission-model-api
  template:
    metadata:
      labels:
        app: mission-model-api
    spec:
      containers:
      - name: mission-model-api
        image: my_registry.azurecr.io/serving/mission_model_api:58642
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        ports:
        - containerPort: 80
        imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: mission-model-api
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: mission-model-api
</code></pre>
<p>And here is my CI/CD <code>azure-pipelines.yaml</code></p>
<pre><code>variables:
  tag: '$(Build.BuildId)'
  vmImageName: 'ubuntu-latest'
  envName: 'poc-releases'
  docker_image_name: API
  imagePullSecret: 'AUTH'
  dockerRegistryServiceConnection: 'XX'

trigger:
  batch: true
  branches:
    include:
      - feature/*

stages:
- stage: Build
  displayName: Build stage
  pool:
    vmImage: $(vmImageName)
  jobs:
    - job: Build
      displayName: Build job
      variables:
        PROJECT_DIR: $(Build.SourcesDirectory)/apps/$(docker_image_name)
        IMAGE_AND_TAG: &quot;$(docker_image_name):$(tag)&quot;
      steps:
        - script: |
            az acr login --name my_registry.azurecr.io --username user --password $(acr_password)
          displayName: ACR Login
        - bash: &gt;
            docker build -f ./Dockerfile -t &quot;$(IMAGE_AND_TAG)&quot; .
          displayName: Build docker image
          workingDirectory: $(PROJECT_DIR)
        - script: |
            REGISTRY_PATH=my_registry.azurecr.io/serving
            docker tag &quot;$(IMAGE_AND_TAG)&quot; &quot;$REGISTRY_PATH/$(IMAGE_AND_TAG)&quot;
            docker push &quot;$REGISTRY_PATH/$(IMAGE_AND_TAG)&quot;
          displayName: Tag and Push to ACR
        - task: PublishPipelineArtifact@0
          inputs:
            artifact: 'manifests'
            artifactName: 'manifests'
            targetPath: '$(PROJECT_DIR)/manifests'

- stage: Deploy_BVT
  displayName: Deploy BVT
  dependsOn: Build
  jobs:
  - deployment: Deploy_BVT
    pool:
      vmImage: $(vmImageName)
    environment: '$(envName).ingress-basic'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: DownloadPipelineArtifact@1
            inputs:
              artifactName: 'manifests'
              downloadPath: '$(System.ArtifactsDirectory)/manifests'
          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: ingress-basic
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
          - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              namespace: &quot;ingress-basic&quot;
              manifests: |
                $(System.ArtifactsDirectory)/manifests/cluster-isseur.yaml
                $(System.ArtifactsDirectory)/manifests/deployment.yaml
                $(System.ArtifactsDirectory)/manifests/ingress.yaml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                &quot;$REGISTRY_PATH/$(docker_image_name):$(tag)&quot;
</code></pre>

Sam Comber
<p>Replace tokens task can solve your problem. I use it most of the time.</p>
<ol>
<li>For the deployment yaml, change the image like this.</li>
</ol>
<blockquote>
<pre><code>image: my_registry.azurecr.io/serving/mission_model_api:#{Build.BuildId}#
</code></pre>
</blockquote>
<ol start="2">
<li>Before the <strong>task: PublishPipelineArtifact@0</strong> task in <strong>Build</strong> stage, put a <strong><a href="https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens" rel="nofollow noreferrer">Replace Tokens</a></strong> task. You should add it as an extension to Azure DevOps</li>
</ol>
<blockquote>
<pre><code>- task: replacetokens@4
  inputs:
    targetFiles: '**/deployment.yml'
    encoding: 'auto'
    tokenPattern: 'default'
    writeBOM: true
    actionOnMissing: 'warn'
    keepToken: false
    actionOnNoFiles: 'continue'
    enableTransforms: false
    useLegacyPattern: false
    enableTelemetry: true
</code></pre>
</blockquote>
<p>Then it should work as you expected.</p>
