jsonkuberneteskubernetes-secrets

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


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

Solution

  • 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.