Serverless Frameworkで環境変数を外部ファイルから読み込み、環境毎に自動で切り替えてみる

どうも!西村祐二@大阪です。

現在、Lambdaを開発するときにServerless Frameworkをよく使っています。
Lambdaで利用する環境変数はserverless.ymlに記載することでデプロイ時に設定されますが
本番環境と開発環境で環境変数を分けたいときは
外部ファイルにだして、それを読み込むほうがスッキリとして
また、今後環境変数を編集する際も作業しやすくなると思います。

今回は、デプロイ時に外部ファイルに書き出した環境変数を読み込み
開発環境と本番環境とで自動的に切り替える方法を紹介したいと思います。

やりたいこと

今回やりたいことをまとめると下記の通りです。

$ sls deploy
コマンド実行後、開発環境用の環境変数が自動的に設定される

$ sls deploy --stage prd
コマンド実行後、本番環境用の環境変数が自動的に設定される

さっそくやっていきましょう。

事前準備

  • AWS CLIの設定

aws conigureコマンドで利用設定を予め行っておいてください。
下記リンクが参考になります。

http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html

ここではプロファイルを「sls」として設定を行ったと仮定して進めます。
また、今回は動作確認が目的のため本番環境、開発環境のデプロイ先を同じとして
関数名に本番用、開発用の名前をつけてデプロイし動作の確認を行いたいと思います。

$ aws configure --profile sls
AWS Access Key ID [None]: XXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
  • Serverless Frameworkのインストール
$ npm install serverless -g

環境

Mac : macOS Sierra 10.12.5
AWS CLI : aws-cli/1.11.117 Python/3.6.0 Darwin/16.6.0 botocore/1.5.80
Serverless Framework : 1.17.0

プロジェクト作成

今回、「test-sls」というプロジェクトを作成します。言語は「python3.6」です。

$ sls create --template aws-python3 --path test-sls
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/nishimura.yuji/study/sls/test-sls"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.17.0
 -------'

Serverless: Successfully generated boilerplate for template: "aws-python3"

外部ファイル作成

Lambdaで指定する環境変数を外部ファイルとする場合は
YAMLかJSONファイルで記載する必要があります。

参考リンク

今回、環境変数のキーを「Other_File」とし、
キーに対する値を
開発環境なら「Development environment」、
本番環境なら「Production environment
とします。

$ cd test-sls

$ mkdir conf/{dev,prd}

$ vim conf/dev/dev.yml
Other_File: Development environment


$ vim conf/prd/prd.yml
Other_File: Production environment


$ tree .
.
├── conf
│   ├── dev
│   │   └── dev.yml
│   └── prd
│       └── prd.yml
├── handler.py
└── serverless.yml

3 directories, 4 files

serverless.ymlを編集

下記のように編集します。
下記がserverless.ymlの全体です。

$ cat serverless.yml| egrep -v "^$|^#"

service: test-sls
provider:
  name: aws
  runtime: python3.6
  region: ap-northeast-1
  stage: ${opt:stage, self:custom.defaultStage}
  profile: ${self:custom.profiles.${self:provider.stage}}
  # 共通の環境変数
  environment:
    COMMON_VARIABLES: common
custom:
  defaultStage: dev
  profiles:
    dev: sls
    prd: sls
  otherfile:
    environment:
      dev: ${file(./conf/dev/dev.yml)}
      prd: ${file(./conf/prd/prd.yml)}
functions:
  hello:
    handler: handler.hello
    environment:
      Other_File: ${self:custom.otherfile.environment.${self:provider.stage}.Other_File}

簡単に解説していきます。

環境の切替

stage: ${opt:stage, self:custom.defaultStage}

8行目に記載されている上記について簡単に説明します。

  • sls deploy --stage devとした場合

${opt:stage}devが返ります。

  • sls deploy --stage prdとした場合

prdが返ります。

  • --stageを指定しない場合は

defaultStageより、devが返ります。

profile: ${self:custom.profiles.${self:provider.stage}}

9行目に記載されている上記について簡単に説明します。

  • sls deployとした場合

defaultStageより、devが返るため、
${self:provider.stage} => dev
となり、
${self:custom.profiles.dev} => プロファイルの「sls」
を指定することになる。

  • sls deploy --stage prdとした場合

${opt:stage}は、prdが返るため、
${self:provider.stage} => prd
となり、
${self:custom.profiles.prd} => プロファイルの「sls」
を指定することになる。

今回はテストのため、本番環境と開発環境のプロファイルは同じとしていますが
実際に利用する場合は環境ごとにプロファイルを分けておきます。

外部ファイル読み込み

Other_File: ${self:custom.otherfile.environment.${self:provider.stage}.Other_File}

26行目に記載されている上記について簡単に説明します。

  • sls deployとした場合

defaultStageより、devが返るため、
${self:provider.stage} => dev
となり、
./conf/dev/dev.yml
を指定することになり、ファイル内のキーに対する値が取得できる。

  • sls deploy --stage prdとした場合

${opt:stage}は、prdが返るため、
${self:provider.stage} => prd
となり、
./conf/prd/prd.yml
を指定することになり、ファイル内のキーに対する値が取得できる。

2017-07-19_0_24_53

handler.pyを編集

下記ファイルのように編集します。
プログラムの内容として、環境変数を取得してprintとreturnしているだけです。

$ cat handler.py | egrep -v "^$|^#"

import json
import os
def hello(event, context):
    GET_VARIABLES = os.environ['Other_File']
    print(GET_VARIABLES)
    return GET_VARIABLES

動作確認

開発環境にデプロイしてみる

下記コマンドを実行し開発環境へデプロイする。

$ sls deploy

マネージメントコンソールにアクセスし確認する。

2017-07-18_23_20_23

環境変数が想定どおりの値になっているか確認する。

2017-07-19 1.00.01

本番環境にデプロイしてみる

下記コマンドを実行し開発環境へデプロイする。

$ sls deploy --stage prd

マネージメントコンソールにアクセスし確認する。

2017-07-18_23_20_23_2

環境変数が想定どおりの値になっているか確認する。

2017-07-19 1.00.15

プログラムから環境変数を取得してみる

本番環境にてマネージメントコンソールからテストを実施してみます。
下記画像のように問題なく、環境変数が出力されているかと思います。

2017-07-19_1_01_53

さいごに

いかがだったでしょうか。
外部ファイルに書き出した環境変数を環境ごとに自動で切り替える方法についてまとめてみました。
環境変数にファイルパスを指定しておけば、
読み込むコンフィグを切り替えることができます。
また、ChatOps開発時に指定するルームやアカウントを開発・本番環境で切り替えたいときなどにも
利用できると思います。

検索してもあまりヒットしなかったのでブログにしてみました。
誰かのお役に立てたら幸いです。