Parameterizing custom fields in Helm Chart, Kustomize, OC templates

In this tutorial, we illustrate how to parameterize a custom field in the Helm chart generated by Move2Kube.

  1. Start by creating an empty workspace directory say workspace and make it the current working directory. We will assume all commands are executed within this directory.
$ mkdir workspace && cd workspace
  1. Use the enterprise-app as input for this flow.
$ curl https://move2kube.konveyor.io/scripts/download.sh | bash -s -- -d samples/enterprise-app/src -r move2kube-demos
$ ls src
README.md		config-utils		customers	docs			frontend		gateway			orders
  1. Run Move2Kube without any customization. The relevant snippet from the deployment YAML generated in the path myproject/deploy/yamls-parameterized/helm-chart/myproject/templates/orders-deployment.yaml looks like this.

When complete, delete the myproject directory.

$ move2kube transform -s src/ --qa-skip && cat myproject/deploy/yamls-parameterized/helm-chart/myproject/templates/orders-deployment.yaml && rm -rf myproject
  apiVersion: apps/v1
  kind: Deployment
  metadata:
      annotations:
          move2kube.konveyor.io/service.expose: "true"
      creationTimestamp: null
      labels:
          move2kube.konveyor.io/service: orders
      name: orders
  spec:
      progressDeadlineSeconds: 600
      replicas: {% raw %}{{ index .Values "common" "replicas" }}{% endraw %}
      revisionHistoryLimit: 10
      selector:
          matchLabels:
              move2kube.konveyor.io/service: orders
      strategy:
          rollingUpdate:
              maxSurge: 25%
              maxUnavailable: 25%
          type: RollingUpdate
      template:
          metadata:
              annotations:
                  move2kube.konveyor.io/service.expose: "true"
              creationTimestamp: null
              labels:
                  move2kube.konveyor.io/service: orders
              name: orders
          spec:
              containers:
                  - env:
                      - name: PORT
                        value: "8080"
                    image: quay.io/myproject/orders:latest
                    imagePullPolicy: Always
                    name: orders
                    ports:
                      - containerPort: 8080
                        protocol: TCP
                    resources: {}
                    terminationMessagePath: /dev/termination-log
                    terminationMessagePolicy: File
              dnsPolicy: ClusterFirst
              imagePullSecrets:
                  - name: quay-io-imagepullsecret
              restartPolicy: Always
              schedulerName: default-scheduler
              securityContext: {}
              terminationGracePeriodSeconds: 30
  status: {}

Notice that except the replicas field, no other field is parameterized.

  1. Use a custom configured version of the parameterizer transformer to view the parameterizing the other fields in the transformer.

Then copy it into the customizations sub-directory.

$ curl https://move2kube.konveyor.io/scripts/download.sh | bash -s -- -d custom-helm-kustomize-octemplates-parameterization -r move2kube-transformers -o customizations
  1. Transform using this customization and specify the customization using the -c flag.
$ move2kube transform -s src/ -c customizations/ --qa-skip

When the output is generated, observe the same deployment as mentioned before.

$ cat myproject/deploy/yamls-parameterized/helm-chart/myproject/templates/orders-deployment.yaml
  {% raw %}apiVersion: apps/v1
  kind: Deployment
  metadata:
      annotations:
          move2kube.konveyor.io/service.expose: "true"
      creationTimestamp: null
      labels:
          move2kube.konveyor.io/service: orders
      name: orders
  spec:
      progressDeadlineSeconds: 600
      replicas: {{ index .Values "common" "replicas" }}
      revisionHistoryLimit: 10
      selector:
          matchLabels:
              move2kube.konveyor.io/service: orders
      strategy:
          rollingUpdate:
              maxSurge: 25%
              maxUnavailable: 25%
          type: RollingUpdate
      template:
          metadata:
              annotations:
                  move2kube.konveyor.io/service.expose: "true"
              creationTimestamp: null
              labels:
                  move2kube.konveyor.io/service: orders
              name: orders
          spec:
              containers:
                  - env:
                      - name: PORT
                        value: "8080"
                    image: {{ index .Values "imageregistry" "url" }}/{{ index .Values "imageregistry" "namespace" }}/{{ index .Values "services" "orders" "containers" "orders" "image" "name" }}:{{ index .Values "services" "orders" "containers" "orders" "image" "tag" }}
                    imagePullPolicy: Always
                    name: orders
                    ports:
                      - containerPort: 8080
                        protocol: TCP
                    resources: {}
                    terminationMessagePath: /dev/termination-log
                    terminationMessagePolicy: File
              dnsPolicy: ClusterFirst
              imagePullSecrets:
                  - name: quay-io-imagepullsecret
              restartPolicy: Always
              schedulerName: default-scheduler
              securityContext: {}
              terminationGracePeriodSeconds: 30
  status: {}
  {% endraw %}

