Git Submoduleで管理しているコードをLambda Layersで使ってみる

Git SubmoduleとLambda Layersの組み合わせでデプロイしてみました。
2023.07.07

AWS Lambda LayersとAWS Lambdaを利用しています。それぞれ異なるGitリポジトリで管理しており、ローカルのUnit Testで参照するために、Git Submoduleを利用しています。

Git Submoduleを利用したリポジトリ構成

このとき、「Lambda Layers Repository」と「Lambda Repository」をそれぞれデプロイしていたのですが、「Git Submodule使ってるんだし、Lambda Repositoryだけのデプロイで良いのでは?」と思ったので、試してみました。 (本記事では簡略版で試しています。)

おすすめの方

  • Git Submoduleを利用したい方
  • Lambda Layersを利用したい方
  • Git SubmoduleとLambda Layersを合わせて利用したい方

Lambda Layersを作成する

Layers用のリポジトリを作成する

  • blog-lambda-layers.git

リポジトリの作成後、git cloneしておきます。

Layers用のコードを作成する

cd blog-lambda-layers 

mkdir -p src/layers
touch src/layers/hello.py

コードは下記です。

hello.py

def message():
    return 'hello world'

コード作成後、git commit & git pushしておきます。

Lambdaを作成する

sam init

sam init \
    --runtime python3.9 \
    --name sam-layers-test \
    --app-template hello-world \
    --no-tracing \
    --no-application-insights \
    --package-type Zip

作成後、Gitリポジトリ化しておきます。

cd sam-layers-test
git init
git add .
git commit -m "first commit"

Git Submoduleを追加する

さきほどpushしておいたLayers用のリポジトリをSubmoduleとして追加します。

git submodule add git@github.com:cm-fujii/blog-lambda-layers.git

SAMテンプレート

Lambda Layersのコードの場所は、Git Submoduleとして追加したリポジトリを指定します。

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: sam-layers-test

Resources:
  BlogLayer:
    Type: AWS::Serverless::LayerVersion
    Metadata:
      BuildMethod: python3.9
    Properties:
      LayerName: blog-layer
      ContentUri: blog-lambda-layers/src/layers/
      CompatibleRuntimes:
        - python3.9

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Timeout: 5
      Layers:
        - !Ref BlogLayer
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

  HelloWorldFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}

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

コード

Layersに存在する関数を呼びます。

hello_world/app.py

import json

from hello import message

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": message(),
        }),
    }

LayersとLambdaをデプロイして、動作を確認する

デプロイ

sam build
sam deploy \
    --guided \
    --region ap-northeast-1 \
    --stack-name sam-layers-test-Stack

動作を確認する

バッチリですね。

curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

{"message": "hello world"}

Layersのコードを更新して、デプロイして、動作を確認する

Layersのコードを更新する

hello.py

def message():
    return 'hello world!!!!!! Yeah!!!!!'

保存したあと、commit & push します。

git commit -am "update message()"

git push origin main

Lambdaを管理するリポジトリを確認する

さきほど、Git Submoduleとして利用しているリポジトリに変更をpushしましたが、ローカルリポジトリは変更されていません。 そのため、最新のコードではありません。

$ cat blog-lambda-layers/src/layers/hello.py

def message():
    return 'hello world'

Git Submoduleを更新する

Git Submoduleの更新にはいくつかの方法がありますが、今回は下記コマンドを実行します。 (少し手間ですが、明示的に更新するので分かりやすいと思います。)

cd blog-lambda-layers

git pull origin main

cd ..

念のためコードを確認すると、更新されています。

$ cat blog-lambda-layers/src/layers/hello.py

def message():
    return 'hello world!!!!!! Yeah!!!!!'

デプロイ

sam build
sam deploy

動作を確認する

最新のLayersのコードが利用されています。やったね!

curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

{"message": "hello world!!!!!! Yeah!!!!!"}

さいごに

Git Submoduleを利用したLayersコードの管理を試してみました。 どなたかの参考になれば幸いです。