概要
600本あるLambda関数をデプロイする必要があったのでその時の対応をメモ
- 1つずつ書く → さすがにこれはNG
- Function名一覧を定義してfor_eachでまわす → Function名一覧作るんもツライ
ってことでどうにか楽できないかというので取った対応です
前提
まず前提条件として、全Lambda関数が全て同じ設定になるようにする必要があります
- 環境変数はLambda内でSSM Parameter Storeから取得する
- zipファイル名は Function名.zip とする
- ランタイム・アーキテクチャは全て同じにする
コード
zipファイルがローカルにある場合
filesetでzipファイルの一覧を取得して Function名 => zipファイル名 というmapを作成
locals {
functions = {
for f in fileset(var.dir_path, "*.zip") :
trimsuffix(f, ".zip") => f
}
}
これをもとにfor_eachでまわします
resource "aws_lambda_function" "batch" {
for_each = local.functions
function_name = each.key
filename = "${var.dir_path}/${each.value}"
source_code_hash = filebase64sha256("${var.dir_path}/${each.value}")
handler = "lambda_function.lambda_handler"
role = aws_iam_role.lambda.arn
runtime = "python3.9"
}
zipファイルがs3にある場合
aws_s3_bucket_objectsでファイル一覧を取得し、これも同じように Function名 => zipファイル名 というmapを作成
data "aws_s3_bucket_objects" "files" {
bucket = var.bucket_name
}
locals {
functions = {
for f in data.aws_s3_bucket_objects.files.keys :
trimsuffix(f, ".zip") => f if can(regex("\\.zip$", f))
}
}
これをもとにfor_eachでまわします
resource "aws_lambda_function" "batch" {
for_each = local.functions
function_name = each.key
s3_bucket = var.bucket_name
s3_key = each.value
handler = "lambda_function.lambda_handler"
role = aws_iam_role.lambda.arn
runtime = "python3.9"
}
ローカル用で16行、s3用で19行で書けました
さすがに実行時間は・・・ですが(笑)
まとめ
実行時間を考えると、Lambda関数の更新のたびにTerraformを実行するというのはなかなか難しいですね
(実際に、初回だけTerraformでデプロイし更新については別の仕組みでデプロイしています)