Closed9

terraformでAWS/Lambdaをデプロイする

not75743not75743

とりあえず最小構成?をChatGPTくんに作ってもらった

ディレクトリ構成

.
├── lambda_function
│   └── main.py
├── main.tf

tfファイル

main.tf
data "archive_file" "example_zip" {
  type        = "zip"
  source_dir  = "${path.module}/lambda_function"
  output_path = "${path.module}/example_lambda.zip"
}

resource "aws_lambda_function" "example_lambda" {
  function_name    = "example-lambda"
  handler          = "main.handler"
  runtime          = "python3.10"
  filename         = data.archive_file.example_zip.output_path
  source_code_hash = data.archive_file.example_zip.output_base64sha256

  role = aws_iam_role.lambda_role.arn
}

resource "aws_iam_role" "lambda_role" {
  name = "example-lambda-role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

実行するもの

main.py
import json

def handler(event, context):
    response = {
        'statusCode': 200,
        'body': 'Hello, Lambda!'
    }
    return response

テスト

$ aws lambda invoke --function-name example-lambda output.txt
$ cat output.txt 
{"statusCode": 200, "body": "Hello, Lambda!"}

OK

not75743not75743

aws_lambda_function

Lambdaの設定を記述する

main.tf
resource "aws_lambda_function" "example_lambda" {
  function_name    = "example-lambda"
  handler          = "main.handler"
  runtime          = "python3.10"
  filename         = data.archive_file.example_zip.output_path
  source_code_hash = data.archive_file.example_zip.output_base64sha256

  role = aws_iam_role.lambda_role.arn
}

handler

Lambdaがコードを実行する際に呼び出す関数名のこと
<ファイル名>.<関数名>で表される。

source_code_hash

アップデートのトリガーに使用されるハッシュ。
これが無いとコードを修正した際にterraformが検知できない

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function

not75743not75743

ログ周り追加

cloudwatch logs、iam policyのログ周りも追加。
ログ周りのサンプルがあるのでこちらを参照する
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#example-usage

cloudwatch logs

main.tf
resource "aws_cloudwatch_log_group" "example_log_group" {
  name = "/aws/lambda/${aws_lambda_function.example_lambda.function_name}"
  retention_in_days = 30
}

権限周り

main.tf
# IAMポリシー
resource "aws_iam_policy" "lambda_policy" {
  name        = "example-lambda-policy"
  description = "IAM policy for the example Lambda function"

  policy = jsonencode({
    Version   = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource = [
          aws_cloudwatch_log_group.example_log_group.arn,
          "${aws_cloudwatch_log_group.example_log_group.arn}:*"
        ]
      }
    ]
  })
}

# ポリシーとロールの紐づけ
resource "aws_iam_role_policy_attachment" "lambda_policy_attachment" {
  role       = aws_iam_role.lambda_role.name
  policy_arn = aws_iam_policy.lambda_policy.arn
}
not75743not75743

動作確認

terraform実行

terraform apply --auto-approve

Lambda動作確認

aws lambda invoke --function-name example-lambda output.txt

ログ確認

# ログストリームを出力
aws logs describe-log-streams --log-group-name /aws/lambda/example-lambda

# ログ閲覧
aws logs get-log-events --log-group-name /aws/lambda/example-lambda --log-stream-name '<ログストリーム>'
not75743not75743

コードの中身を変更する

変更後のterraform apply

$ terraform apply
... 略 ...
  # aws_lambda_function.example_lambda will be updated in-place
  ~ resource "aws_lambda_function" "example_lambda" {
      ~ source_code_hash               = "Sz6ADScqeMpguMBqwx6fnki6sL7+0UzCmBnLQlZbanE=" -> "Bn0OTrmBfM2nmtlkC5PWmYdq89jCBvNxgl6k/BGNJrc="

このようにハッシュ値でChangeとなればOK

このスクラップは2023/05/16にクローズされました