🌤️
GAEのapp.yamlのenv_variablsをローカル環境で使い回したかった
背景
本番とステージングをGAEで運用してるnodeのアプリケーションで、環境ごとにコード変更したくないので、アプリケーションコードでは環境変数を参照するようにして、app.yamlを環境毎に用意、env_variables
を定義してデプロイ時に設定されるようにしてた。
ステージング用
runtime: nodejs12
instance_class: F2
env_variables:
BUCKET_NAME: "staging-gcs-bucket"
本番用
runtime: nodejs12
instance_class: F4
env_variables:
BUCKET_NAME: "production-gcs-bucket"
みたいな。
それは良いけど困ったゾイ
GAEにデプロイする分には何も考えなくていいのでパラメータ指定を間違えることはないものの、同じコードをローカルやDockerコンテナ内で動かそうとしたときに、いちいちexport BUCKET_NAME=xxx
とかしたりしてめんどくさいなぁって思ってた。JSONみたいなエスケープしないといけないパラメータだとかなり辛い。
app.yamlやstaging.yamlをそのまま使えるようにする
辛かったので素直にアプリケーションコードの先頭でyamlを読んで環境変数を上書きするようにした。
app.js
async function setEnvVariablesFromYaml(filename){
const jsYaml = require("js-yaml");
const fs = require("fs").promises;
const yamlData = await fs.readFile(`${process.cwd()}/${filename}`, 'utf-8');
const config = jsYaml.safeLoad(yamlData);
// yamlから環境変数を設定する
Object.entries(config.env_variables).map((e)=>{
process.env[e[0]] = e[1];
});
}
if(process.env["NODE_ENV"] === "local"){
const filename = process.env["NODE_YAML_FILE"];
setEnvVariablesFromYaml(filename);
}
実行時
ローカル実行フラグと読み込みたいファイル名を環境変数で渡してやる
export NODE_ENV="local" && NODE_YAML_FILE="staging.yaml"; node app.js
これでenv_variables
がそのまま使えるし、同じようにテストコードの前処理とかにも対応できる。素直に良き。
所感
bashにexport書き散らかして脳筋運用してたので、もっと早く気が付けばよかった。
yamlに合わせてbashをメンテしなくていいのがタイポに神経すり減らさなくてとてもよい。
ちくしょう。みんな知ってるならもっと早く教えといてよ…!!!
Discussion