Help us understand the problem. What is going on with this article?

AWS Lambda@Edge で 環境変数を使う方法 (Node.js)

はじめに

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いいよね。

.env
APP_ENV=production
APP_URL=https://www.example.com
APP_DEBUG=false

ここまで出来たら、これらをZIPファイルにまとめて、
Lambda@Edgeにアップロードします。

ZIPファイルでアップロードする方法は、
ネットに腐るほど書いてますのでググってください

【絶対にすること】 エディタで隠しファイルを表示する

2020.02.19 追記

下の方法よりもっと簡単な方法がありました。
プロジェクトフォルダの右の歯車をクリックした後、「Show Hidden Files」をクリックするだけです

3.png

ファイルアップロードが終わったら、
以下の手順に従い、コンソールエディタで
「.env」などの隠しファイルが表示されるようにしてください
(将来の Lambda@Edge のアップデートで表示方法が変更になる可能性があります)

1.png

① エディタ右上の歯車マークをクリック
② User Settings をクリック
③ Tree and Go Panel をクリック
④ Hidden File Pattern: から 次のように 「, .*」 を削除

*.pyc, __pycache__, .*
↓
*.pyc, __pycache__

2.png

これにより、隠しファイルが表示されるので
どこに設定ファイルがあるかがわかるようになりますね。

(筆者は動作確認のために .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関数みたいな感じにラッピングしてから使用しています

index.js
/* =====================================================================
*  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);
};

もっと良い方法をご存知の方が
いらっしゃいましたらコメントください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした