LoginSignup
1
1

More than 1 year has passed since last update.

SAM CLIを用いたLambda Layer 検証方法メモ

Posted at

Lambda Layerとは

  • 複数のLambda関数で外部ライブラリやビジネスロジックを共有できる仕組み

  • メリット

    • ライブラリなどの共通コンテンツをレイヤーとして作成することで、パッケージにライブラリを含める必要がなくなる。

    • アップロードされたデプロイアーカイブのサイズを縮小し、デプロイスピードを高速化できる。

検証

  • DynamoDBアクセス共通処理をLayer化し、SAMで検証用APIを作成する。

事前準備

  • DynamoDB環境構築

    • docker-compose.yml

      version: '3'
      
      services:
        dynamodb-local:
          container_name: dynamodb-local
          image: amazon/dynamodb-local:latest
          user: root
          command: -jar DynamoDBLocal.jar -sharedDb -dbPath /data
          volumes:
            - dynamodb-data:/data
          ports:
            - 8000:8000
          networks:
            - dynamodb-network
      
        dynamodb-admin:
          container_name: dynamodb-admin
          image: aaronshaf/dynamodb-admin:latest
          environment:
            - DYNAMO_ENDPOINT=dynamodb-local:8000
          ports:
            - 8001:8001
          depends_on:
            - dynamodb-local
          networks:
            - dynamodb-network
      
      volumes:
        dynamodb-data:
      
      networks:
        dynamodb-network:
          external: true
      
    • 起動

      docker-compose up -d
      

      ※localhost:8000でDynamoDBが起動する。

    • test_userという名前でテーブル作成しておく。

コード

  • sam initでHello World templateを利用して作成。

  • 構成

    ├── src
    │   ├── func
    │   │   ├── __init__.py
    │   │   └── app.py
    │   └── layer
    │       └── python
    │           ├── __init__.py
    │           ├── dynamo_util.py
    │           └── requirements.txt
    ├── template.yaml
    
  • template.yaml

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    Description: >
      sam-app
    
      Sample SAM Template for sam-app
    
    # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
    Globals:
      Function:
        Timeout: 3
    
    Resources:
      MyLayer:
        Type: AWS::Serverless::LayerVersion
        Properties:
          ContentUri: src/layer/python
          CompatibleRuntimes:
            - python3.8
        Metadata:
          BuildMethod: python3.8
        LayerName: MyLayer
      HelloWorldFunction:
        Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
        Properties:
          CodeUri: src/func
          Handler: app.lambda_handler
          Runtime: python3.8
          Architectures:
            - x86_64
          Environment:
            Variables:
              aws_access_key_id: dummy
              aws_secret_access_key: dummy
              region_name: ap-northeast-1
              dynamo_endpoint: http://dynamodb-local:8000
          Events:
            HelloWorld:
              Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
              Properties:
                Path: /item
                Method: post
          Layers:
            - !Ref MyLayer
    
  • dynamo_util.py : DynamoDB共通処理

    from boto3.session import Session 
    import os
    # DynamoDB
    session = Session(
        aws_access_key_id=os.environ['aws_access_key_id'],
        aws_secret_access_key=os.environ['aws_secret_access_key'],
        region_name=os.environ['region_name']
    )
    dynamodb = session.resource(
        service_name='dynamodb', 
        endpoint_url=os.environ['dynamo_endpoint']
    )
    
    def put_item(item):
        
        table = dynamodb.Table('test_user')
        table.put_item(
            Item=item
        )
        
    
  • app.py : DynamoDB共通処理を呼び出し、リクエストで受け付けた内容をテーブルに登録する。

    import json
    import dynamo_util as dynamo_util
    
    def lambda_handler(event, context):
        dynamo_util.put_item(json.loads(event['body']))
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": "item_put succeeded",
            }),
        }
    
    
  • requirements.txt : 依存ライブラリ

    requests
    boto3
    

動作確認

  • ビルド

    sam build
    
  • 起動※Docker 起動しているDynamoDBローカルと接続するためにオプション指定している。

    sam local start-api --docker-network dynamodb-network
    
  • リクエスト

    POST /item HTTP/1.1
    Host: localhost:3000
    Content-Type: application/json
    Content-Length: 58
    
    {
        "id":"12345",
        "email":"example@example.com"
    }
    
  • レスポンス

    {
        "message": "item_put succeeded"
    }
    
  • DynamoDB Local登録結果

    dynamo_result.png

参考情報

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1