How to define image name in Kubernetes manifest deployment.yml file dynamically or with variables?

8/23/2021

I have deplyonment.yml file which looks like below :

apiVersion : apps/v1
kind: Deployment
metadata:
  name: worker
spec:
  progressDeadlineSeconds: 3600
  replicas: 1
  selector:
    matchLabels:
      app: worker
  template:
    metadata:
      labels:
        app: worker
    spec:
      containers:
        - name: worker         
          image: $(RegistryName)/$(RepositoryName):$(Build.BuildNumber)
          imagePullPolicy: Always 

But I am not able to use $(RegistryName) and $(RepositoryName) as I am not sure how to even initialize this and assign a value here.

If I specify something like below

image: XXXX..azurecr.io/werepo:$(Build.BuildNumber)

It worked with the direct static and exact names. But I don't want to hard core registry and repository name.

Is there any way to replace this dynamically? just like the way I am passing these in task

  - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              kubernetesServiceConnection: 'XXXX-connection'
              namespace: 'XXXX-namespace'
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml 
              containers: |
                $(Registry)/$(webRepository):$(Build.BuildNumber) 
-- JARVIS
azure-container-registry
azure-devops
azure-pipelines
docker
kubernetes

1 Answer

8/23/2021

You can do something like

deployment.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: test-image
  labels:
    app: test-image
spec:
  selector:
    matchLabels:
      app: test-image
      tier: frontend
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: test-image
        tier: frontend
    spec:
      containers:
      - image: TEST_IMAGE_NAME
        name: test-image
        ports:
        - containerPort: 8080
          name: http
        - containerPort: 443
          name: https

in CI step or run sed command in ubuntu like

steps:
- id: 'set test core image in yamls'
  name: 'ubuntu'
  args: ['bash','-c','sed -i "s,TEST_IMAGE_NAME,gcr.io/$PROJECT_ID/$REPO_NAME/$BRANCH_NAME:$SHORT_SHA," deployment.yaml']

above will resolve your issue.

Above command simply find & replace TEST_IMAGE_NAME with variables that creating the docker image URI.

Option : 2 kustomization

If you want to do it with customization

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service.yaml
- deployment.yaml
namespace: default
commonLabels:
  app: myapp
images:
- name: myapp
  newName: registry.gitlab.com/jkpl/kustomize-demo
  newTag: IMAGE_TAG

sh file

#!/usr/bin/env bash
set -euo pipefail

# Set the image tag if not set
if [ -z "${IMAGE_TAG:-}" ]; then
    IMAGE_TAG=$(git rev-parse HEAD)
fi

sed "s/IMAGE_TAG/${IMAGE_TAG}/g" k8s-base/kustomization.template.sed.yaml > location/kustomization.yaml

Demo github : https://gitlab.com/jkpl/kustomize-demo

-- Harsh Manvar
Source: StackOverflow