-
Notifications
You must be signed in to change notification settings - Fork 519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document solution to problem of random passwords change on upgrade (from helm/charts) #1259
Comments
When I became a maintainer I learned it was best practice to auto-generate passwords and have told folks to follow this pattern. I never really questioned this but am not really happy about it either. I appreciate you brought up the discussion. Auto-generating passwords is kind of nice. It makes it easy to get started and is certainly better than a hard-coded password. But for a real-world installation, I wouldn't rely on this. So, we need at least better documentation. Thinking about it again, wouldn't it be better not to provide a default password at all? We could use the |
cc @kubernetes/charts-maintainers |
This is indeed a problem. Currently I'm overcoming this by specifying a value with I tend to save charts on git repositories but without the password. Ideally I neither want to:
A way to automate 3 in a K8S/Helm way would go a long way. |
e.g. it could be useful to add an annotation that prevents updating of a secret like this:
Except this only works for preventing deletion. |
I had the same problem. You can create a secret only on install by using a |
I think the issue is not feeding back secrets into a chart upgrade, nor a problem with generating passwords. I think the issue is that if a chart is generating a random password, it should not overwrite an existing secret. This seems like it should use the following wrapper around the secret definition: {{- if or .Values.somePassword .Release.IsInstall}}
apiVersion: v1
kind: Secret
...
data:
{{- if .Values.somePassword }}
some-password: {{ .Values.somePassword | b64enc | quote }}
{{- else }}
some-password: {{ randAlphaNum 10 | b64enc | quote }}
{{- end }}
{{- end}} Thoughts? |
@michaelfig I like this, either we explicitly specify the password, or we autogenerate it during an install. Does this work? (i.e. Have you tried running this to check that it does not entirely delete the secret during an update when not finding the secret template?) |
Tried it myself just now, alas Helm will simply wipe out the secret. |
The service is writing password to the secrets. Maybe it will be better to check first for existence and use old if a secret has a value already. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions. |
Is there any progress on setting up a way for random secrets to not be reset implicitly during upgrades? |
From the dev call, one possible solution to try would be through an install hook that writes out a configmap. |
That or checking for the presence of |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions. |
Any update? |
This is pretty annoying, especially with things like Jenkins and Grafana, you're constantly looking up the new password on upgrades. |
@arianitu Since Grafana is usually a not mission-critical component, a workaround is to add an annotation to the deployment's |
Hi all!
Any advice pls! |
Solve this quiz with pre-install hook that check if secret exist |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions. |
/remove stale |
Any progress? |
I'm curious, @bacongobbler, whether any of the work in Helm 3 will resolve or at least provide a direct workaround to this. thots? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions. |
This issue is still relevant |
There has been some discussion here : helm/charts#10400 |
My opinion: The problem is NOT only for randomly generated passwords in helm charts. Even for not random passwords, you need to always pass proper |
Hey @squillace, this is just an issue that nobody has documented a working convention in chart development. Helm 3 won't solve this issue necessarily. Has anyone tried the suggestions made here? If so, does that solve the issue? |
@bacongobbler I have a working, backward-compatible convention that relies on Helm PR helm/charts#5290 As per the documentation in the PR, you can just do the following to an existing chart, and it will just work, even for people who upgrade an existing installation: apiVersion: v1
kind: Secret
metadata:
name: {{ template "helm-random-secret.fullname" . }}
{{- if not .Values.somePassword }}
annotations:
"helm.sh/resource-policy": no-upgrade-existing
{{- end }}
labels:
app: {{ template "helm-random-secret.name" . }}
chart: {{ template "helm-random-secret.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
{{- if .Values.somePassword }}
some-password: {{ .Values.somePassword | b64enc | quote }}
{{- else }}
some-password: {{ randAlphaNum 10 | b64enc | quote }}
{{- end }} The semantics are: # Use a specific password.
# If omitted, will use existing password otherwise generate a new random one.
# somePassword: "my Pas$w0rd" Thoughts? |
Dropped a comment in that PR. Let's continue the discussion on that particular feature over there. |
This is a workaround for https://github.com/helm/charts/issues/5167. Please set a proper password in production.
This might be a useful workaround. With helm 3.1 there is a lookup function,
edit:
Then elsewhere in secret
|
Here is an alternative (requires Helm v3) to tahmmee's solution, in which the generated values are stored in template variables and if the resource already exists, the existing values are used:
|
Please let's have it fixed. It's ok to use workaround for in-house charts, not for 3rd party dependency though. |
@herrberk Any ideas for rendering |
Hi I've rewritten kubernetes replicator and added some annotations to deal with this kind of problems: https://github.com/olli-ai/k8s-replicator#use-random-password-generated-by-an-helm-chart Now can generate a random password with helm, and replicate it only once to another secret thus it won't be change by helm in the future. apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: admin-password-source
annotations:
k8s-replicator/replicate-to: "admin-password"
k8s-replicator/replicate-once: "true"
stringData:
password: {{ randAlphaNum 64 | quote }} Hope it will help people. |
From helm 3.1.0 you should be able to use the lookup function to read a previously created random.password from kubernetes: https://helm.sh/docs/chart_template_guide/functions_and_pipelines/ |
How can it work, if the docs state, that:
so exaclty in the cases where that values would be used? |
If you use this trick from |
@jglick this would still show a diff when using the |
Wouldn't a new value for
This will allow you to specify the following
|
As a solution, I've created the following template:
Then you can simply configure secrets like:
|
That works great @iTaybb ! I have a suggestion to improve it a bit so you can still change the contents of the secret in the future:
By checking if I know this wouldn't work if you have empty data in your secrets, but in my case that's not a problem. |
this was my solution for this problem.
then, I created my own secret as the following:
EDIT: I had a requirement to give the
And it works! It seems to me that the string value - |
@saharhagbi , thanks, it works. |
Same issue here. I resolved it by rolling back to previous release using helm and getting the old password out. Then i upgraded my helm kong release again with this password. And this worked. I used kong helm chart from bitnami and here is the solution mentioned in there articles https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/ |
Since 1.21 Kubernetes provides an option to set individual Secrets and ConfigMaps as immutable: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable. Can it be a solution? |
What will happen if Helm will try to delete or modify such immutable secret? If the request will be gently ignored, it would be the solution. |
Did you check it locally? |
My workaround is to combine lookup and resource-policy/keep
Now on first deployment the secret is created. On upgrade the secret is not charted and is marked to be deleted, but the resource policy prevents it. |
@eoneoff I think the idiom shown in #1259 (comment) is preferable in general, as it ensures that other changes to the |
How about a pattern similar to this where a password definition in _helpers.tpl can be referenced multiple times but yields the same random password in an upgrade safe way? `{{/* apiVersion: v1 apiVersion: v1 |
I have cobbled together a solution from a couple different solutions. My use case:
First you create a function to generate static passwords. This has the neat property of creating a different random password per Release.Name, though of course you could get more granular with it. Props to https://stackoverflow.com/a/75723185/3760330 for the random password generator function: {{- define "generate_static_password" -}}
{{- /* Create "tmp_vars" dict inside ".Release" to store various stuff. */ -}}
{{- if not (index .Release "tmp_vars") -}}
{{- $_ := set .Release "tmp_vars" dict -}}
{{- end -}}
{{- /* Some random ID of this password, in case there will be other random values alongside this instance. */ -}}
{{- $key := printf "%s_%s" .Release.Name "password" -}}
{{- /* If $key does not yet exist in .Release.tmp_vars, then... */ -}}
{{- if not (index .Release.tmp_vars $key) -}}
{{- /* ... store random password under the $key */ -}}
{{- $_ := set .Release.tmp_vars $key (randAlphaNum 20) -}}
{{- end -}}
{{- /* Retrieve previously generated value. */ -}}
{{- index .Release.tmp_vars $key -}}
{{- end -}} Next you create a function that will try to lookup the value in the K8s secret on upgrade. If it's not an upgrade (assume it's install) it requires two values, which are the name of the secret to create, and the key to store the password as in the secret. Note that lookup() returns an empty state on template or dry-run, so this solution creates a default dict to avoid errors. {{- define "random_pw_reusable" -}}
{{- if .Release.IsUpgrade -}}
{{- $data := default dict (lookup "v1" "Secret" .Release.Namespace .Values.random_pw_secret_name).data -}}
{{- if $data -}}
{{- index $data .Values.random_pw_secret_key | b64dec -}}
{{- end -}}
{{- else -}}
{{- if and (required "You must pass .Values.random_pw_secret_name (the name of a secret to retrieve password from on upgrade)" .Values.random_pw_secret_name) (required "You must pass .Values.random_pw_secret_key (the name of the key in the secret to retrieve password from on upgrade)" .Values.random_pw_secret_key) -}}
{{- (include "generate_static_password" .) -}}
{{- end -}}
{{- end -}}
{{- end -}} Finally you create your secret: ---
apiVersion: v1
kind: Secret
metadata:
name: "{{ .Values.random_pw_secret_name }}"
namespace: "{{ .Release.Namespace }}"
type: Opaque
{{- if .Values.secretData -}}
data:
{{- range $k, $v := .Values.secretData }}
"{{ $k }}": "{{ tpl $v $ | b64enc }}"
{{- end }}
{{- end -}}
random_pw_secret_name: db-credentials
random_pw_secret_key: DB_PASSWORD
secretData:
DB_HOST: db
DB_NAME: mydatabase
DB_USER: postgres
DB_PASSWORD: '{{- include "random_pw_reusable" . -}}'
DB_CONNECTION_STRING: 'postgresql://postgres:{{- include "random_pw_reusable" . -}}@db:5432/mydatabase' As you can see, a new secret will be created with a set of KEY=VALUE pairs. Both In this way you can deploy Postgres at install time with a random password, upgrade it and retain the same password, and rotate the password at any time (outside of Helm) yet still retain that rotated password. Resources are managed as normal so a delete/uninstall will work fine. I suppose the only problem is if the secret gets deleted, this won't create a new random password... |
I was replying in helm/charts#3591 and realized this is a much bigger problem that deserves a charts issue to decide whether we should agree on and document a policy for this across charts.
Can we address this at one of the next charts meetings?
Related:
The text was updated successfully, but these errors were encountered: