How to replace fields value of angular config.json using environment variable in kubernetes and nginx in CI &CD VSTS

7/1/2019

I am trying to replace authenticationEndpoint url and other configuation in the config.json of angular project using environment variable in kubernetes dynamically. For that configured in the helm chart for environment variable in the CI & CD pipeline of VSTS. But not sure how config.json field will be replaced with environment variable in kubernetes. Could you please help me on this.?

env in pods (kubernetes) ran printenv cmd

 authenticationEndpoint=http://localhost:8888/security/auth

config.json

 {
   "authenticationEndpoint": "http://localhost:8080/Security/auth",
   "authenticationClientId": "my-project",
   "baseApiUrl": "http://localhost:8080/",
   "homeUrl": "http://localhost:4300/"
 }

Generated yaml file from helm chart

        # Source: sample-web/templates/service.yaml
        apiVersion: v1
        kind: Service
        metadata:
          name: cloying-rattlesnake-sample-web
          labels:
            app.kubernetes.io/name: sample-web
            helm.sh/chart: sample-web-0.1.0
            app.kubernetes.io/instance: cloying-rattlesnake
            app.kubernetes.io/managed-by: Tiller
        spec:
          type: ClusterIP
          ports:
            - port: 80
              targetPort: 80
              protocol: TCP
              name: http
          selector:
            app.kubernetes.io/name: sample-web
            app.kubernetes.io/instance: cloying-rattlesnake
        ---
        # Source: sample-web/templates/deployment.yaml
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: cloying-rattlesnake-sample-web
          labels:
            app.kubernetes.io/name: sample-web
            helm.sh/chart: sample-web-0.1.0
            app.kubernetes.io/instance: cloying-rattlesnake
            app.kubernetes.io/managed-by: Tiller
        spec:
          replicas: 1
          selector:
            matchLabels:
              app.kubernetes.io/name: sample-web
              app.kubernetes.io/instance: cloying-rattlesnake
          template:
            metadata:
              labels:
                app.kubernetes.io/name: sample-web
                app.kubernetes.io/instance: cloying-rattlesnake
            spec:
              containers:
                - name: sample-web
                  image: "sample-web:stable"
                  imagePullPolicy: IfNotPresent
                  ports:
                    - name: http
                      containerPort: 80
                      protocol: TCP
                  livenessProbe:
                    httpGet:
                      path: /
                      port: http
                  readinessProbe:
                    httpGet:
                      path: /
                      port: http
                  env:
                    - name: authenticationEndpoint
                      value: "http://localhost:8080/security/auth"
                  resources:
                    {}
        ---
        # Source: sample-web/templates/ingress.yaml
        apiVersion: extensions/v1beta1
        kind: Ingress
        metadata:
          name: cloying-rattlesnake-sample-web
          labels:
            app.kubernetes.io/name: sample-web
            helm.sh/chart: sample-web-0.1.0
            app.kubernetes.io/instance: cloying-rattlesnake
            app.kubernetes.io/managed-by: Tiller
          annotations:
            kubernetes.io/ingress.class: nginx
            nginx.ingress.kubernetes.io/rewrite-target: /$1
            nginx.ingress.kubernetes.io/ssl-redirect: "false"

        spec:
          rules:
            - host: ""
              http:
                paths:
                  - path: /?(.*)
                    backend:
                      serviceName: cloying-rattlesnake-sample-web
                      servicePort: 80

Absolute path of config.json

Ran shell cmd - kubectl exec -it sample-web-55b71d19c6-v82z4 /bin/sh

path: usr/share/nginx/html/config.json
-- Seenu
angular6
docker
kubernetes
kubernetes-helm
nginx

2 Answers

7/12/2019

I have found simple solution. using shell script I am applying same command to replace the content of the config.json then start Nginx for running application. It works....

Config.json

{
  "authenticationEndpoint": "$AUTHENTICATION_ENDPOINT",
  "authenticationClientId": "$AUTHENTICATION_CLIENT_ID",
  "baseApiUrl": "http://localhost:8080/",
  "homeUrl": "http://localhost:4300/"
}

setup.sh

sed -i -e 's#$AUTHENTICATION_ENDPOINT#'"$AUTHENTICATION_ENDPOINT"'#g' usr/share/nginx/html/config.json
sed -i -e 's#$AUTHENTICATION_CLIENT_ID#'"$AUTHENTICATION_CLIENT_ID"'#g' /usr/share/nginx/html/config.json
nginx -g 'daemon off;'
-- Seenu
Source: StackOverflow

7/1/2019

Use a init container to modify your config.json when the pod starts.

Updated your Deployment.yaml

    # Source: sample-web/templates/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: cloying-rattlesnake-sample-web
      labels:
        app.kubernetes.io/name: sample-web
        helm.sh/chart: sample-web-0.1.0
        app.kubernetes.io/instance: cloying-rattlesnake
        app.kubernetes.io/managed-by: Tiller
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: sample-web
          app.kubernetes.io/instance: cloying-rattlesnake
      template:
        metadata:
          labels:
            app.kubernetes.io/name: sample-web
            app.kubernetes.io/instance: cloying-rattlesnake
        spec:
          initContainers:
            - name: init-myconfig
              image: busybox:1.28
              command: ['sh', '-c', 'cat /usr/share/nginx/html/config.json | sed -e "s#\$authenticationEndpoint#$authenticationEndpoint#g" > /tmp/config.json && cp /tmp/config.json /usr/share/nginx/html/config.json']
              env:
                - name: authenticationEndpoint
                  value: "http://localhost:8080/security/auth"
          containers:
            - name: sample-web
              image: "sample-web:stable"
              imagePullPolicy: IfNotPresent
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /
                  port: http
              readinessProbe:
                httpGet:
                  path: /
                  port: http
              env:
                - name: authenticationEndpoint
                  value: "http://localhost:8080/security/auth"
              volumeMounts:
                - mountPath: /usr/share/nginx/html/config.json
                  name: config-volume
          volumes:
            - name: config-volume
              hostPath:
                path: /mnt/data.json # Create this file in the host where the pod starts. Content below.
                type: File

Create /mnt/data.json file in the host where the pod starts

{
      "authenticationEndpoint": "$authenticationEndpoint",
      "authenticationClientId": "my-project",
      "baseApiUrl": "http://localhost:8080/",
      "homeUrl": "http://localhost:4300/"
}
-- Prakash Krishna
Source: StackOverflow