How to populate application.properties file value from kubernetes Secrets mounted as file

3/2/2021

I am working on Springboot and Kubernetes and I have really simple application that connects to Postgres database. I want to get the value of datasource from configmap and password from secrets as mount file.

Configmap file :

apiVersion: v1
kind: ConfigMap
metadata:
  name: customer-config
data:
  application.properties: |
    server.forward-headers-strategy=framework
    spring.datasource.url=jdbc:postgresql://test/customer
    spring.datasource.username=postgres

Secrets File :

apiVersion: v1
kind: Secret
metadata:
  name: secret-demo
data:
  spring.datasource.password: cG9zdGdyZXM=

deployment file :

spec:
  containers:
    - name: customerc
      image: localhost:8080/customer
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 8282
      volumeMounts:
        - mountPath: /workspace/config/default
          name: config-volume
        - mountPath: /workspace/secret/default
          name: secret-volume
  volumes:
    - name: config-volume
      configMap:
        name: customer-config
    - name: secret-volume
      secret:
        secretName: secret-demo
        items:
          - key: spring.datasource.password
            path: password

If I move spring.datasource.password prop from secret to configmap then it works fine or If I populate its value as env variable then also work fine. But as we know both are not secure way to do so, can someone tell me what's wrong with file mounting for secrets.

-- Still Learning
kubernetes
spring-boot

3 Answers

3/2/2021

Spring Boot 2.4 added support for importing a config tree. This support can be used to consume configuration from a volume mounted by Kubernetes.

As an example, let’s imagine that Kubernetes has mounted the following volume:

etc/
  config/
    myapp/
      username
      password

The contents of the username file would be a config value, and the contents of password would be a secret.

To import these properties, you can add the following to your application.properties file:

spring.config.import=optional:configtree:/etc/config/

This will result in the properties myapp.username and myapp.password being set . Their values will be the contents of /etc/config/myapp/username and /etc/config/myapp/password respectively.

-- Andy Wilkinson
Source: StackOverflow

3/2/2021

By default, consuming secrets through the API is not enabled for security reasons.Spring Cloud Kubernetes requires access to Kubernetes API in order to be able to retrieve a list of addresses of pods running for a single service. The simplest way to do that when using Minikube is to create default ClusterRoleBinding with cluster-admin privilege.

Example on how to create one :-

$ kubectl create clusterrolebinding admin --clusterrole=cluster-admin --serviceaccount=default:default

-- Amit
Source: StackOverflow

3/2/2021

You need to give secret type in manifest file. Hope it will work.

apiVersion: v1
kind: Secret
metadata:
  name: secret-demo
type: Opaque
data:
  spring.datasource.password: cG9zdGdyZXM
-- Pulak Kanti Bhowmick
Source: StackOverflow