/ #aws #cdk 

CDK(Python)でLambdaとLayerをデプロイする

もくじ


注意:以下の記事の内容は古いです。 最新はこちらを御覧ください。


CDKでLambda_Layerをデプロイして、それをLambdaで使ってみます🤔

CDKでLambda_Layerをデプロイする方法ですが、私的に色々迷う要素がありまして、

「こんな感じが良いのではないかなー?🤔」って思うものを共有させていただけます

アーキテクチャはこんな感じです。

個人的な理由でCDK周りでDockerを使いたくないのですが、$ pip installをする環境だけは固定していたほうが良いと思うのでコンテナを挟みました。

使うイメージはdocker-lambdaを使います。

前提

では 作っていきましょう👻

まずLambda_Layerにするディレクトリを作っていきます。

ファイル名等はこのみですで、下記はあくまでも参考程度に👍

$ mkdir -p layers/lambda_layer

Layerで使うmoduleをインストールします。ここではなんとなくrequestsをインストールして、requirements.txtを追加します。

※ ちなみに$ pip installを叩いたのは、requestsのバージョンが欲しかっただけです😅

$ pip install requests
$ pip freeze | grep requests > layers/lambda_layer/requirements.txt

Lambda_LayerをBuild(❓)する

今後もなんども叩くことになると思うので、Makefileにする

Makefileに下記を追加します

layer_build:
	docker run --rm \
		-v ${CURDIR}/layers/lambda_layer:/var/task \
		lambci/lambda:build-python3.8 \
		pip install -r requirements.txt -t python/

で、Build(?)します👍

$ make layer_build

うまくいくとlayers/lambda_layer配下にpythonというディレクトリが作られて、そこの下にモジュールがインストールされてるはずです。 余談ですが、このディレクトリ名のpythonという名前は固定です。 node.jsとかだとnodejs,Rubyだとrubyです。 詳細は公式をお読みください👍

話戻って、現状のままで$ git add .すると悲惨なことになるので.gitignoreに下記を追加しておきます。

layers/*/python

Lambdaを追加します

このへんはおまけですね。

このブログのtopページをgetで取得するという謎のLambdaを実装します。

import requests


def lambda_handler(event, context):

    url = "https://blog.i-tale.jp/"
    response = requests.get(url)

    return {"text": response.text}

Stackの実装

きっとこれがメインだと思いますが、とくに説明なくサンプルコードです

from aws_cdk import aws_lambda, core


class LambdaLayerStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # lambda_layer
        layer = aws_lambda.LayerVersion(
            self,
            "LambdaLayerLayer",
            compatible_runtimes=[aws_lambda.Runtime.PYTHON_3_8],
            code=aws_lambda.AssetCode("layers/lambda_layer"),
        )

        # lambda
        common_lambda_params = dict(
            runtime=aws_lambda.Runtime.PYTHON_3_8,
            handler="lambda_function.lambda_handler",
            timeout=core.Duration.seconds(10),
            memory_size=128,
        )
        lambda_ = aws_lambda.Function(
            self,
            "LambdaLayerLambda",
            code=aws_lambda.Code.asset("lambdas/lambda_layer"),
            layers=[layer],
            **common_lambda_params,
        )

requirements.txtに追記する

今回使うリソースはcore以外はLambdaしか使ってないので、下記で大丈夫です👍

aws-cdk.core==1.72.0

aws-cdk.aws-lambda==1.72.0

エントリーポイントにStack追記

app.pyに下記追記

...省略
from stacks.lambda_layer_stack import LambdaLayerStack
...省略
LambdaLayerStack(app, "lambda-layer-stack", env=env)
...省略

デプロイ🚀

cdk コマンドでデプロイ!ですが、1個注意点があるとすると、cdkではlambda_layerのrequirements.txtを見て自動でインストール等はしてくれないので$ make layer_buildを叩きわすれないようにしましょう

$ make layer_build # ←重複してますが書いておきます
$ cdk deploy lambda-layer-stack

動かしてみましょう👍

まずデプロイしたLambda名をコンソールやら$ aws lambda list-functions | grep lambda-layer-stackやらを叩いて取得します

ここではlambda-layer-stack-LambdaLayerLambdaC17D23EC-MDU08AV9B9IZという名前でした。

$ aws lambda invoke --function-name "lambda-layer-stack-LambdaLayerLambdaC17D23EC-MDU08AV9B9IZ" --payload '{}' response.json

# `response.json`に出力が保存されたので、頭50文字出力してみます。

$ head -c 50 response.json
> {"text": "<!DOCTYPE html>\n<html lang=\"ja-jp\" />%

きちんと実行結果が取得できました😊

まとめ

今回はCDKとDockerを使ってLambda&Layerをデプロイしてみました😊

Lambda_LayerのデプロイだとCDKだけで完結しないので、複雑になってしまいますね。。

今回のリポジトリはこちら

https://github.com/sisi100/cdk-my-template/tree/20201109.1

Author

Sisii

インフラが好きなエンジニアぶってるなにか