I am looking for a kubectl command that will list everywhere a secret is referenced.
Example output:
deploymentABC - secretkeyname1
deploymentXYZ - secretkeyname2
statefulset123 - secretkeyname1
I imagine it could access the env.from.secret.name
from the yaml?
For all this complicated queries and if you absolutely want to/only can use kubectl
, you can rely on Go templates support.
First, define the template (e.g. in a file list_secrets.tmpl
).
{{- range .items}}
{{- $namespaceAndName := (printf "%s\t%s/%s" .kind .metadata.namespace .metadata.name)}}
{{- range .spec.template.spec.containers}}
{{- range .envFrom}}
{{- $namespaceAndName}}{{- " - "}}{{- .secretRef.name}}{{- "\n"}}
{{- end}}
{{- end}}
{{- end}}
This iterates over all envFrom
sections of all containers, and display namespace/name - secretRefName
if any.
Then, use that template in kubectl
to format your Deployment
s and StatefulSet
s. You could technically pass the template like this: --o=gotemplate='{{...]}}'
, but I found it rather difficult to read, so I'd rather write it in a separate file (but it's just my opinion).
kubectl get -A deploy,statefulsets -o=go-template-file=list_secrets.tmpl
You should get something like:
Deployment default/app1 - secret1
Deployment default/app2 - secret1
StatefulSet default/app3 - secret1
StatefulSet default/app3 - secret3
From there, you can do whatever you want, some examples of what you can achieve below.
Deployment
s/StatefulSet
s with a particular secretHere, secret1
for example (see {{- if eq .secretRef.name "secret1"}}
to check name equality).
{{- range .items}}
{{- $namespaceAndName := (printf "%s\t%s/%s" .kind .metadata.namespace .metadata.name)}}
{{- range .spec.template.spec.containers}}
{{- range .envFrom}}
{{- if eq .secretRef.name "secret1"}}
{{- $namespaceAndName}}{{- " - "}}{{- .secretRef.name}}{{- "\n"}}
{{- end}}
{{- end}}
{{- end}}
{{- end}}
Here, we have to iterate over volumes rather than containers.
{{- range .items}}
{{- $namespaceAndName := (printf "%s\t%s/%s" .kind .metadata.namespace .metadata.name)}}
{{- range .spec.template.spec.volumes}}
{{- if .secret }}
{{- $namespaceAndName}}{{- " - "}}{{- .secret.secretName}}{{- "\n"}}
{{- end}}
{{- end}}
{{- end}}
This is a mix of the previous solutions; we also add details if the secret is used as env vars or volumes.
{{- range .items}}
{{- $namespaceAndName := (printf "%s\t%s/%s" .kind .metadata.namespace .metadata.name)}}
{{- range .spec.template.spec.containers}}
{{- range .envFrom}}
{{- $namespaceAndName}}{{- " - "}}{{- .secretRef.name}}{{- " (env)\n"}}
{{- end}}
{{- end}}
{{- range .spec.template.spec.volumes}}
{{- if .secret }}
{{- $namespaceAndName}}{{- " - "}}{{- .secret.secretName}}{{- " (volume)\n"}}
{{- end}}
{{- end}}
{{- end}}
This will print:
Deployment default/app1 - secret1 (env)
Deployment default/app1 - secret1 (volume)
Deployment default/app2 - secret1 (env)
StatefulSet default/app3 - secret1 (env)
StatefulSet default/app3 - secret3 (env)