Spring Cloud Vault support in Spring Cloud Data Flow 2.10.0 - spring

I am running Spring Cloud Dataflow on Kubernetes runtime.
Currently, I am using K8 secrets to manage secrets for the dataflow server, and skipper server. Going forward I want to use Spring Cloud Vault as a secrets manager.
Is there any support to configure vault secrets in dataflow and skipper servers?
SCDF Version: springcloud/spring-cloud-dataflow-server:2.10.0
Skipper Version: springcloud/spring-cloud-skipper-server:2.9.0
I enabled following configuration in
application.yaml
vault:
enabled: true
authentication: KUBERNETES
uri: http://<vault_host>
backend: secret
application-name: scdf-server
kubernetes:
role: internal-app
bootstrap.yaml
spring:
application:
name: scdf-server
I was expecting scdf-server to inject secrets from the vault kV backend, but it seems it's not activating the vault config.

Spring Cloud Vault isn't in the classpath of the standard build.
You can follow these instructions to add jar files to the containers.

Related

Best practices for storing passwords when using Spring Boot

We are working on a Java Spring Boot application, that needs access to a database, the password is stored on the application.properties file.
Our main issue is that the passwords might be viewable when uploaded to GitLab/GitHub.
I found that we can use Jasypt to encrypt the data, but from what I read, I need to use the decryption key on the execution, which is also stored on Git, in order to be deployed using Kubernates.
Is there some way to secure our passwords in such a case? We are using AWS if that makes any difference, and we are trying to use the EKS service, but until now we have had a VM with K8s installed.
Do not store passwords in application.properties as you mention is insecure but also you may have a different version of your application (dev, staging, prod) which will use different databases and different passwords.
What you can do in this case is maintain the password empty in source files and externalize this configuration, i.e you can use an environment variable in your k8 deployment file or VM that the application will be run, spring boot will load it as property value if they have the right format. From spring documentation:
Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use a variety of external configuration sources, include Java properties files, YAML files, environment variables, and command-line arguments.
You should use environment variables in your application.properties file for this:
spring.datasource.username=${SPRING_DATASOURCE_USERNAME}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
Or with a default value (for development):
spring.datasource.username=${SPRING_DATASOURCE_USERNAME:admin}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:admin}
Then you can add a Kubernetes Secret to your namespace:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: mynamespace
data:
SPRING_DATASOURCE_PASSWORD: YWRtaW4=
SPRING_DATASOURCE_USERNAME: YWRtaW4=
And assign it to your Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment
spec:
# omitted...
containers:
- name: mycontainer
envFrom:
- secretRef:
name: mysecret
- configMapRef:
name: myconfigmap
# omitted...
Another alternative would be to store the entire application.properties file in your Secret or ConfigMap and mount it into your container as a file.
Both scenarios are explained in further detail here:
https://developers.redhat.com/blog/2017/10/03/configuring-spring-boot-kubernetes-configmap

Fetch multiple secrets using spring-cloud-aws-secrets-manager-config module

I am integrating the spring-cloud-aws-secrets-manager-config module with my SpringBoot application to fetch secrets from AWS Secrets Manager.
I have following two secrets in AWS Secrets Manager.
/myapp/dbcredentials
/myapp/apikey
Now, with bootstrap.yml, I am able to fetch either of these two secrets. Not both.
bootstrap.yml
aws:
secretsmanager:
prefix: /myapp
defaultContext: application
profileSeparator: _
failFast: false
name: dbcredentials
enabled: true
What will be the configuration in bootstrap.yml to fetch both the secrets?
Starting from Spring cloud AWS 2.3, spring.config.import could be used to load more than one secrets
spring.config.import=aws-secretsmanager:secret-key;other-secret-key
https://docs.awspring.io/spring-cloud-aws/docs/2.3.0/reference/html/index.html#integrating-your-spring-cloud-application-with-the-aws-secrets-manager
Hope this helps !

passing application configuration using K8s configmaps

How to pass in the application.properties to the Spring boot application using configmaps. Since the application.yml file contains sensitive information, this requires to pass in secrets and configmaps. In this case what options do we have to pass in both the sensitive and non-sensitive configuration data to the Spring boot pod.
I am currently using Spring cloud config server and Spring cloud config server can encrypt the sensitive data using the encrypt.key and decrypt the key.
ConfigMaps as described by #paltaa would do the trick for non-sensitive information. For sensitive information I would use a sealedSecret.
Sealed Secrets is composed of two parts:
A cluster-side controller / operator
A client-side utility: kubeseal
The kubeseal utility uses asymmetric crypto to encrypt secrets that only the controller can decrypt.
These encrypted secrets are encoded in a SealedSecret resource, which you can see as a recipe for creating a secret.
Once installed you create your secret as normal and you can then:
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml
You can safely push your sealedSecret to github etc.
This normal kubernetes secret will appear in the cluster after a few seconds and you can use it as you would use any secret that you would have created directly (e.g. reference it from a Pod).
You can mount Secret as volumes, the same as ConfigMaps. For example:
Create the secret.
kubectl create secret generic ssh-key-secret --from-file=application.properties
Then mount it as volume:
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: mySshImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
More information in https://kubernetes.io/docs/concepts/configuration/secret/

Disable Spring cloud server in spring boot 2.0.0

For one of our customer, who is using Spring Boot version 2.0.0 Release, we have Spring cloud config server with native settings. For local development, we want to disable spring cloud config server so that other spring boot micro-services can use application-local.yml settings.
I tried below options but its not working
Setting spring.cloud.config.enabled=false in bootstrap.yml file
Setting -Dspring.profiles.active="local"
When I run the micro-services, it is still looking for config server. Any inputs.
Can not remove the dependency of config-starter reference in gradle file as a workaround
These are the configurations that worked for me. I'm using Eureka service to find where the config server is.
spring:
cloud:
config:
enabled: false
discovery:
enabled: false
eureka:
client:
enabled: false
to run the local service without loading props from any remote config server you need to disable the bootstrap file and config.
resources/bootstrap.yml --> resources/application.yml
with this springboot will load your application.yml by default.

Access NFS volume mounts from Spring Boot application Kubernetes

I have added a NFS volume mount to my Spring Boot container running on Kubernetes. Below is my deployment file for Kubernetes.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ldap
spec:
replicas: 3
spec:
serviceAccountName: xxx-staging-take-poc-admin
volumes:
- name: nfs-volume
nfs:
server: 10.xxx.xxx.xxx
path: /ifs/standard/take1-poc
containers:
-
image: image-id
volumeMounts:
- name: nfs-volume
mountPath: /var/nfs
name: ldap
How do I access the mount path from my Spring Boot application to achieve file read and write.
If I understand you correctly you can pass external info to sprint boot application through environment variables. Here is an article with more detailed info of how to do it.
Kubernetes ConfigMaps also allows us to load a file as a ConfigMap
property. That gives us an interesting option of loading the Spring
Boot application.properties via Kubernetes ConfigMaps.
Also, you may want to get familiar with this documentation. It shows how to reference secrets which are also mounted so you may find it helpful in your case.
The Spring Cloud Kubernetes plug-in implements the integration between
Kubernetes and Spring Boot. In principle, you could access the
configuration data from a ConfigMap using the Kubernetes API.
Please let me know if that helped.

Resources