要約
最終的なソースコード全体は以下のリンクからご確認いただけます。
関連記事
Go言語で記述したスクリプトを、AWSのLambdaにTerraformを用いてデプロイする機会があり、その過程の試行錯誤を整理して一連の記事にまとめました。
この記事はそのうちの3本目として、GoのスクリプトをAWS EventBridgeから定期実行する構成をデプロイしてみたいと思います。
- zipファイルを用いてGo言語の処理をAWS Lambdaにデプロイする
- Dockerイメージを用いてGo言語の処理をAWS Lambdaにデプロイする
- EventBridgeからAWS Lambdaを定期実行する処理をデプロイする(この記事)
概要
AWS Lambdaの使い道は色々ありますが、その1つにバッチ処理のように定期的に実行したい処理を行うというのもあるかと思います。例えば定時にEC2のインスタンスが起動しているのかを確認したり、毎時ヘルスチェックをしたり、といった用途です。
そこでこの記事では、Amazon EventBridgeをトリガーに定期的に処理が実行されるLambda関数を、Terraformでデプロイするということを目指します。なお、Lambda関数をTerraformでデプロイするというのは、上記にあげた記事で説明していますので、こちらをご参照ください。
実装
今回のディレクトリ構造は以下の様になっています。以前までのLambda関数の記事からの続きで、Dockerを用いてデプロイする方法を利用したいと思います。
cloud_watch.tf
、event-bridge-assume-role.json
、event-bridge.tf
のファイルが追加されて、lambda.tf
を一部修正しました。
.
├── .gitignore
├── docker
│ └── Dockerfile
├── image_digest.txt
├── src
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── terraform
├── .gitignore
├── .terraform
├── .terraform.lock.hcl
├── cloud_watch.tf
├── ecr.tf
├── event-bridge-assume-role.json
├── event-bridge.tf
├── lambda-assume-role.json
├── lambda.tf
├── main.tf
└── terraform.tfstate
ログを見られるように設定
初めに、Lambda関数の実行ログをCloudWatch Logsに記録しておき、後から見られるように設定しておきます。本当に定期的に実行されているのかを確認するためです。
まず以下の様にLambdaのロールにAWSLambdaBasicExecutionRole
のポリシーを追加します。このポリシーは公式のドキュメントにもあるように、CloudWatchへのログ書き込みの最低限の権限が用意されています。
resource "aws_iam_role" "lambda_role" {
name = "role-for-test_lambda"
assume_role_policy = file("lambda-assume-role.json")
+ managed_policy_arns = [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ]
}
それから、CloudWatchのロググループについてもTerraformで定義しておきます。念の為ログの保持期間(retention_in_days
)も3日と短めに設定しておきましょう。
resource "aws_cloudwatch_log_group" "test_lambda" {
name = "/aws/lambda/${aws_lambda_function.test_lambda.function_name}"
retention_in_days = 3
skip_destroy = false
}
EventBridgeのIAMの設定
続いて、定期的にLambdaを呼び出し実行するEventBridgeの権限を設定しておきます。欲しい権限は「対象のLambdaを実行する」権限です。以下のようにactionとして"lambda:InvokeFunction"
を、resourcesとしてterraform.tf
で定義しているaws_lambda_function.test_lambda
のarnを指定します。
################## IAMの設定 ##################
resource "aws_iam_role" "event_bridge" {
name = "role-for-test_lambda-event_bridge"
assume_role_policy = file("event-bridge-assume-role.json")
}
resource "aws_iam_role_policy" "event_bridge" {
name = "role_policy-for-test_lambda-event_bridge"
role = aws_iam_role.event_bridge.name
policy = data.aws_iam_policy_document.event_bridge.json
}
data "aws_iam_policy_document" "event_bridge" {
statement {
effect = "Allow"
actions = [
"lambda:InvokeFunction",
]
resources = [
aws_lambda_function.test_lambda.arn,
]
}
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "scheduler.amazonaws.com"
},
"Sid": "",
"Effect": "Allow"
}
]
}
EventBridge本体の設定
最後にEventBridge本体の設定をしていきます。定期実行のタイミングはcron
式で設定することができます。Linuxに慣れている人なら取っ付きやすいですね。以下の例ならschedule_expression
に"cron(0/3 * * * ? *)"
と設定し、3分おきにLambda関数が実行されるようにしています。
確認しやすいように実行間隔を短くしています。実行し過ぎによる課金などにはご注意ください。
どのLambda関数を実行するかを以下のtarget
ブロックに書いていきます。実行対象のLambdaのと、実行ためのIAMロール(role_arn
)のarn
を指定しています。これらのarn
は、今まで定義してきたリソースの属性を参照しています。
################## EventBridgeの本体 ##################
resource "aws_scheduler_schedule" "test_lambda" {
name = "test_lambda-event_bridge"
schedule_expression = "cron(0/3 * * * ? *)"
schedule_expression_timezone = "Asia/Tokyo"
flexible_time_window {
mode = "OFF"
}
target {
arn = aws_lambda_function.test_lambda.arn
role_arn = aws_iam_role.event_bridge.arn
}
}
動作確認
これでterraform apply
として適用すると、以下のログのように3分おきに関数が実行され、その様子がログとして出力されていることが確認できました。
参考