Setting Go Flags from Environment Variables
Recently, I needed to update a Go program to allow configuration via environment variables. The program already supported configuration using Go’s flag package. I wondered if there was a way to populate flag variables from the environment, in addition to from the command line. It turns out you can using flag.VisitAll, os.LookupEnv, and flag.Set.
func SetFlagsFromEnvironment() (err error) {
flag.VisitAll(func(f *flag.Flag) {
name := strings.ToUpper(strings.Replace(f.Name, "-", "_", -1))
if value, ok := os.LookupEnv(name); ok {
err2 := flag.Set(f.Name, value)
if err2 != nil {
err = fmt.Errorf("failed setting flag from environment: %w", err2)
}
}
})
return
}
The function above iterates over the defined flags using flag.VisitAll and attempts to set their value from the environment using flag.Set. For example, the function above sets -my-flag
from the environment variable MY_FLAG
(if it exists).
I wanted environment variables to be lower priority and get overwritten by command line arguments. I acheived this by calling SetFlagsFromEnvironment() before flag.Parse().
A complete example of this technique is available on The Go Playground.