はじめに
Terrformを使ってインフラ管理しているのですが、Lambdaのデプロイにちょっと手間取ったので、記録を残しておきます。
実現したいこと
- Github Actions + TerraformでLambdaをデプロイしたい
- LambdaコードはTerraformコードとは別ディレクトリで管理(同じリポジトリではある)
- 言語はGo
- Lambdaのコードに変更があった場合と、Terraform側のコードに変更があった場合のみデプロイが実行されるようにしたい
Github ActionsでTerraformを扱えるようにする
OIDCを使って、Github ActionsでTerraformを扱えるようにする記事は色々ありますので、細かい説明は割愛させていただきます。
Terraform
terraformの階層と違う階層にLambdaのファイルを保存したいと思いますので、その前提で以下のようなコードになります。
resource "terraform_data" "build_lambda" {
// ファイルに変更があった場合のみ以下を実行
triggers_replace = {
file_content = md5(file("../lambda/main.go")) // 相対パスでLambdaファイルを指定
// ファイルでなくディレクトリを指定したい場合は以下
// file_content = sha1(join("", [for f in fileset("../lambda", "*") : filesha1("../lambda/${f}")]))
}
provisioner "local-exec" {
command = "cd ../lambda/ && GOOS=linux GOARCH=amd64 go build -o ../bootstrap" // ファイルの出力場所を指定する
}
}
data "archive_file" "lambda" {
type = "zip"
source_file = "${path.module}/bootstrap"
output_path = "${path.module}/go.zip"
// path.moduleはこのモジュールが配置されているディレクトリ
depends_on = [terraform_data.build_lambda]
}
resource "aws_lambda_function" "some_func" {
filename = "${path.module}/go.zip"
function_name = "some-function"
role = aws_iam_role.iam_for_lambda.arn
handler = "bootstrap"
memory_size = 128
timeout = 300
source_code_hash = data.archive_file.lambda.output_base64sha256
runtime = "provided.al2023"
// build_lambdaしないと失敗するので、depends_onでbuild_lambdaがあれば実行されるようにする
depends_on = [terraform_data.build_lambda]
}
注意点
terraform plan時点では、bootstrapというファイルは存在しないため、"archive_file"が失敗します。
そのため、空のbootstrapというファイルを設置しておく必要があります。