terraformによりlambdaとしてコンテナイメージをデプロイ
コンテナイメージを用いたlambda
概要
- 2020/12からlambdaとしてECR上のコンテナイメージをデプロイできる
- 今までのzip形式との大きな違いはアーティファクトサイズ制限(250 MB -> 10 GB)
- ローカルでテストするのが簡単 (Lambda コンテナイメージをローカルでテストする)
デプロイ方法
zipとコンテナイメージの両方を簡単な図で示すと以下のようになる。
terraformによるデプロイ
terraformによりlambdaの作成のみを行い、作成後のイメージ管理は行わない。
この場合、github actions等を用いて、イメージのbuild, push, lambdaの更新までを行うと管理が楽になる。
resource "aws_lambda_function" "function" {
function_name = "<Function name>"
description = "<Description>"
package_type = "Image"
image_uri = "<Account id>.dkr.ecr.<Region>.amazonaws.com/<ECR>:<Tags>"
timeout = <Timeout>
lifecycle {
ignore_changes = [image_uri]
}
role = <Role arn>
}
terraformでイメージ管理を行わない場合、イメージ更新の際はupdate-function-code
を用いると良い。
コマンド例は以下の通り。
aws lambda update-function-code --function-name "<Function name>" --image-uri "<Account id>.dkr.ecr.<Region>.amazonaws.com/<ECR>:<Tags>"
気づき
パブリックイメージは使用できない
パブリックイメージは使用できず、自アカウントのイメージを指定する必要がある。
このことに気づいたのは、ダミーとして適当なイメージを使おうとして、パブリックイメージが指定できなかったためである。
terraformによりイメージを管理しないと、lambda生成時にはダミーイメージを用いたら以下の二点が便利である。
- 簡素なmoduleが用意できる (必要な引数は
function_name, description, role
で、あとはデフォルト値を設定) - lambdaとecrを一度に作成できる (ダミーを使わない場合、lambdaを作る前にecrを作り、イメージをpushしておく必要がある)
サクッとダミーイメージを用意する
そこでダミーイメージを簡単に作れるようにした (yoshi65/lambda_hello_world_image)。
以下の手順で、ecrにdummy:latest
が生成できる。事前に、認証情報は設定しておく必要がある。
git clone https://github.com/yoshi65/lambda_hello_world_image.git
cd lambda_hello_world_image
./hello_world.sh
もし消したくなったら、以下の通り。
./hello_world.sh -d
この生成に、terraformを使うか考えたけど、
- ダミーイメージ自体はコンソールやcliから作る際にも活用できる
- ecrをterraformで作ったところで、結局イメージプッシュのためのスクリプトは必要
などにより、使わなかった (気が向いた時に追加するかも)。
update-function-code
後、すぐinvoke
できない
lambdaを使用する際に、$LATEST
を使わず、aliasを指定して、invoke
することは多い。
そこで、動作確認のためにinvoke
し、正常終了を確認してから、aliasを更新しようとした。
その時、invoke
において
-
$LATEST
を指定すると前のバージョンが使われる -
update-function-code
でパブリッシュされたバージョンを使うとResourceConflictException
が生じる
invoke
できないわけ
この理由としては、イメージの最適化が挙げられる。
コンソール上でイメージ更新を確認したことがあればわかると思うが、更新後すぐは更新中といった旨が上部に表示され、しばらくしたら完了の旨が表示される。
invoke
するために
解決法としては、ステータスの更新を待てばいい。
以下のコマンドで解決する。
aws lambda wait function-updated --function-name "<Function name>"
lambdaの更新、待機、起動をまとめると、
aws lambda update-function-code --function-name "<Function name>" --image-uri "<Image uri>" --publish
aws lambda wait function-updated --function-name "<Function name>"
aws lambda invoke --function-name "<Function name>":\$LATEST response.json
感想
好みはありそうだが、コンテナイメージの方がzipより使い勝手はよかった。
コンテナイメージで設定していることが多いため、lambdaを作る際に必要な設定が減る。
Discussion