SoFunction
Updated on 2025-03-05

Gradually explain the process of merging yaml files from Golang

There is currently a trend to use environment variables instead of configuration files, mainly to facilitate container deployment, because files require additional file permissions. However, environment variables also have disadvantages, such as the complexity caused by too many lengths and too many, and nesting is also difficult to implement, so configuration files are more suitable at this time.

This article introduces Golang's read and write configuration files and merge configurations to obtain the final configuration information.

Read configuration

First prepare the configuration file:

name: test
image: 
environment:
  os: linux
  group: admin
  user: testAdmin
limits:
  cpu: 4
  memory: 512M

In order to load the configuration, you need to define the structure and tag, which are similar to the json tag:

type Spec struct {
	// Name: name of the function
	Name string `yaml:"name"`
	// Image: docker image name of the function
	Image       string            `yaml:"image"`
	Environment map[string]string `yaml:"environment,omitempty"`
	// Limits for the function
	Limits *FunctionResources `yaml:"limits,omitempty"`
}
// FunctionResources Memory and CPU
type FunctionResources struct {
	Memory string ` yaml:"memory"`
	CPU    string ` yaml:"cpu"`
}

Here we only use yaml instead of json, and the following parsing also uses the Unmarshal interface to generate objects:

import (
    "fmt"
    "os"
	"/yaml.v2"
)
func ReadYaml() {
	bytesOut, err := ("")
	if err != nil {
		panic(err)
	}
	spec := Spec{}
	if err := (bytesOut, &spec); err != nil {
		panic(err)
	}
	("Function name: %s\tImage: %s\tEnvs: %d\n", , ,
		len())
	("Limists: %s, %s\n", , )
}

Output result:

Function name: test    Image:     Envs: 3
Limists: 4, 512M

Write configuration

Write a file. First, use the interface Marshal to serialize the object into a byte array, and then call the os method to write a yaml file:

func WriteYaml() {
	spec := Spec{
		Image: "/functions/figlet:latest",
		Name:  "figlet",
	}
	bytesOut, err := (spec)
	if err != nil {
		panic(err)
	}
	err = ("", bytesOut, )
	if err != nil {
		panic(err)
	}
	("Wrote: . . OK. \n")
}

Running the program successfully generates the file and outputs:

Wrote: . . OK. 

Use the yaml.v2 library to quickly implement configuration file-related work. The following describes how to merge multiple configuration information.

Merge configuration

If the configuration information includes many fields, it may be necessary to maintain an example file and allow the user to provide new values ​​for modification. We can use the merge library to implement the merge function, and of course other libraries can also implement similar functions. This method supports any structure in memory and is not necessarily YAML:

import "/imdario/mergo"
func MergeYaml() {
	base := Spec{
		Image:       "/functions/figlet:latest",
		Name:        "figlet",
		Environment: map[string]string{"stage": "develop"},
		Limits:      &FunctionResources{Memory: "512Mi", CPU: "60Mi"},
	}
	production := Spec{
		Environment: map[string]string{"stage": "production"},
		Limits:      &FunctionResources{Memory: "1Gi", CPU: "100Mi"},
	}
	overrides := []Spec{
		base,
		production,
	}
	merged := Spec{}
	for _, override := range overrides {
		err := (&merged, override, )
		if err != nil {
			panic(err)
		}
	}
	bytesOut, err := (merged)
	if err != nil {
		panic(err)
	}
	("Merged content: \n\n%s\n", string(bytesOut))
}

Run the test output:

Merged content: 

name: figlet
image: /functions/figlet:latest
environment:
  stage: production
limits:
  memory: 1Gi
  cpu: 100Mi

We overwrite the pre-configuration after Merge method specification, and readers can also view other merge methods through the source code.

This is the article about the gradual explanation of the Golang merging yaml file process. For more related content on Golang merging yaml, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!