AWS Lambda LayerのTerraform化でハマったこと


この記事の目的

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.pytest_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らしいので、その辺をうまく使うのかもしれない。
必要になったら検証します。報告するかは不明。

以上