Home > Enterprise >  How to parse a JSON secret to YAML in Vault?
How to parse a JSON secret to YAML in Vault?

Time:10-06

I have a secret in Vault which is really a "complex" structure of JSON, meaning it's not just a key/value but there are several keys at different sublevels.

I need to somehow get this secret and convert it to the YAML representation of that JSON. If it was a simple structure (like several k/v at the same level), I could use something as simple as

      {{- with secret "secret/foo" -}}
          {{ range $k, $v := .Data.data }}
            {{ $k }}: {{ $v }}
          {{- end }}
      {{- end }}

however, as this is not the case, and the structure of the JSON is complex, trying to come up with a template is rather impossible.

However, I found that Vault uses Consul templates, and Consul has a parseYAML function, so my question is, how can I template this so that I get all the content of .Data.data and translate it into YAML?

I have tried several approaches similar to this one below:

{{- with secret "secret/foo" -}}
{{ .Data.data| parseYAML }}
{{- end }}

but I'm always getting the same error wrong type for value; expected string; got map[string]interface {}"

UPDATE

Sample yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
      annotations:
        vault.hashicorp.com/agent-inject: 'true'
        vault.hashicorp.com/agent-inject-secret-foo: 'secret/foo'
        vault.hashicorp.com/agent-inject-template-secret-foo: |
          {{- with secret "secret/foo" -}}
          {{ .Data.data| parseYAML }}
          {{- end }}
        vault.hashicorp.com/role: 'app'
    spec:
      containers:
        - name: app
          image: 'app:1.0.0'
      serviceAccountName: app

where secret/foo is a long JSON with no clear structure. A random example (actual JSON is about 300 lines I think).

{
  "a": {
    "a": "a",
    "b": "b",
    "c": {
      "a": "a",
      "b": {
        "c": "c"
      },
      "d": "a"
    },
    "e": {
      "a": {
        "b": {
          "c": {
            "a": "a",
            "b": "b"
          }
        }
      }
    }
  }
}

CodePudding user response:

Ok, just figure this out.

{{- with secret "secret/foo" -}}
{{ .Data.data| parseYAML }}
{{- end }}

this is correct, but instead of parseYAML the right function is toYAML.

  • Related