Understanding passing values from helm charts to java application
Introduction
Microservice architecture is one of the most popular way to build and ship modern software applications. If you are more familiar with this architecture, you would have heard of technologies such as docker, Kubernetes and helm charts. Here is a nice video which simply explains how all these different pieces fit in.
Helm is considered the package manager for Kubernetes , a way to manage your manifest yaml files. It provides a way to pass secrets, configuration values to the application. But, in this complex environment with so many pieces of docker, Kubernetes, helm charts, java resources how do we end up passing values and accessing them in the running SpringBoot application? In this article we go step by step providing programming references on passing the values.
The above figure gives an illustration of the how the values flow from definition in helm chart to being finally used in the application.
Step 1: Add the entry to helm chart values
Here we add a feature flag to the values.yml, manifest file. But note that this value would not be sufficient to be accessed in the springboot application, so we define it as a environment variable.
For illustration a feature secret is also passed, this will need to have the secret defined in its separate secrets.yml file, here is an informative answer regarding the same.
// file: values.yml
feature:
enabled: true
..
secret:
data:
feature_secret: {{ .Values.feature.feature_secret | b64enc }}
...
// Add environemnt variable
env:
- name: FEATURE_ENABLED
value: {{ .Values.feature.enabled }}
- name: FEATURE_SECRET
valueFrom:
secretKeyRef:
name: {{ include "application-name.fullname" . }}
key: feature_secret
Step 2: Add entry in application resources
We will now access the environment variable in the application yaml file
// file: application.yml
feature:
enabled: ${FEATURE_ENABLED:false}
secret: ${FEATURE_SECRET:featureSecret}
Step 3: Receive value in configuration properties class
We can then access resources in a Configuration properties class.
// file: FeatureProperties.class
@Data
@RequiredArgsConstructor
@ConstructorBinding
@ConfigurationProperties( prefix = "feature" )
public class FeatureProperties
{
private boolean enabled;
private String secret;
}
Step 4: Access value in application class
Finally we may access the flag in any application class using injected features properties class.
// file: Application.class
@Service
@EnableConfigurationProperties( {FeatureProperties.class} )
public class Application
{
private FeatureProperties featureProperties;
//......
System.out.println(' Feature is enabled? ' + featureProperties.isEnabled() );
}
And that’s it! Now you can use the value in your application.