Closed9
terraformでAWS/Lambdaをデプロイする
LambdaもIaCしたい、ということでterraformで管理する方法を模索してみる
とりあえず最小構成?を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
深堀
archive_file
ファイルやディレクトリからzipファイルを作れる
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が検知できない
ログ周り追加
cloudwatch logs、iam policyのログ周りも追加。
ログ周りのサンプルがあるのでこちらを参照する
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
}
動作確認
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 '<ログストリーム>'
コードの中身を変更する
変更後の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
requirements.txtを読み込ませるのは無理?
LambdaLayerを使うことになりそうかな、使ったことないので、次回試す
このスクラップは2023/05/16にクローズされました