tech-blog > ๐Ÿ›  Creating a Laravel APP_KEY automatically in an Helm deployment

๐Ÿ›  Creating a Laravel APP_KEY automatically in an Helm deployment

Kubernetes is hard. Writing a Helm is even harder. But by writing a nice Helm chart, you can ease the work of the people that are going to deploy your application.

In this article, I'll explain how I can simplify the life of our users by automating the creating of a Laravel APP_KEY.

The Laravel APP_KEY

The APP_KEY in Laravel is a crucial part of the application's security and functionality. It serves several important purposes. It is used for encryption, for CSRF protection, for session security and for password resets.

Because of these uses, the APP_KEY is an essential part of a Laravel application's security. It is important that the APP_KEY is kept secret and is a sufficiently strong, random string. If the APP_KEY were to be exposed, it could lead to a compromise of encrypted data and overall application security.

When setting up a new Laravel project, one of the first steps is typically to generate the APP_KEY using the php artisan key:generate command, which automatically generates a secure key and updates the .env file accordingly.

But when deploying in the cloud, especially using a Helm chart, you usually have to generate the APP_KEY out of the cloud, and then set the value in a secret.

We can do better!

Wouldn't it be cool if we could find a way to:

The solution

secret-env-laravel.yaml

                    
                        
{{- $secret := (lookup "v1" "Secret" .Release.Namespace "secret-env-laravel") }}

{{- $appKeyValue := (printf "%s%s" "base64:" (encryptAES (randAlpha 32) "plaintext")) | b64enc }}
{{- if $secret }}
{{- $appKeyValue = index $secret.data "APP_KEY" }}
{{- end -}}
---
kind: Secret
apiVersion: v1
metadata:
  name: secret-env-admin
type: Opaque
data:
  APP_KEY: {{ .Values.app.key | b64enc | default $appKeyValue | quote }}


                    
                

Let's break this down:

An APP_KEY is a AES-256-CBC encoded 32 bytes string.

Our first task is therefore to generate a random 32 bytes string and encode it properly. The encryptAES Helm function does AES-256-CBC encoding. The result is Base64 encoded. That's good because that's what Laravel processes.

The APP_KEY must start with "base64:". So we use the printf function to prepend "base64:".

Finally, in Kubernetes, secrets must be base64 encoded, so we encode the whole result one more time in Base64.

Result:

                    
                        
{{- $appKeyValue := (printf "%s%s" "base64:" (encryptAES (randAlpha 32) "plaintext")) | b64enc }}

                    
                

Now, we need a way to put this value in the secret ONLY if it is not already set in the secret.

For this, we are doing a lookup on the secret.

                    
                        
{{- $secret := (lookup "v1" "Secret" .Release.Namespace "secret-env-laravel") }}

                    
                

This will put in the "$secret" variable the list of all values of the "secret-env-laravel" secret.

Now, we just have to do a simple "if" statement and override the $appKeyValue the APP_KEY if the secret already exists.

                    
                        
{{- if $secret }}
{{- $appKeyValue = index $secret.data "APP_KEY" }}
{{- end -}}

                    
                

Finally, in case the user wants to provide its own APP_KEY, we let him/her do that in the values.yaml file:

                    
                        
  APP_KEY: {{ .Values.app.key | b64enc | default $appKeyValue | quote }}

                    
                

values.yaml:

                    
                        
app:
  # If empty, the Laravel APP_KEY will be autogenerated
  key: ""

                    
                

Instagram logo in the footer of this web page. LinkedIn logo in the footer of this web page. Twitter logo in the footer of this web page. Facebook logo in the footer of this web page. Discord logo in the footer of this web page. YouTube logo in the footer of this web page. GitHub logo in the footer of this web page.

Copyright © 2024 WorkAdventure - All Rights Reserved