When managing secrets in argocd, I encode the value in argocd-secret with base64 and set it to manifest.
In that case, although I use kusotomize, build and apply it, secret encoded by base64 will be encoded to base64 further.
$ echo -n "clientid" | base64
Y2xpZW50aWQ=
$ echo -n "clientsecret" | base64
Y2xpZW50c2VjcmV0
---
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
type: Opaque
stringData:
dex.github.clientID: Y2xpZW50aWQ=
dex.github.clientSecret: Y2xpZW50c2VjcmV0
If you use kustomize build to build and check the difference, it looks like this
$ kustomize build --load_restrictor none overlays/dev/ap-northeast-1/argocd | k diff -f -
+ dex.github.clientID: WTJ4cFpXNTBhV1E9
+ dex.github.clientSecret: WTJ4cFpXNTBjMlZqY21WMA==
I don't understand why something encoded by base64 is encoded further. I'm going to ask for someone's help.
Thanks.
I reproduced your case and it looks like it isn't further encoded by kustomize but by kubectl (either by kubectl
client itself or by kube-apiserver
performing the operation requested by e.g. kubectl apply
command).
And here you can find a fragment that sheds some light on why this is actually happening:
The Secret contains two maps:
data
andstringData
. Thedata
field is used to store arbitrary data, encoded using base64. ThestringData
field is provided for convenience, and allows you to provide secret data as unencoded strings.
The data
field serves for storing the data already encoded using base64 and value of this field isn't further encoded when we apply the Secret
. The stringData
however behaves quite differently. It allows you to provide secret data as unencoded strings and for that reason it is further encoded when you run kubectl apply
. In your example you use stringData
field and although it contains already encoded data, it is treated as any other string and in consequence is encoded again.
Solution: simply use data
rather than stringData
map in your Secret
and your base64 encoded strings won't be encoded again during the resource creation.
It's actually secret controller who encodes the string. So, you can't pass an encoded string into a yaml. You need to leave it in plain text:
$ echo -n demo | base64
ZGVtbw==
$ echo -n ZGVtbw== | base64
WkdWdGJ3PT0=
$ kubectl create secret generic demo --from-literal=key=demo
secret/demo created
$ kubectl create secret generic demo2 --from-literal=key=ZGVtbw==
secret/demo2 created
$ kubectl get secret demo demo2 -oyaml
apiVersion: v1
items:
- apiVersion: v1
data:
key: ZGVtbw== <- word demo got encoded
kind: Secret
metadata:
creationTimestamp: "2020-06-04T13:41:27Z"
name: demo
namespace: default
resourceVersion: "10118413"
selfLink: /api/v1/namespaces/default/secrets/demo
uid: bc39444c-e4f6-43ba-b151-705e15811831
type: Opaque
- apiVersion: v1
data:
key: WkdWdGJ3PT0= <- encoded string of demo got encoded further
kind: Secret
metadata:
creationTimestamp: "2020-06-04T13:41:47Z"
name: demo2
namespace: default
resourceVersion: "10118469"
selfLink: /api/v1/namespaces/default/secrets/demo2
uid: 2fe63343-06b4-4f47-94cd-9fe8e12fb388
type: Opaque
kind: List
metadata:
resourceVersion: ""
selfLink: ""
Note: this was not always like that. And it can actually change again. Back in the days, you had to encode it, then you must not, then again...