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))
The problem is right now I have to manually retrieve this build version and enter it into deployment.yaml and then run kubectl apply -f deployment.yaml
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.
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?
Here is my deployment.yaml
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
And here is my CI/CD azure-pipelines.yaml
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: "$(docker_image_name):$(tag)"
steps:
- script: |
az acr login --name my_registry.azurecr.io --username user --password $(acr_password)
displayName: ACR Login
- bash: >
docker build -f ./Dockerfile -t "$(IMAGE_AND_TAG)" .
displayName: Build docker image
workingDirectory: $(PROJECT_DIR)
- script: |
REGISTRY_PATH=my_registry.azurecr.io/serving
docker tag "$(IMAGE_AND_TAG)" "$REGISTRY_PATH/$(IMAGE_AND_TAG)"
docker push "$REGISTRY_PATH/$(IMAGE_AND_TAG)"
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: "ingress-basic"
manifests: |
$(System.ArtifactsDirectory)/manifests/cluster-isseur.yaml
$(System.ArtifactsDirectory)/manifests/deployment.yaml
$(System.ArtifactsDirectory)/manifests/ingress.yaml
imagePullSecrets: |
$(imagePullSecret)
containers: |
"$REGISTRY_PATH/$(docker_image_name):$(tag)"
CodePudding user response:
Replace tokens task can solve your problem. I use it most of the time.
- For the deployment yaml, change the image like this.
image: my_registry.azurecr.io/serving/mission_model_api:#{Build.BuildId}#
- Before the task: PublishPipelineArtifact@0 task in Build stage, put a Replace Tokens task. You should add it as an extension to Azure DevOps
- 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
Then it should work as you expected.