How to consume properties from configmaps in Java Spring boot application deployed through Helm

5/11/2018

I have simple Spring boot application which I need to deploy on development and prod different namespaces on a Kubernetes cluster using Helm.

I was thinking about keeping multiple application.properties (application-dev.properties, application-prod.properties) files for each environment and then create configmaps from them through values.yaml files which also will be different for each environment and specified when I execute Helm upgrade.

Now the question is how do I consume values from config.maps as I understand I can either mount the properties file inside container for example /deployment/application.properties

Or expose each property as an environment variable inside container.

But how do I consume them from Java application?

Also at the moment when I create container image it has current application .properties inside /resources/ files embedded and this is what application is using from default so I need to overwrite this behaviour when application is running inside container as opposite to then when its just build and run manually on developer desktop.

-- Rafal
java
kubernetes
kubernetes-helm
spring-boot

3 Answers

5/22/2018

I'd recommend mounting the files (application.properties or application.yml) inside the ConfigMap onto somewhere on the file system that Spring Boot can automatically detect - then your app stays nice and simple

-- James Strachan
Source: StackOverflow

5/11/2018

Springboot can automatically infer variables from environment variables. In your application.properties or application.yaml, just use ${MY_ENVIRONMENT_VARIABLE:my-defaultvalue}.
Use helm to populate your configmap. Use configmap as environment variables into your deployment manifest.

This way you do not need to have multiple application.properties for dev, int ,prod inside your image. Keeping it intact across deployment.

And then in your helm chart, you can have multiple values.yaml example values-dev.yaml or values-int.yaml. you can also dynamically set helm values from command line, overriding the yaml file.

I have a demo app in github https://github.com/balchua/demo, which uses this pattern.

-- Bal Chua
Source: StackOverflow

5/14/2018

You could certainly use environment variables as Bal Chua suggests. If you do that you can override particular values at install time using --set or if you've a lot of config you can use the '-- values' flag and pass in a custom values.yaml file.

Another approach is to load a whole file using .Files.Glob (example in github) and load the file as part of the chart. You can then mount the file to /config to consume it in your spring boot application. Then your config file would be in the same form as a Spring boot config file, rather than a helm values.yaml. Though in many cases there needn't be much difference.

There's a discussion of how you could do similar for secrets (presumably you'll want to put your passwords in secrets) and use it for CI/CD in https://dzone.com/articles/hunting-treasure-with-kubernetes-configmaps-and-se (which is the article accompanying the github example). Basically you would use .Files.Glob with .AsSecrets instead of .AsConfig so as to encode the content. Many helm charts have the option to generate a random password if not specified but I'd guess you probably don't need that.

-- Ryan Dawson
Source: StackOverflow