A few of the parameterized yamls are:

$ cat myproject/deploy/yamls-parameterized/helm-chart/myproject/values-prod.yaml
  common:
    replicas: 10
  imageregistry:
    namespace: konveyor
    url: quay.io
  services:
    config-utils:
      containers:
        config-utils:
          image:
            name: myimage
            tag: latest
    customers:
      containers:
        customers:
          image:
            name: myimage
            tag: latest
    frontend:
      containers:
        frontend:
          image:
            name: frontend
            tag: latest
    gateway:
      containers:
        gateway:
          image:
            name: myimage
            tag: latest
    orders:
      containers:
        orders:
          image:
            name: orders
            tag: latest
$ cat myproject/deploy/yamls-parameterized/kustomize/overlays/prod/apps-v1-deployment-orders.yaml
  - op: replace
    path: /spec/replicas
    value: 10
  - op: replace
    path: /spec/template/spec/containers/0/image
    value: orders
$ cat myproject/deploy/yamls-parameterized/openshift-template/parameters-prod.yaml
COMMON_REPLICAS=10
IMAGEREGISTRY_URL=quay.io
IMAGEREGISTRY_NAMESPACE=konveyor
SERVICES_FRONTEND_CONTAINERS_FRONTEND_IMAGE_TAG=latest
SERVICES_GATEWAY_CONTAINERS_GATEWAY_IMAGE_NAME=myimage
SERVICES_ORDERS_CONTAINERS_ORDERS_IMAGE_NAME=orders
SERVICES_ORDERS_CONTAINERS_ORDERS_IMAGE_TAG=latest
SERVICES_CUSTOMERS_TOMCAT_CONTAINERS_CUSTOMERS_TOMCAT_IMAGE_NAME=myimage
SERVICES_CUSTOMERS_TOMCAT_CONTAINERS_CUSTOMERS_TOMCAT_IMAGE_TAG=latest
SERVICES_FRONTEND_CONTAINERS_FRONTEND_IMAGE_NAME=frontend
SERVICES_CONFIG_UTILS_CONTAINERS_CONFIG_UTILS_IMAGE_NAME=myimage
SERVICES_CONFIG_UTILS_CONTAINERS_CONFIG_UTILS_IMAGE_TAG=latest
SERVICES_GATEWAY_CONTAINERS_GATEWAY_IMAGE_TAG=latest

Anatomy of the parameterizer

The contents of parameterizer are as shown below:

$ ls customizations/custom-helm-kustomize-octemplates-parameterization/
README.md			deployment-parameterizers.yaml	parameterizers.yaml

The transformer configuration is in parameterizers.yaml and the parameterization config is in deployment-parameterizers.yaml. The configuration below specifies the fields that need to be parameterized, how to parameterize them, and the default values those fields should take. This can be extended to parameterize any field in any Kubernetes Yaml, and generate the appropriate helm chart, Kustomize YAMLs and Openshift templates.

$ cat customizations/custom-helm-kustomize-octemplates-parameterization/deployment-parameterizers.yaml
  {% raw %}apiVersion: move2kube.konveyor.io/v1alpha1
  kind: Parameterizer
  metadata:
    name: deployment-parameterizers
  spec:
    parameterizers:
      - target: "spec.replicas"
        template: "${common.replicas}"
        default: 10
        filters:
          - kind: Deployment
            apiVersion: ".*/v1.*"
      - target: 'spec.template.spec.containers.[containerName:name].image'
        template: '${imageregistry.url}/${imageregistry.namespace}/${services.$(metadataName).containers.$(containerName).image.name}:${services.$(metadataName).containers.$(containerName).image.tag}'
        default: quay.io/konveyor/myimage:latest
        filters:
          - kind: Deployment
            apiVersion: ".*/v1.*"
        parameters:
          - name: services.$(metadataName).containers.$(containerName).image.name
            values:
            - envs: [dev, staging, prod]
              metadataName: frontend
              value: frontend
            - envs: [prod]
              metadataName: orders
              value: orders
              custom:
                containerName: orders
  {% endraw %}

Next step is adding custom files and directories in custom locations.