Home > database >  combining 2 yaml files to generate one values file for helm in terraform
combining 2 yaml files to generate one values file for helm in terraform

Time:06-24

Let us say I have 2 yaml values from 2 different files such as:

lambo.yaml:

    - key: car
      value: "lambo"
      descriptors:
        unit: kmh
        topspeed: 300

toyota.yaml:

    - key: car
      value: "bugatti"
      descriptors:
        unit: kmh
        topspeed: 400

and I want to form a yaml values file to use in a helm chart, such as:

result.yaml:

    domain: supercardomain
    descriptors:
      - key: supercars
        descriptors:
        - key: car
          value: "lambo"
          descriptors:
            unit: kmh
            topspeed: 300
        - key: car
          value: "bugatti"
          descriptors:
            unit: kmh
            topspeed: 400

CONTEXT: I have a helm_release in terraform that needs to have a ConfigMap(k8s) with the exact value as the one above(result.yaml). Merging values files in helm is not possible, and we also want to avoid using any lazy hardcoded methods (such as creating .Values.lambo and .Values.toyota yaml structures and appending them to the configmap helm template).

What I have tried is:

car_descriptor=indent(2, format("car:\ndescriptors:\n%s\n%s", var.lambo_descriptor, var.buggati_descriptor)

with var.<car>_descriptor being a string representation of the car yaml values.

This is then used as a values file by the helm_release:

resource "helm_release" "my_helm_release" {
  name             = "my_helm_release"
  ...

  values = [
    var.car_descriptor
  ]

and then templated into the Configmap like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: car-config
data:
  config.yaml: |
    domain: supercardomain
    descriptors:
    - key: supercars
      descriptors:
{{- if .Values.car.descriptors }}
{{ toYaml .Values.car.descriptors | indent 6 }}
{{- end }}

It works, but I was wondering if there is a simpler and more DRY way to perform this without doing the format and indent stuff, while only using terraform/helm. Also, I would like to not mess with the yaml structure of the 2 car files, or the templating in the Configmap (I have already tried this).

Tips to make this question more concise are also greatly appreciated :)

CodePudding user response:

tree

.
├── Chart.yaml
├── charts
├── data
│   ├── cars
│   │   ├── lambo.yaml
│   │   └── toyota.yaml
│   └── cpus
│       ├── amd.yaml
│       └── intel.yaml
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── configmap.yaml
│   └── deployment.yaml
└── values.yaml

data/cars/lambo.yaml

- key: car
  value: "lambo"
  descriptors:
    unit: kmh
    topspeed: 300

data/cars/toyota.yaml

- key: car
  value: "bugatti"
  descriptors:
    unit: kmh
    topspeed: 400

data/cpus/amd.yaml

- key: cpu
  value: "amd"
  descriptors:
    unit: cps
    topspeed: 20

data/cpus/intel.yaml

- key: cpu
  value: "intel"
  descriptors:
    unit: cps
    topspeed: 10

template/configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: test
data: 
  config.yaml: |
    domain: supercardomain
    descriptors:
    {{- range .Values.car.descriptors }}
      {{- $item := . }}
      - key: {{ .key }}
        descriptors:
        {{- range $path, $_ :=  $.Files.Glob  "data/**" }}
        {{- if eq (dir $path) $item.descripPath }}
        {{- $.Files.Get $path | nindent 10 }}
        {{- end }}
        {{- end }}
    {{- end }}

values.yaml

car:
  domain: supercardomain
  descriptors:
    - key: supercars
      descripPath: data/cars
    - key: cpus
      descripPath: data/cpus

cmd

helm install test .

output

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: test
data: 
  config.yaml: |
    domain: supercardomain
    descriptors:
      - key: supercars
        descriptors:
          - key: car
            value: "lambo"
            descriptors:
              unit: kmh
              topspeed: 300
          - key: car
            value: "bugatti"
            descriptors:
              unit: kmh
              topspeed: 400
      - key: cpus
        descriptors:
          - key: cpu
            value: "amd"
            descriptors:
              unit: cps
              topspeed: 20
          - key: cpu
            value: "intel"
            descriptors:
              unit: cps
              topspeed: 10
  • Related