Reputation: 9668
I am setting up my Kubernetes
cluster using kubectl -k
(kustomize). Like any other such arrangement, I depend on some secrets during deployment. The route I want go is to use the secretGenerator
feature of kustomize
to fetch my secrets from files or environment variables.
However managing said files or environment variables in a secure and portable manner has shown itself to be a challenge. Especially since I have 3 separate namespaces for test, stage and production, each requiring a different set of secrets.
So I thought surely there must be a way for me to manage the secrets in my cloud provider's official way (google cloud platform - secret manager).
So how would the secretGenerator
that accesses secrets stored in the secret manager look like?
My naive guess would be something like this:
secretGenerator:
- name: juicy-environment-config
google-secret-resource-id: projects/133713371337/secrets/juicy-test-secret/versions/1
type: some-google-specific-type
Upvotes: 5
Views: 1751
Reputation: 26084
While technically scheduled for deprecation, with kustomize v5.4.1
you can still leverage an exec plugin for this. Here's an example.
Layout:
.
├── base
│ └── secrets
│ ├── kustomization.yaml
│ └── secretGenerator.yaml
└── plugin
└── util
└── gcloudsecretgenerator
└── gcloudSecretGenerator
base/secrets/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generators:
- secretGenerator.yaml
base/secrets/secretGenerator.yaml
apiVersion: util
kind: gcloudSecretGenerator
metadata:
name: whatever
argsOneLiner: |-
secret1 gcloudSecret1Name
secret2 gcloudSecret2Name
plugin/util/gcloudsecretgenerator/gcloudSecretGenerator
#!/bin/bash
# Discard the first argument
secret_data=("${@:2}")
# Loop over input arguments and for every other input look up the secret value
for ((i=1;i< ${#secret_data[@]} ;i+=2));
do
# Get secret and convert to base64
secret_value=$(gcloud secrets versions access latest --secret=${secret_data[$i]} | base64)
secret_data[$i]="$secret_value"
done
# Format secret data properly for interpolation
v=$(printf '"%s" : "%s"\n ' "${secret_data[@]}")
echo "
kind: Secret
apiVersion: v1
metadata:
name: secret
data:
$v
"
The path of this plugin is important. The first folder must match the apiVersion (so in this case util
), the second folder must be the lower case kind (so in this case gcloudsecretgenerator
) and the filename must match the kind (so in this case gcloudSecretGenerator
). Make sure the plugin is executable (chmod +x
)
This plugin parses the arguments that it receives from argsOneLiner
and for every other argument it looks up the secret value from gcloud
using an api call.
To run a build we must use KUSTOMIZE_PLUGIN_HOME
to tell kustomize where to find the plugin:
$ KUSTOMIZE_PLUGIN_HOME="$(pwd)/plugin" kustomize build base/secrets/ --enable-alpha-plugins
apiVersion: v1
data:
secret1: ippZ0USQwwTUfptm....
secret2: ippZ0USQwwTUfptm....
kind: Secret
metadata:
name: secret
Reference: https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins/
Upvotes: 0
Reputation: 1150
There is a Go plugin for this (I helped write it), but plugins weren't supported until more recent versions of Kustomize, so you'll need to install Kustomize directly and run it like kustomize build <path> | kubectl apply -f -
rather than kubectl -k
. This is a good idea anyway IMO since there are a lot of other useful features in newer versions of Kustomize than the one that's built into kubectl.
As seen in the examples, after you've installed the plugin (or you can run it within Docker, see readme) you can define files like the following and commit them to version control:
my-secret.yaml
apiVersion: crd.forgecloud.com/v1
kind: EncryptedSecret
metadata:
name: my-secrets
namespace: default
source: GCP
gcpProjectID: my-gcp-project-id
keys:
- creds.json
- ca.crt
In your kustomization.yaml
you would add
generators:
- my-secret.yaml
and when you run kustomize build
it'll automatically retrive your secret values from Google Secret Manager and output Kubernetes secret
objects.
Upvotes: 1
Reputation: 54221
I'm not aware of a plugin for that. The plugin system in Kustomize is somewhat new (added about 6 months ago) so there aren't a ton in the wild so far, and Secrets Manager is only a few weeks old. You can find docs at https://github.com/kubernetes-sigs/kustomize/tree/master/docs/plugins for writing one though. That links to a few Go plugins for secrets management so you can probably take one of those and rework it to the GCP API.
Upvotes: 2