Lambdaで他サービスのAPIを度々利用したくなると思います。
(例えば、S3にアクセスしたり、DynamoDBからデータを取り出したり等)
ローカルでは権限を設定したIAMユーザーの認証情報を利用して実行し、運用時にはロールをLambdaに設定して走らせたいところです。
TypeScriptのwebpackでのコンパイル分岐の為にdotenv
を利用しているので、そこに設定してもいいんですが、SAMのテンプレートに記述する方法もあるのでそちらをまとめておきます。
テンプレートを分ける
開発環境と運用環境などを分けたくなるので、テンプレートと環境変数ファイルを複数用意したいです。
なのでディレクトリ(もしくはファイル)で分けておきます。
具体的には
プロジェクトディレクトリ
├ sam/
│├ develop/ ←開発用ディレクトリ
││├ env.json
││└ template.yaml
│├ test/ ←自動テスト用ディレクトリ
││├ env.json
││└ template.yaml
│└ deploy/ ←運用版ディレクトリ
│ ├ env.json
│ └ template.yaml
├ built/ ←TypeScriptのコンパイル先
├・・・
のようなイメージです。
(全てに環境変数が要るかは状況次第だとは思いますが)
これでとりあえず.gitignore
に**/env.json
とでも追記しておけばリポジトリにヤバイ情報をアップロードしなくて済みそうです。
テンプレートの修正
ここで、SAMのテンプレートファイルを修正しておきます。
テンプレートのResources
→関数名
→Properties
→CodeUri
は、テンプレートからみた相対パスなので、上記のディレクトリ構成を取っている場合は
~ Properties: CodeUri: ../../built/ ~
となります。
試しにローカル実行してみる
とりあえず色々動かしたのでローカルで実行してみます。
テンプレートを何個か使い分けるので、プロジェクトのルートディレクトリからテンプレートを明示して実行します。
sam local start-api -p 3001 -t sam/develop/template.yaml
今回はポート(3001)も明示しました。(よくReactで3000番は使ってるので)
とりあえず今は動けばOKです。
環境変数の定義
早速環境変数を設定していきます。
SAMでローカル実行する際に環境変数を使うには
- テンプレート上で変数を定義する
- 読み込むJSONを作成する
という手順が必要です。
コマンドですんなり入ってくれればいいんですが、テンプレート上で変数を定義するということをお忘れ無きよう。
テンプレート上で変数を定義する
テンプレートに変数の情報を書き込んでいきます。
環境変数の適応には2通りあり
- Globalsに記述してResources全てで適応できる変数を定義する
- Resourcesの関数毎に変数を定義する
のどちらかになります。
自分の記憶では、以前は両方を両立できたと思うんですが、現状どちらかを選べば片方の環境変数がうまく注入されないような気がします。
(例えば、Globalsに環境変数を定義すると、Resourcesの環境変数がうまく変更できない)
基本的には公式ドキュメントで例のある後者をオススメします。
Globalsに記述してResources全てで適応できる変数を定義する
テンプレートには下記の様に記載します。
~ Globals: Function: Runtime: nodejs10.x Timeout: 3 Environment: Variables: GLOBAL_ENV: DUMMY ~
注入する環境変数のJSONファイルは下記のように作成します。
{ "Parameters": { "GLOBAL_ENV": "hoge" } }
Resourcesの関数毎に変数を定義する
テンプレートには下記の様に記載します。
~ Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: ../../built/ Handler: development.lambdaHandler Events: HelloWorld: Type: Api Properties: Path: /hello Method: get Environment: Variables: FUNC_ENV: DUMMY ~
注入する環境変数のJSONファイルは下記のように作成します。
{ "HelloWorldFunction": { "FUNC_ENV": "fuga" } }
環境変数を注入して実行
上記の2通りどちらでも実行方法は同じです。
sam local start-api -p 3001 -t sam/develop/template.yaml -n sam/develop/env.json
上記のコマンドをpackage.json
に書いておけば、簡単にテストできます。
自分はnpm-run-all
を利用してSAMのローカルサーバーとwebpackのwatchを走らせてますのでpackage.json
のscripts
を
~ "scripts": { "dev:localhost": "sam local start-api -p 3001 -t sam/develop/template.yaml -n sam/develop/env.json", "dev:watch": "webpack --watch", "dev": "run-p dev:*", ~
としておけば、yarn dev
でSAMとwebpackが走ります。