はじめに
Lambda ならば、環境変数という項目があり、
そこにキーと値を書けば process.env
オブジェクトから取得できました。
参考URL
AWS Lambda で環境変数を渡してみる(Node.js)
Lambda@Edge にも同じく環境変数の入力欄があるのですが、
どういうわけかまだサポートされてないらしく、
2020年2月時点では使用できません。
初見殺しもいいところですね。
でも、環境変数が使いたい時はあると思います。
色々模索した結果、以下の方法に落ち着きました。
結論 dotenv
ライブラリを使う
ローカル環境とかにdotenvライブラリを導入します
$ cd /path/to/project
$ npm install dotenv
次に、 .env
ファイルを用意して、そこに環境変数を色々書いておきます。
$ touch .env
$ vi .env
私はかつてLaravel5(PHP)を使っていたので、それに習った書き方をしています。
Laravelいいよね。
APP_ENV=production
APP_URL=https://www.example.com
APP_DEBUG=false
ここまで出来たら、これらをZIPファイルにまとめて、
Lambda@Edgeにアップロードします。
ZIPファイルでアップロードする方法は、
ネットに腐るほど書いてますのでググってください
【絶対にすること】 エディタで隠しファイルを表示する
2020.02.19 追記
下の方法よりもっと簡単な方法がありました。
プロジェクトフォルダの右の歯車をクリックした後、「Show Hidden Files」をクリックするだけです
ファイルアップロードが終わったら、
以下の手順に従い、コンソールエディタで
「.env」などの隠しファイルが表示されるようにしてください
(将来の Lambda@Edge のアップデートで表示方法が変更になる可能性があります)
① エディタ右上の歯車マークをクリック
② User Settings をクリック
③ Tree and Go Panel をクリック
④ Hidden File Pattern: から 次のように 「, .*」 を削除
*.pyc, __pycache__, .*
↓
*.pyc, __pycache__
これにより、隠しファイルが表示されるので
どこに設定ファイルがあるかがわかるようになりますね。
(筆者は動作確認のために .envファイルを複数用意していますが、
必要ありません。「.env」ファイルだけが使用されます)
環境変数の取得方法
Lambdaで環境変数を取得する方法と全く同じやり方で取得できます。
つまり、 process.env
オブジェクトから取得できます。
var ENV = require('dotenv').config();
var appUrl = process.env['APP_URL'];
console.log(appUrl); // e.g. "https://www.example.com"
私の場合、毎回 process.env
って書くのがだるいので
Laravelのenv関数みたいな感じにラッピングしてから使用しています
/* =====================================================================
* Load External Modules
* =================================================================== */
try {
var ENV = require('dotenv').config(); // 環境変数が使えるようになったらこのモジュールは不要
}
catch(ex){ // if module is not exists
console.error(ex);
}
/**
* Get Envrionment Variable
* Lambda@Edgeは2020年2月時点では環境変数が使えないから
* DotEnvライブラリで代用する(環境変数もDotEnvも process.env で値を取得できる)
*
* @param string key (should be write UPPERCASE)
* @param mixed defaultValue [optional]
* @return mixed
*/
function getEnv(key, defaultValue = null)
{
var myKey = key.toUpperCase();
return process.env[myKey] ? process.env[myKey] : defaultValue;
}
function loadProfile()
{
var env = new Object();
env.APP_URL = getEnv("APP_URL", "https://www.example.com");
env.APP_ENV = getEnv("APP_ENV", "development");
env.APP_DEBUG = getEnv("APP_DEBUG", true);
env.S3_BUCKET_NAME = getEnv("S3_BUCKET_NAME", "my-s3-bucket-name");
env.EC2_URL = getEnv("EC2_URL", "");
return env;
}
exports.handler = async (event, context, callback) => {
var request = event.Records[0].cf.request;
var env = loadProfile();
console.log(env["APP_URL"]); // e.g. "https://www.example.com"
console.log(env["APP_ENV"]); // e.g. "production" .env に定義されているので その値が使用される
console.log(env["S3_BUCKET_NAME"]); // e.g. "my-s3-bucket-name" .env に定義されていないので getEnv関数の第2引数が使用される
callback(null, request);
};
もっと良い方法をご存知の方が
いらっしゃいましたらコメントください。