この記事の目的
AWS Lambda LayerをTerraform化しました。
一部手間取ったので、自分と同僚用にメモを残します。
まず結論
最終的に出来上がったTerraformはこちらです。
Terraform version
$ terraform version
Terraform v0.12.24
Layerを使用するLambda側
resource "aws_lambda_function" "main_lambda" {
filename = "../../lambda_function/test_lambda/test_lambda.zip"
function_name = "test_lambda"
role = aws_iam_role.lambda_iam_role.arn
handler = "lambda_function.lambda_handler"
timeout = 30
runtime = "python3.8"
layers = ["${aws_lambda_layer_version.lambda_layer.arn}"]
}
Layer側
resource "aws_lambda_layer_version" "lambda_layer" {
layer_name = "test_layer"
filename = "../../lambda_layer/test_layer/test_layer.zip"
compatible_runtimes = ["python3.8"] # Lambda関数と互換性のあるruntimeを設定
source_code_hash = "${filebase64sha256("../../lambda_layer/test_layer/python.zip")}"
}
ハマったところ①
Layerのfilenameに設定しているzipファイルの圧縮単位にコツがいった。
初めは、../../lambda_layer/test_layer/test_layer.pyのtest_layer.pyをzip化していた。
ところが、Terraforを実行してLambdaとLayerが作成されるも、LambdaからLayerが読み込めない。
どうやら、LayerはLambda内の/opt/pythonに展開しないといけないらしい。
そこで、Layerを../../lambda_layer/test_layer/python/test_layer.pyに置き、pythonごとzip化したら解決。
ハマったところ②
Layerにはバージョンというものがあり、Layerのpyファイルを更新して再度アップロードすると、Layerのバージョンが上がるようになっている。
古いバージョンのLayerも残っており、使用することができる。
おそらく、Lambda Aではバージョン1のLayer、Lambda Bでは最新バージョンのLayerを使用したい、という使い分けのためだろうと思われる。

初め、以下のようにsource_code_hashを設定していなかった。
すると、test_layer.pyを更新してtest_layer.zipを再作成しても、Terraform実行後のLayerのバージョンが上がらない。ずっと1のままだ。
resource "aws_lambda_layer_version" "lambda_layer" {
layer_name = "test_layer"
filename = "../../lambda_layer/test_layer/test_layer.zip"
compatible_runtimes = ["python3.8"] # Lambda関数と互換性のあるruntimeを設定
}
source_code_hashを設定すると、Layer自体のバージョン及びLambdaにひもづくLayerのバージョンも最新のものに上がるようになった。
でもこれ、今はいいけどいずれTerraform上でLambda毎にLayerのバージョン指定したくなったらどうするのか……
aws_lambda_layer_version.lambda_layer.arnはバージョン付きのARNだけど、aws_lambda_layer_version.lambda_layer.layer_arnはバージョンなしのARNらしいので、その辺をうまく使うのかもしれない。
必要になったら検証します。報告するかは不明。
以上