Lambda Layersで参照する環境変数は、それぞれのLambdaの環境変数であることを確認する(複数のLambdaがある場合)

杞憂でした。ですよねー。
2022.03.25

Lambda Layersで環境変数を参照するコードを書いているとき、ふと気になりました。

「あれ? Lambda Layersの環境変数は、それぞれのLambdaの環境変数が使われるんだよね……?」

というわけで、実験してみました。

おすすめの方

  • Lambda Layersで参照する環境変数は、それぞれのLambdaの環境変数になると知りたい方
  • Lambda Lyaersを使いたい方
  • AWS SAMを使いたい方

Lambda LayersとLambdaをデプロイする

sam init

sam init \
    --runtime python3.9 \
    --name Lambda-Layers-Environment-Sample \
    --app-template hello-world \
    --package-type Zip

SAMテンプレート

下記を作成しています。

  • Lambda Layers
  • Lambda Function 1
  • Lambda Function 2

なお、Lambdaは同じコードを使いますが、異なる環境変数にしています。

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda-Layers-Environment-Sample

Resources:
  CommonLayer:
    Type: AWS::Serverless::LayerVersion
    Metadata:
      BuildMethod: python3.9
    Properties:
      LayerName: !Sub sam-layer-test-for-environment
      ContentUri: layers/
      CompatibleRuntimes:
        - python3.9

  HelloWorld1Function:
    Type: AWS::Serverless::Function
    Properties:
      Layers:
        - !Ref CommonLayer
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Timeout: 3
      Environment:
        Variables:
          NAME: classmethod
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello1
            Method: get

  HelloWorld1FunctionLogGroup:
      Type: AWS::Logs::LogGroup
      Properties:
        LogGroupName: !Sub /aws/lambda/${HelloWorld1Function}

  HelloWorld2Function:
    Type: AWS::Serverless::Function
    Properties:
      Layers:
        - !Ref CommonLayer
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Timeout: 3
      Environment:
        Variables:
          NAME: developersio
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello2
            Method: get

  HelloWorld2FunctionLogGroup:
      Type: AWS::Logs::LogGroup
      Properties:
        LogGroupName: !Sub /aws/lambda/${HelloWorld2Function}

Outputs:
  HelloWorld1Api:
    Value: !Sub https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello1

  HelloWorld2Api:
    Value: !Sub https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello2

Lambda Layersのコード

環境変数のNAMEを返すだけです。

common.py

import os

def name() -> str:
    return os.environ["NAME"]

Lambda本体のコード

Lambda Layersのname()を実行し、APIのレスポンスとして返しています。

app.py

import json
import common

def lambda_handler(event, context):

    return {
        "statusCode": 200,
        "body": json.dumps({
            "name": common.name(),
        }),
    }

デプロイ

sam build

sam deploy \
    --stack-name Lambda-Layers-Environment-Sample-Stack \
    --s3-bucket cm-fujii.genki-deploy \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset

動作を確認する

APIエンドポイントを取得する

$ aws cloudformation describe-stacks \
    --stack-name Lambda-Layers-Environment-Sample-Stack \
    --query 'Stacks[].Outputs'

[
    [
        {
            "OutputKey": "HelloWorld1Api",
            "OutputValue": "https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello1"
        },
        {
            "OutputKey": "HelloWorld2Api",
            "OutputValue": "https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello2"
        }
    ]
]

APIにアクセスして、レスポンスを確認する

それぞれのLambdaで定義した環境変数が返ってきました。

$ curl "https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello1"
{"name": "classmethod"}
$ curl "https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello2"
{"name": "developersio"}

さいごに

もやもやが晴れて、スッキリしました。