AWS LambdaのデッドレターキューとSNSでリトライ構成を構築する(Serverless Framework準備編)
AWS Lambdaを利用する場合、失敗した場合に大元の関数の引数等を引き継いで何らかのリトライ処理を実行したい場合があると思います。
本記事では、AWS LambdaのデッドレターキューとAWS SNSを利用した関数のリトライ構成について、Serverless Frameworkを使って試してみたいと思います。
なお、AWS Lambdaのデッドレターキューを利用したリトライについては公式のドキュメントに記載があります。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-async.html#dlq
もくじ
開発環境
ローカルの開発マシンはMacで、Dockerを使用します。
- macOS Catalina
- docker desktop 2.2.0.5
- docker-compose 1.25.4
準備
Amazon Linuxが再現されたDockerイメージで開発
AWS Lambdaの関数が実行される環境はAmazon Linuxらしいです。Macのローカルで動いてたのにAWS Lambdaにしたら動かない、というような環境差分を避けるため、下記のAmazon Linuxの環境が再現されたDockerイメージを利用して開発します。
今回はnode.jsをで試すため、tagがbuild-nodejs12.x
のイメージを利用します。
Serverless Frameworkを利用
AWS Lambda用の関数の作成からデプロイまで、オールインワンで簡単にできるServerless Frameworkを利用します。
AWS IAMでデプロイ用のユーザー/ポリシーを作成する
Serverless Framworkを利用してAWSにデプロイする際、デプロイ用のIAMユーザー(アクセスキーIDとシークレットアクセスキー)を作成し、そのIAMユーザーに各種AWSリソースへアクセスできるポリシーをアタッチする必要があります。
これについては、公式のドキュメントに丁寧に書いてあります。
- ユーザー名:
serverless-admin
- アタッチするAWS管理ポリシー:
AdministratorAccess
作成したIAMユーザーのアクセスキーIDとシークレットアクセスキーをホストマシン側に~/.aws/private/credentials
を作成し記載しておきます。
アクセスキーIDとシークレットアクセスキーは漏れたら危険なので取り扱いには注意しましょう。
[default] aws_secret_access_key = AWS上で表示された値 aws_access_key_id = AWS上で表示された値
また、~/.aws/private/config
にリージョン情報等を記載しておきます。
[profile default] region = ap-northeast-1 output = json
※今回は~/.aws/private
というディレクトリを切っていますが、必須ではありません。筆者の都合でprivate
ディレクトリにお試し用のIAMユーザーの認証情報ファイルを配置しています。
なお、今回アタッチしたAdministratorAccess
ポリシーは少し権限が大きく、本来は最小の権限に絞ったポリシーを自作してアタッチする方がセキュリティ的には望ましいです。
これについては公式ドキュメントがあり、以下のgistに記載されているJSONを使用することを推奨しています。
Dockerfileを用意
以下のようなDockerfile
を用意します。Serverless Frameworkをグローバルにインストールしておきます。
FROM lambci/lambda:build-nodejs12.x # Serverless Framework RUN npm install -g serverless WORKDIR /var/task CMD ["/bin/bash"]
都度docker run
を実行してコンテナを起動するのは面倒なので、docker-compose.yml
でコンテナを起動できるようにします。また、ソースコードをホスト側と共有するために、予め./src
ディレクトリを作成しておきます。
container_name
やimage
の名称は任意です。今回はlambda_node12x
とします。
version: '3.7' services: lambda_node12x: build: context: . container_name: lambda_node12x image: lambda_node12x volumes: - ./src:/var/task - ${HOME}/.aws/private:/root/.aws/ working_dir: /var/task tty: true stdin_open: true
AWS credentialsをホストとDockerコンテナで共有する
上記のdocker-compose.yml
のvolumes
に${HOME}/.aws/private:/root/.aws/
と書いていますが、これは先ほど作成したAWSの認証情報を記載したcredentials
とconfig
ファイルをDockerコンテナ内でも参照できるようにするためです。
これをしないとAWSにデプロイできません。
なお、この方法とは別に、Serverless Framworkの`config credentialsコマンドでAWSの認証情報を設定することが可能です。
また、今回はprofile名をdefault
のままにしていますが、変更している場合は以下のコマンドで変更する必要があります。
sls deploy --aws-profile hogeProfile
個人的には、コンテナを削除しても設定し直す必要がないため、
profileはdefault
でcredentials
をホスト側に用意して共有するのが楽だと思います。
以上で準備は完了です。
関数を作成してデプロイする
Dockerコンテナ上で関数作成
Dockerコンテナにログインし、Serverless Frameworkのコマンドを叩いてテスト用の関数を作成します。
# ログイン docker exec lambda_node12x bash # コンテナ内で実行 sls create -t aws-nodejs --path=failFunc # 以下のように作成される Serverless: Generating boilerplate... Serverless: Generating boilerplate in "/var/task/failFunc" _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v1.67.1 -------' Serverless: Successfully generated boilerplate for template: "aws-nodejs"
関数をローカルで試す
下記のコマンドでローカルで関数の実行を試すことができます。まだ何も修正していないのでテンプレートにより作成された関数が実行されます。
sls invoke local -f hello # 下記の結果が返ってくる { "statusCode": 200, "body": "{\n \"message\": \"Go Serverless v1.0! Your function executed successfully!\",\n \"input\": \"\"\n}" }
デプロイする
sls create
で作成されたserverless.yml
にAWSのリージョン情報を追記します。設定しないとデフォルトのus-east-1
にデプロイされます。
provider: name: aws runtime: nodejs12.x region: ap-northeast-1 # これを追記
デプロイはコマンドで一発です。-v
をつけているとデプロイの実行過程をみることができます。
sls deploy -v
成功したらAWSのコンソールのAWS Lambdaでデプロイした関数を確認できます。
デプロイした関数を削除する
下記のコマンドで削除できます。
sls remove -v
上記以外のコマンドは公式のCLIリファレンスを参照しましょう。
Serverless Framworkは便利
AWS LambdaのデッドレターキューとAWS SNSを利用した関数のリトライ構成について書こうと思っていましたが、Serverless Framworkの紹介だけで長くなってしまったので、今回はここまでとします。
次回の記事で本題について書こうと思います。