How to do immutability check on helm values? - kubernetes

I have a helm chart which creates namespace and bunch of other Kubernetes resources. I want make sure that user will not be able to change the namespace name once created. I was trying to use JSON schema validation but it cannot compare old and new value. What would be right way to do validate if existing value is changed in the helm values for the existing helm release.

Related

Helm - how to add secrets for subchart from repo?

I installed mongodb chart from bitnami as follows
helm install mongodb bitnami/mongodb
which created this file ./charts/mongodb-10.15.2.tgz
What I do not understand and what I cant find is how to link Secrets to these kind of subcharts. I am aware that values.yaml can override child subcharts. What really confuses me is that this downloaded subchart is just encoded file and I have absolutely no idea how to bend it in terms of deployment/service...
Therefore my question is, how to supply this subchart (of which I dont know anything) with Secrets like dbpassword, dbroot... ? (I hope that the secrets are not supplied via values.yaml override)
When you have sub chart, you map them probably as a dependency (look at the condition carefully, that will match with your values.yaml of the same parent chart.), and here is how you pass the sub-charts values.
Now, I believe you are using this mongodb chart, and in case you want to pass the passwords, you might want to create a k8s secret object and pass the name here.
Now let's say,
There is a chart A and MongoDB is a sub chart of the chart A,
if you add MongoDB as a dependency like this, you can put the configuration/values of chart MongoDB, in A values, just like this.
Now, for the secrets, there is mentioned in the values.yaml of MongoDB, you can create a custom secret and pass the name of the same there, if still not satisfied, you might want to pass the env vars directly to the MongoDB charts values.
and most importantly, when you defining any chart as dependency or sub chart, you would know which chart it is and what are the values it takes,
you can nest the same values in the parent chart.
When you have more time you can spend some here :)

Update helm chart values for different environments

I have helm charts created for a microservice that I have built and everything is working as expected. Now, I have created a new k8s namespace and I want to try to deploy the same helm charts as my old namespace. Although, I have just one value that I need it different while everything else remain the same.
Do I have to create another values.yaml for the new namespace and copy everything over and update the one field I want updated ? Or is there any other way ? I do not want to use the --set method of passing updates to the command line.
David suggested the right way. You can use different values.yaml where you can specify the namespace you want to deploy the chart:
$ helm install -f another-namespace-values.yaml <my-release> .
It's also entirely possible to launch helm chart with multiple values.
For more reading please check values section of helm docs.

How to merge a K8s Configmap to a Secret (or two secrets together)

I am using Helm w/ Kubernetes and am trying to add data that I have in an existing Configmap to an existing secret. The reason for this, is that there is a property on a CRD that I need to set which only takes in a single secret key ref. The existing secret is created by Vault, and the existing Configmap is configured in the Helm chart in plain text. For reasons that I won't get into, we cannot include the content of the configmap into the Vault secret entry, so I MUST be able to merge these two into a secret.
I've tried searching for this, but most answers I see involve creating an initContainer and setting up a volume, but unfortunately I don't think this will work for my situation. I just need a single secret that I can reference in a CRD and problem solved. Is this possible using Kubernetes/Helm?
My fallback plan is to create my own CRD and associated controller to merge the configmap data and the secret's data and basically create a new secret, but it seems like overkill.
As far as I am aware of there is not way to do this in kubernetes.
The only solution that I can see would be to implement some tool yourself. With something like kopf you could implement a simple operator that listen for the creation/update of a specific secret and configmap, get their data and merge it into a new secret.
Using an operator allows you to handle all the cases that might occur during the life of your resources, such as when your new secret is deleted or updated, etc.

How to pass dynamic data to helm subchart

I'm using the mongodb helm chart and the mongo-express one. mongodb generates the name depending on my release name, so it is dynamic. The mongodb service name will be something like my-release-mongodb.
mongo-express requires to pass mongodbServer - the location at which the mongodb can be reached. How can I provide this value to mongo-express if it is generated and can change depending on the release name?
Helm doesn't directly have this ability. (See also helm - programmatically override subchart values.yaml.) It has a couple of ways to propagate configured values from a subchart to a parent but not to use computed values, or to send these values to a sibling chart.
In the particular case of Services created by a subchart, I've generally considered the Service name as part of the chart's "API": you know the Service will be named {{ .Release.Name }}-mongodb and you just have to hard-code that in the consuming chart.
If you're launching this under a single "umbrella" chart, this is a little more straightforward. Both parts have the same release name, so you can construct the service name the same way. (Umbrella charts have other limitations – if you have multiple services that each should have an independent MongoDB installation, Helm will only deploy the database once for the whole umbrella chart – but you can still hit this same problem making HTTP calls between microservices.)
If they're totally separate installations, you may need to pick the release name yourself and pass it in as a value.
helm install thedb ./mongodb
helm install theapp ./mongo-express --set serviceName=thedb-mongodb
This also a place where a still higher-level tool like Helmfile or Helmsman can come in handy, since that would let you specify these parameters in a fixed file.

Whats the best way for stage-specific K8s config?

Let's say we have to manage a database connection string for stages test, int and prod.
What are the patterns here for Kubernetes?
I would handle general configuration via ConfigMaps. Create configuration for each environment and have your pods/deployment consume the values via environment variables.
This approach allows you to decouple your configuration from your k8 object definition and gives the ability to inject the required config per environment.
For sensitive data, which might include a username and password in a connection string for example, consider using Secrets instead.
The best way in my experience is to use a higher level construct like Helm Chart. This way you manage all your manifests in platform agnostic way and make them configurable during chart install/update.
That way you can use both ConfigMaps, Secrets or env vars, and populate them from values set during install/upgrade. With helm, you would do it somewhat like this :
helm install -f values.yaml : where values yaml contains all your non-default values (ie. db password)
helm upgrade <release> --reuse-values --set image.tag=1.0.1 to say release a new version keeping all other values defined during initial install.
For non-default components like ie. development database, you can use value like devdb.enabled with a default value to false and set it to true only on dev env where you want to launch devdb pod and point your database service there (all the logic for it within manifest templates in helm chart)