--- title: "TerraformでAWS Lambda Function URLsをデプロイする" date: "2022-04-16T14:03:05+0900" tags: ["lambda", "terraform", "aws"] --- https://aws.amazon.com/jp/about-aws/whats-new/2022/04/aws-lambda-function-urls-built-in-https-endpoints/ AWS LambdaでHTTPSエンドポイントがデフォルト利用できるようになり、API Gatewayを付与する必要がなくなった。早いもので、すでにServerless FrameworkもTerraformも対応しているのだが、せっかくなのでLambdaのデプロイには使ったことがない、Terraformで試してみた。 ## Terraform with AWS Lambda AWS LambdaでTerraformを管理するというのはあまり一般的なケースではなく、僕もServerless Frameworkなどを使うことが多い。 改めて、なぜTerraformでAWS Lambdaを管理しないのか、言語化してみるとポイントはいくつかある。 ### Terraformはattribute差分による状態管理を行う Terraformの基本的な考え方は、クラウドリソースのattributeについて、HCLで記述された状態と実際の状態とを比較し、差分があればそれを適用の対象とする、というものである。AWS Lambdaの場合はソースコードをデプロイするわけだが、その差分はソースコードをzip化したもののハッシュ値を用いて比較することが多い。 しかし、Lambdaでアップロードするzipには、依存ライブラリなどすべてのファイルを含めることになるので、ライブラリインストールにおいて予期せぬ差分が発生する場合がままある。その上Terraformの `plan` 結果で表示されるのはハッシュ値の差分だから、何が実際の差分なのかは判別ができない。 ### TerraformはあくまでAWS APIのラッパー Terraformは基本的にAWS APIをラップするものでしかない。従ってAWS LambdaのFunctionを作成、変更、削除はできるが、コードの依存ライブラリをインストールして、zipに圧縮して、といった作業をうまいことお膳立ててくれるわけではない。Terraformのbuilt-inな機能を使えば実現は可能だが、Serverless Frameworkなど専用のフレームワークを使ったほうが上手いこと付随処理を隠蔽してくれる。 ## Example そういったデメリットを理解しつつ、試しに書いてみたTerraformが以下の通り。 ```hcl resource "null_resource" "lambda_function_pre_build" { triggers = { packages = filebase64sha256("${path.root}/function/package.json") } provisioner "local-exec" { working_dir = "${path.root}/function" command = "npm i" } } data "archive_file" "lambda_function" { type = "zip" source_dir = "${path.module}/function" output_path = "${path.module}/lambda.zip" depends_on = [ null_resource.lambda_function_pre_build, ] } resource "aws_iam_role" "iam_for_lambda" { name = "iam_for_lambda" managed_policy_arns = [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", ] assume_role_policy = <