How to embed JSON string as the value in a Kubernetes Secret

1/23/2020

Part of our orchestration uses envsubst to update a YAML template file with our desired values.

envsubst < "${SECRET_TEMPLATE}" | kubectl apply -f -

The value for our keyword config is a JSON string:

data=$(jq -c . ${JSON_FILE})

This results in YAML that looks like this (trimmed for brevity):

apiVersion: v1
kind: Secret
metadata:
  name: reporting-config
type: Opaque
data:
  config: {"database": "foo"}

This apparently worked in some earlier versions of Kube, I wanna say 1.8. Anyways, we are running 1.15 and now kubectl interprets this as a map type and complains:

error: error validating "STDIN": error validating data: ValidationError(Secret.data.config): invalid type for io.k8s.api.core.v1.Secret.data: got "map", expected "string"; if you choose to ignore these errors, turn validation off with --validate=false

Is there a trick to doing this now. I've played around with quoting and various places, escaping quotes, and all that jazz and nada.

* update 1 *

Using stringData still results in the same error:

apiVersion: v1
kind: Secret
metadata:
  name: monsoon-storage-reporting-config
type: Opaque
stringData:
  config: {"database": "foo"}
error: error validating "STDIN": error validating data: ValidationError(Secret.stringData.config): invalid type for io.k8s.api.core.v1.Secret.stringData: got "map", expected "string"; if you choose to ignore these errors, turn validation off with --validate=false
-- Crashk1d
json
kubernetes
kubernetes-secrets

1 Answer

1/23/2020

I had to base64 encode the value

$ echo {"database": "foo"} | base64
e2RhdGFiYXNlOiBmb299Cg==

and then use the base64 encoded value in the data: field

apiVersion: v1
kind: Secret
metadata:
  name: reporting-config
type: Opaque
data:
  config: e2RhdGFiYXNlOiBmb299Cg==

Also note this on base64 encoding:

When using the base64 utility on Darwin/macOS users should avoid using the -b option to split long lines. Conversely Linux users should add the option -w 0 to base64 commands or the pipeline base64 | tr -d '\n' if -w option is not available.

-- Jonas
Source: StackOverflow