Play application not picking environment variables from Kubernetes yaml file Ask

My YAML file has the following environment variables defined.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: codingjediweb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: codingjediweb
  template:
    metadata:
      labels:
        app: codingjediweb
    spec:
      volumes:
      - name: shared-logs
        emptyDir: {}
      containers:
      - name: codingjediweb
        image: docker.io/manuchadha25/codingjediweb:06072020
        volumeMounts:
        - name: shared-logs
          mountPath: /deploy/codingjediweb-1.0/logs/
        env:
    - name: db.cassandraUri
              value: cassandra://xx.yy.zzz.ppp:9042
            - name: db.password
              value: 9__
            - name: db.keyspaceName
              value: dbname
            - name: db.username
              value: dbname2
       ports:
        - containerPort: 9000
      - name: logging
        image: busybox
        volumeMounts:
        - name: shared-logs
          mountPath: /deploy/codingjediweb-1.0/logs/
        command: ['sh', '-c', "while true; do sleep 86400; done"]

My Play application uses the variables. If a variable is not defined in config file then Play checks for environment variables.

https://www.playframework.com/documentation/2.6.x/ConfigFile

My application picks the configuration as follows

 val dbUsernameOption = configuration.getOptional[String]("db.username")

    val dbUsername = dbUsernameOption.map(name => name).getOrElse({
      cassandraRepositoryComponentsLogger.error("unable to pick db username from configuration.")
      ""
    })

    val dbPasswordOption = configuration.getOptional[String]("db.password")
    val dbPassword = dbPasswordOption.map(name=>name).getOrElse({
      cassandraRepositoryComponentsLogger.error("unable to pick db password from configuration.")
      ""
    })

When I start the application by applying the Kubernetes YAML file, the container stops and I see error

unable to pick db username from configuration.
unable to pick db password from configuration.

I can see that the environment variables are defined in the container.

# printenv
db.keyspaceName=somename <-- here
KUBERNETES_PORT=tcp://10.15.240.1:443
KUBERNETES_SERVICE_PORT=443
CODINGJEDIWEB_SERVICE_PORT_9000_TCP_ADDR=10.15.249.26
HOSTNAME=codingjediweb-649db4fcb9-xxhwm
CODINGJEDIWEB_SERVICE_PORT_9000_TCP_PORT=9000
SHLVL=1
CODINGJEDIWEB_SERVICE_PORT_9000_TCP_PROTO=tcp
HOME=/root
CODINGJEDIWEB_SERVICE_SERVICE_HOST=10.15.249.26
db.cassandraUri=cassandra://xxx <-- here
CODINGJEDIWEB_SERVICE_PORT_9000_TCP=tcp://10.15.249.26:9000
CODINGJEDIWEB_SERVICE_SERVICE_PORT=9000
CODINGJEDIWEB_SERVICE_PORT=tcp://10.15.249.26:9000
db.username=something <-- here
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.15.240.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.15.240.1:443
KUBERNETES_SERVICE_HOST=10.15.240.1
PWD=/
db.password=9__ <-- here
/ #

Am I incorrect that Play will check for environment variables if the configuration is missing in config file? I am not sure if this is a Play issue or a Kubernetes issue because when I run the Play application in IntelliJ and provide the environment variables in the build configuration then the application works.

enter image description here

Hi @manuchadha,

instead of directly using:

 val dbUsernameOption = configuration.getOptional[String]("db.username")

try:

// in application.conf
# reads the EnvVar and sets the value in the `Config` object.
myproject.db.username = ${db.username}

and then:

 val dbUsernameOption = configuration.getOptional[String]("myproject.db.username")

Thanks. I tried to change to substitutions but that doesn’t seem to work either - cassandraUri=${?DB_CASSANDRA_URI} where DB_CASSANDRA_URI is an environment variable. I’ll try without the ?.