· 3分で読了

プロジェクトに環境変数を設定する - VIPER

この記事は中国語から自動翻訳されたものです。翻訳によりニュアンスが失われている場合があります。

数ヶ月前、Golang で環境変数を設定する方法についての記事を書いた。環境変数をいかにエレガントに設定するかは非常に重要なことであり、そのため簡単な関数を自作して対応した。

当時の考えはシンプルで、対応する config ファイルがあれば、その中の key/value を os.Setenv で設定する。その後はアプリ全体で、直接 os.Getenv を使って値を取得できるようにするというものだった。

だが、いざ本番環境にデプロイするとなると、いくつかの問題に直面することになる:

  • 設定ファイルが yaml とは限らず、他のフォーマットの場合もある
  • 外部サービス(Consul、etcd など)から環境変数を注入したい場合があるが、現状の実装では os.Getenv を前提としている
  • 異なるパスから設定ファイルを読み込めるようにしたい
  • コマンドライン引数から変数を設定できるようにしたい
  • さらに多くの予期せぬ問題

小規模なプロジェクトであればこれで僕の課題は解決できたが、より柔軟な設定方法が必要になると、これだけでは不十分だ。

そして上記の問題に対して、Golang にはすでに Viper という成熟したソリューションが存在する。

VIPER

VIPER は非常に強力な環境設定パッケージだ。以下のような機能をサポートしている:

  • デフォルト値の設定
  • 様々なフォーマットの設定ファイルのサポート(json、toml、yaml)
  • 設定ファイルの変更監視(サーバーを再起動する必要がなくなる!)
  • リモートサーバーからの変数取得(例:consul や etcd)
  • コマンドラインの flag による変数取得
  • reader からの変数取得(異なるソースから設定を注入できることを意味する)

基本的な使い方

まずは go get や mod を使って VIPER をダウンロードする。

go get github.com/spf13/viper

func main() {
  viper.SetDefault("AWS_ACCESS_TOKEN", "AWS123456789") // 設定預設值
	viper.SetConfigName("config") // 指定 config 的檔名
	viper.AddConfigPath("./config")
	viper.ReadInConfig()
	viper.AutomaticEnv()
}
  • SetDefault(key, value):デフォルト値を設定する
  • SetConfigName(name):config のファイル名を設定する。例えば設定ファイルが config.yml の場合は config と指定する。なぜ拡張子を指定しなくていいのかというと、Viper が自動的に処理してくれるからだ。
  • AddConfigPath:複数のフォルダ(探索パス)を設定できる
  • ReadInConfig:これを呼び出すのを忘れないこと。実際に設定を読み込む処理だ
  • AutomaticEnv:ENV の変数を Viper 内に自動で同期する

Viper は設定を容易にするための関数を他にも多数提供している。

変数の取得

変数を設定した後は、viper.Get を使って読み取ることができる。Get が返すのは interface{} だが、Viper は viper.GetString、viper.GetDuration、viper.GetStringMap など、数多くの型変換メソッドも提供している。

func main() {
	fmt.Println(viper.GetString("AWS_ACCESS_TOKEN"))
  fmt.Println(viper.GetUint32("YOUR_INT"))
  fmt.Println(viper.GetTime("YOUR_TIME"))
}

まとめ

環境設定は難しいといえば難しく、簡単といえば簡単だが、考慮すべきことは想像以上に多い。そして VIPER は、よくあるユースケースの多くを肩代わりして処理してくれる。

また、特に注意すべき点として、access token や secret key などを設定する際は、コミット時に誤って GitHub にプッシュして取り返しのつかない事態にならないよう、必ず .gitignore に追加しておくことを忘れないでほしい。

関連記事

他のトピックを探索