Ways to inject variables into kubernetes deployment configs using hasura
Tags: devops, kubernetes
Published: 2022-01-21 07:54:04

In this post I want to discuss ways to inject variables into kubernetes deployment condigs.

## Why do you need that?

Well it starts with version control. You certanly dont want to have sensitive information like passwords in your repository.
Or consider different system environments like dev, test, stage or prod. Each of them will have slightly different variables and settings.

## Example

I'm going to use the hasura deployment config used for remotify in this example.

{% gist https://gist.github.com/flodev/882776825b511e5cd2d860aff2c8dfae %}


It has a few variables that have to be replaced depending to which environment the pod will be deployed:

`$HASURA_GRAPHQL_DATABASE_URL`
`$HASURA_GRAPHQL_ADMIN_SECRET`
`$HASURA_GRAPHQL_JWT_SECRET`

To have a complete example I also have the service config for hasura but there are no variables to inject here. Nevertheless I'm going to use it later with helm so here it is:

{% gist https://gist.github.com/flodev/214832600eb79dc3abcbb7d1fd024d42 %}

## Inject variables using envsubst

The first and certainly easiest way is to create env files next to the deployment config and substitute them with the ones used in the deployment config. The folder structure in my case looks the following:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fkeia8dnd4pte4mocpq.png)

The .env file contains the following:

```
export HASURA_GRAPHQL_JWT_SECRET='{"type":"RS256", "key": "super secret key"}'
export HASURA_GRAPHQL_ADMIN_SECRET="super secret admin secret"
export HASURA_GRAPHQL_DATABASE_URL="postgres://postgres:testpassword@postgresql/remotify"
```

Then I navigate to the `hasura` directory using the command line and execute the following command:

`source .env && envsubst < deployment.yaml | kubectl apply -f -` 

And done.


## Create a helm chart

The next method wasn't quite so obvious to me. I was using helm charts before by executing a simple command e.g. for installing a postgres pod. I've never spend a second thought how it works. Under the hood it's very simple and offers exactly what I needed: Configurable kubernetes templates.

Let's get back to our example. I do have the kubernetes config for hasura. Now I want to inject the mentioned variables. 

In order to do that with helm chart navigate to a directory where you plan to create the chart on the command line and execute `helm create hasura`.

![command line create hasura command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwxzn5g8sfzsbh93f4of.png)

Now what the command does is that it creates template files for your deployment.

![folder overview after creating template files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/894qrvruc9vgazic5xzu.png)
 
 
For my example I don't need all of these files. So I'm going to delete all files in the template folder since I have my own configs already:

![folder overview after cleaning up templates folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyc4ecl2nkfyuiowdp14.png)

Next I copy my own hasura configs service.yaml and deployment.yaml into the templates folder.

![Chart folder overview after copying own template files into templates folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvqb81bbl7hg8mg6hrqz.png)
 
Now I declare the variables that I need to inject in the values.yaml
Here is my example values yaml:

{% gist https://gist.github.com/flodev/f89d0766af9173c15064d0e2bdbf5237 %}

Helm uses mustache templates (I guess 🤥) so I cannot let the variables look like in the gist of the deployment yaml on the top. I have to change the deployment variables to the following format:

```yaml
env:
- name: HASURA_GRAPHQL_DATABASE_URL
  value: "{{ .Values.deployment.databaseUrl }}"
- name: HASURA_GRAPHQL_ADMIN_SECRET
  value: "{{ .Values.deployment.adminSecret }}"
- name: HASURA_GRAPHQL_ENABLE_CONSOLE
  value: "true"
- name: HASURA_GRAPHQL_JWT_SECRET
  value: '{{ .Values.deployment.jwt }}'
```

Now I can test the chart using `helm install hasura --dry-run --debug ./hasura` and it will output the successfully replaced configs.
With helm you can also utilise the `--set` parameter so that you override the values in declared in values.yaml

## Fazit

Even though the helm chart method takes a lot more space in this article (which is due to the images ☺️) it's not complicated and I really would always prefer the helm approach over the envsubst. Helm is no magic trick and pretty easy once understood.
Do you now other methods for replacing variables and which would you prefer?