Last active
July 26, 2024 07:09
-
-
Save foogunlana/b75175b4ff62bc07258ea78274c698cd to your computer and use it in GitHub Desktop.
Helm + Sealed secrets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I had a bit of trouble figuring out how to use bitnami's [sealed secrets](https://github.com/bitnami-labs/sealed-secrets) with [helm](https://helm.sh) | |
Here's a definition of done to help you see what I was trying to achieve. | |
**Definition of done** | |
- Single secret available for a release in a namespace, listing all secret variables | |
- Regular helm workflow, with no extra kubeseal commands for developers | |
- Encrypted secrets clearly visible in git | |
- Sealedsecret managed by helm | |
After much suffering, here's what I came up with. A pre-commit hook that creates the single sealedsecret in my chart. | |
It took me a while, so I thought I should share in case someone can improve it. | |
app/templates/sealedsecret.yml -> | |
```yml | |
apiVersion: bitnami.com/v1alpha1 | |
kind: SealedSecret | |
metadata: | |
name: {{ include "app.fullname" . }} | |
labels: | |
... | |
spec: | |
encryptedData: | |
{{- range $key, $val := .Values.secret }} | |
{{ $key }}: {{ $val | quote }} | |
{{- end }} | |
``` | |
./env/ci.values.yml -> | |
```yml | |
... | |
env: | |
... | |
NODE_ENV: production | |
AWS_BUCKET: xyz | |
``` | |
./env/ci.secrets.yml -> | |
```yml | |
... | |
AWS_ACCESS_KEY_ID: abc123 | |
AWS_SECRET_ACCESS_KEY: xyz | |
``` | |
Pre-commit hook -> | |
```bash | |
#!/bin/bash | |
# use bash, as echo -n does not work in #!/bin/sh | |
# dependencies | |
# - yq : read secrets.yml | |
# - kubeseal : encrypt secrets with kubernetes cluster sealed secrets public key | |
set -e | |
encrypt() { | |
# the full name of the app - {release}-{chart} or just {release} | |
fullname="YOUR APP FULL NAME" | |
# the top level yaml key for secrets in the values.yml file | |
secret_prefix="secret" | |
# the name and namespace of the sealed secrets controller after installation to the cluster | |
controller_name="sealed-secrets" | |
controller_namespace="default" | |
# find namespace specific values and secrets files, and a temporary file for storing intermediate values | |
namespace=${1} | |
secrets_file=${GIT_DIR:-$PWD}/env/${namespace}.secrets.yml | |
values_file=${GIT_DIR:-$PWD}/env/${namespace}.values.yml | |
tmp_secret_file=${GIT_DIR:-$PWD}/env/tmpsecretfile | |
if [[ ! -f "$secrets_file" ]]; then | |
echo "No secrets to encrypt in $secrets. Skipping..." | |
return | |
fi | |
# get all secret key names | |
keys=$(yq r -j $secrets_file | jq -r 'keys[]') | |
# count keys, and strip whitespace | |
nkeys=$(wc -w <<<$keys | sed 's/ //g') | |
echo "Encrypting $nkeys secrets from $secrets..." | |
# we will write each key to the values file | |
for key in $keys; do | |
# echo with -n to file first, otherwise you might have a trailing new line in your decrypted value | |
echo -n $(yq r $secrets_file $key) >${tmp_secret_file} | |
# --name should match the name of the sealedsecret (data-platform.fullname from _helpers.tpl) | |
encrypted=$(kubeseal --raw --name=${fullname} --namespace=${namespace} --from-file=${tmp_secret_file} --controller-name=${controller_name} --controller-namespace=${controller_namespace}) | |
rm ${tmp_secret_file} | |
# write the secret to the values file | |
yq w -i $values_file "$secret_prefix.$key" $encrypted | |
done | |
echo "Successfully wrote ciphertext to $values." | |
} | |
encrypt ci | |
encrypt qa | |
encrypt prod | |
git add env | |
``` | |
The folder structure is as follows: | |
app/templates/sealedsecret.yml | |
env/ci.values.yml | |
env/ci.secrets.yml | |
After running `git commit`, the `env/ci.values.yml` file is now as follows | |
```yml | |
env: | |
... | |
NODE_ENV: production | |
AWS_BUCKET: xyz | |
secret: | |
AWS_ACCESS_KEY_ID: ...encrypted data | |
AWS_SECRET_ACCESS_KEY: ...encrypted data | |
``` | |
Make sure to add env/*.secrets.yml to your .gitignore! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thx! Might add the
.md
extension, so markup will get parsed?