Serverless Framework を利用したアプリケーションを作成したときに、ステージごとに環境変数を設定したときにハマったのでメモ。
なお、LambdaのランタイムはNode.js4.3です。
環境変数の読み込み方の記事はあるけれど、ステージごとに環境変数を分けるにはどうしたらいいかについての情報はあまりありませんでした…
なのでお役に立てば。
serverless.ymlにステージごとの環境変数を定義する
以下のように定義されています。
serverless.yml
provider:
name: aws
runtime: nodejs4.3
region: ${self:custom.defaultRegion}
stage: ${opt:stage, self:custom.defaultStage}
environment:
REGION: ${self:custom.defaultRegion}
iamRoleStatements:
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
- "ec2:CreateNetworkInterface"
- "ec2:DescribeNetworkInterfaces"
- "ec2:DeleteNetworkInterface"
Resource:
- "*"
custom:
defaultStage: dev
defaultRegion: ap-northeast-1
environment:
dev:
SERVERLESS_ENV_VAL: dev_env
stage:
SERVERLESS_ENV_VAL: stage_env
prod:
SERVERLESS_ENV_VAL: prod_env
functions:
foo:
handler: app/util/foo.foo
environment: ${self:custom.environment.${self:provider.stage}}
上記のように custom
の environment
にdev, stage, prodのステージごとに環境変数を定義しておきます。
JSから環境変数の読み込む
次はJSから環境変数の読み込みを行います。
foo.js
'use strict';
const testenv = require('../../lib/test-environment');
/**
* Lambdaイベントハンドラー
*/
module.exports.foo = (event, context, callback) => {
const env = process.env.SERVERLESS_ENV_VAL || testenv.env.SERVERLESS_ENV_VAL;
// 以下省略
};
これでJavaScriptでステージごとの環境変数を取得することができます。
ちなみにsls invoke -s dev -f foo
というようにdevで実行した場合は「dev_env」
というように指定したステージに基づいた環境変数が使用されます。
テストプログラムから動作させる場合の注意
テストプログラムから実行される場合、Serverlessフレームワークを経由しないので環境変数が設定されません。
環境変数が設定されていない場合外部のファイル(上記の例だとlib/test-environment.js)から値を読み込むようにすると非常に楽。
lib/test-environment.js
'use strict';
/**
* 環境変数が指定されなかった場合の初期値を定義します
* sls invoke local -f foo というServerlessフレームワークをとおしてではなく
* sls run -f [functionname] でローカルで実行した場合は
* serverless.ymlの環境変数が読み込まれないため
*/
exports.env = {
SERVERLESS_ENV_VAL: 'dev',
};
以上です。
Serverlessでステージごとに環境変数を切り替える場合のコーディングに役に立てば幸いです。