GO: Dynamically Parsing Environment Variables into Config Structures
Managing configurations through environment variables is a common practice in software development, especially in containerized applications. By parsing environment variables, developers ensure that application configurations can be easily modified without altering the code. In this article, we explore a Go code snippet that dynamically parses environment variables into configuration structures by leveraging the envconfig
and mapstructure
libraries.
Leveraging Struct Field Tags and envconfig
The code snippet below employs struct field tags and envconfig
to parse environment variables into configurations:
type SupportingProducerConfig struct {
ExtraConfigs map[string]string `envconfig:"CONFIGS"`
}
Struct field tags, written as envconfig:"CONFIGS"
, guide the envconfig
library on how to map environment variables to Go struct fields.
When envconfig.Process("SUPPORTING_PRODUCER", &c)
is called, the library constructs the environment variable name by concatenating the provided prefix ("SUPPORTING_PRODUCER") and the name from the struct tag ("CONFIGS"), resulting in SUPPORTING_PRODUCER_CONFIGS
. The value of this environment variable, if set, is assigned to the ExtraConfigs
field of the struct.
The environment variable can be set as follows:
err := os.Setenv("SUPPORTING_PRODUCER_CONFIGS", "bucket_name:dev-tests,prefix_path:dlq,profile_name:dev,bucket_region:us-east-2")
Parsing Nested Configurations with mapstructure
In more complex scenarios, we might have nested configurations or different types of producers, like S3, which have their own set of configurations. This is where mapstructure
comes into play.
type S3Config struct {
BucketName string `mapstructure:"bucket_name"`
PrefixPath string `mapstructure:"prefix_path"`
ProfileName string `mapstructure:"profile_name"`
BucketRegion string `mapstructure:"bucket_region"`
}
Given ExtraConfigs
has key-value pairs of configurations, mapstructure
allows you to decode these pairs into a specified struct. This process is shown in the code snippet below: