Use case. Why is this important?
In many environments, being able to set the password to something assumed is important. For example in a training course where we provide instructions, it is cumbersome to have unique passwords for each student's install and have to make them find out what the password is from a secret and then populate it in configuration files like for filebeat, etc.
I've tried work arounds with this. For example the bin/elasticsearch-setup-passwords command does not work from a cluster deployed by the operator which leads me to believe it was already changed. I then try to work around this by changing it with the API:
ES_GENERATED_PASSWORD=$(kubectl get secret es-k8s-logging-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode)
curl -X POST --insecure --user elastic:$ES_GENERATED_PASSWORD https://localhost:30920/_security/user/elastic/_password -H 'Content-Type: application/json' -d '{ "password" : "foobar" }'
However the above does not work because apparently the built-in users are not found and/or allowed to be changed with the API. Below was the error returned from the API:
Validation Failed: 1: user must exist in order to change password;
As you've noticed, it's not currently possible to configure the password of the elastic user. It's defined in the file realm which is managed by the operator internally. The only thing that can currently be done with the elastic user is to reset the password to a new random one by deleting the <cluster-name>-es-elastic-user Secret.
Would using those credentials once to create a new user (in the native realm) work for you? E.g along the lines of:
$ AUTH=elastic:$(kubectl get secret testing-es-elastic-user -o=go-template='{{ .data.elastic | base64decode }}')
$ curl -k -XPOST -u $AUTH https://localhost:9200/_security/user/my-user -H 'Content-Type: application/json' -d '{
"password":"my-password",
"roles":["superuser"]
}'
{"created":true}
$ curl -k -u my-user:my-password https://localhost:9200
{
"name" : "testing-es-2qvmzzn9sl",
"cluster_name" : "testing",
...
"tagline" : "You Know, for Search"
}
Actually it's possible to set the password to a well known value by creating the {clusterName}-es-elastic-user Secret before creating the Elasticsearch resource:
$ kubectl create secret generic testing-es-elastic-user --from-literal=elastic=foobar
secret/testing-es-elastic-user created
$ cat <<'EOFTEST' | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1alpha1
kind: Elasticsearch
metadata:
name: testing
spec:
version: 7.1.0
nodes:
- nodeCount: 1
EOFTEST
elasticsearch.elasticsearch.k8s.elastic.co/testing configured
$ # set up any forwarding you need after the ES pod is done initializing, e.g in another terminal:
$ kubectl port-forward service/testing-es 9200:9200
$ curl -k -u elastic:foobar https://localhost:9200
{
"name" : "testing-es-5ps8sl8sfn",
"cluster_name" : "testing",
...
"tagline" : "You Know, for Search"
}
Thanks to @agup006 for pointing this one out to me.
I would file this under "workaround" for now, and not an officially supported feature.
Wonderful @nkvoll and @agup006, this works great!
This PR has been merged, so in the future after its release we'll be able to specify a custom creation of user & password in a secret file, so that should satisfy your use case.
Most helpful comment
Actually it's possible to set the password to a well known value by creating the
{clusterName}-es-elastic-userSecret before creating the Elasticsearch resource:Thanks to @agup006 for pointing this one out to me.
I would file this under "workaround" for now, and not an officially supported feature.