【AWS Lambda】 Lambdaで初めて環境変数を使ってみたのでその紹介とSAMでの使い方

#1. はじめに
　私はlambdaを使用する際、環境毎にlambdaを作成しテスト環境ではこの関数、本番環境ではこの関数を使う、ってことをよくやっていました。そうなってくると、本番環境ではこのDBを参照、テスト環境ではこのDBを参照といったことをやりたくなってきます。私は aws-sam-cli を用いてlambdaの管理を行っているのですが、環境毎にコードの中身を書き換えることがうまくできていませんでした。
　しかし！　今回紹介する環境変数というlmandaの機能を使用してみたところ抱えていた問題が解決したため、せっかくなんで紹介します。

#2. lambda環境変数とは
　環境変数とは何でしょうか。[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-envvars.html)には以下のように記述されています。

>環境変数を使用すると、コードを更新せずに関数の動作を調整できます。環境変数は、関数のバージョン固有の設定に保存される文字列のペアです。Lambda ランタイムは、環境変数をコードで使用できるようにし、関数と呼び出しリクエストに関する情報を含む追加の環境変数を設定します。

 難しいことが書いてありますが、今までハードコーディングしていたコードの一部を環境変数で臨機応変に書くことができる機能として認識していただければ大丈夫です。

#3. コンソール上でのlambda環境変数の利用
　とりあえずテスト用のlambda関数を作成してみましょう。（今回はpython3.8を使用しています。）作成後、設定項目に環境変数を編集できる項目があります。この編集ボタンから環境変数の追加を実行できます。今回は適当に以下のように保存しました。

key   : test
value : test_env

![スクリーンショット 2021-10-27 163735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/d738356e-7b98-2e87-398a-1b75c648570c.png)

![スクリーンショット 2021-10-27 165432.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/2c6436ca-262d-2d78-8f5e-2881cdc4926c.png)

※暗号化の設定とありますが、今回は特に使用していません。コンソール上でtestやtest_envが見えているのが嫌な方は導入の検討をした方がいいかと思いますが、暗号化用の鍵を用意したりと意外と時間がかかりそうだったため今回は割愛しました。

　lambdaのコード上から環境変数を呼び出すのはそんなに難しくありません。以下のようにosをインポートし、osの環境変数を取り出せば中身を出力できます。

```python
import json
import os
def lambda_handler(event, context):
    
    env = os.environ['test']
    print(env)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

さて、環境変数の簡単な使い方を理解したところで、今度はSAMを使って環境変数を設定してみましょう。

#4. aws-sam-cliを用いたlambda環境変数の設定方法
　lambdaの環境変数はテンプレートファイルを編集することで設定できます。samの使い方がわからない方は[こちらの記事](https://qiita.com/N_H_tennis/items/c0e49be8e04c2a201b6f)をご覧ください。
　環境変数は関数のプロパティで Environment の Variables に key: value の形式で記述します。デフォルトのHelloWorldFunctionテンプレートファイルを変更するなら下記のようになります。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  testpj

Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Environment:
        Variables:
          test: test_env
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
```

この状態でビルド・デプロイすれば環境変数が記述されたlambda関数が使用できます。しかし、それでは少々使いづらいため、実際には下記のようにMappingとParametersを併用して使用しましょう。
　これにより、デプロイする時にパラメータにProかTestを用いるか聞かれ、Proを入力すれば環境変数はtest_pro_env、Testを入力すればtest_test_envとなります。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  testpj

Parameters: 
  SelectEnvironment: 
    Type: String
    Default: Test
    AllowedValues:
      - Pro
      - Test

Mappings:
  EnvMap:
    Pro: 
      value: test_pro_env
    Test: 
      value: test_test_env

Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Environment:
        Variables:
          test: !FindInMap [EnvMap, !Ref SelectEnvironment, value]
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
```

#5. 終わりに
　以上でlambdaの環境変数の使い方は終了になります。lmabda上でハードコーディングをして困っている方はぜひぜひ利用をお勧めします。