Amazon EventBridge Scheduler から CodeBuild を定期スケジュールで実行する方法の備忘録。AWS のマネジメントコンソールから設定する場合は 公式ドキュメントの Getting started with EventBridge Scheduler を見ながら設定すると良いでしょう。この記事では主に Terraform による構築方法を紹介します。Terraform は 1.7.3、AWS provider は 5.38.0 で動作確認しました。
目次
CodeBuild
aws_codebuild_project を参考に設定します。詳細は省略しますのでリンク先をご確認ください。environment_variable
は後で扱うので残してあります。
resource "aws_codebuild_project" "example" {
...
environment {
...
environment_variable {
name = "MY_VARIABLE"
value = "foo"
type = "PLAINTEXT"
}
...
}
...
}
IAM Role
Scheduler から CodeBuild を実行するために IAM Role が必要です。ここは呼び出すサービスによって許可をする Action が異なります。CodeBuild を実行する場合は以下のように IAM Role を作成し、codebuild:StartBuild
Action を許可します。
data "aws_caller_identity" "current" {}
resource "aws_iam_role" "scheduler_schedule" {
name = "my-scheduler-schedule-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "scheduler.amazonaws.com"
}
Action = "sts:AssumeRole",
Condition = {
StringEquals = {
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
},
]
})
inline_policy {
name = "CodeBuildStartPolicy"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"codebuild:StartBuild",
],
Resource = [
aws_codebuild_project.example.arn
]
},
]
})
}
}
その他のサービスを呼び出したい場合は Using templated targets - EventBridge Scheduler を参考に設定をします。AWS マネジメントコンソールから作成するとサービスごとに必要な IAM Role を作ってくれるオプションがあるので、まず AWS マネジメントコンソールから IAM Role を作成し、その内容を Terraform に転記しても良いでしょう。
Scheduler
aws_scheduler_schedule を参考に設定します。このあと注目すべきポイントを解説します。
resource "aws_scheduler_schedule_group" "example" {
name = "my-schedule-group"
}
resource "aws_scheduler_schedule" "example" {
name = "my-schedule"
group_name = aws_scheduler_schedule_group.example.name
flexible_time_window {
mode = "OFF"
}
schedule_expression_timezone = "Asia/Tokyo"
schedule_expression = "cron(0 8 ? * 2-6 *)"
target {
arn = aws_codebuild_project.example.arn
role_arn = aws_iam_role.scheduler_schedule.arn
retry_policy {
maximum_retry_attempts = 0
}
input = jsonencode({
environmentVariablesOverride = [
{
name = "MY_VARIABLE",
type = "PLAINTEXT"
value = "bar",
},
]
})
}
}
cron 構文
Schedule types on EventBridge Scheduler | Cron-based schedules を参考に設定します。Linux の crontab とは書式が少し異なることに注意しましょう。
schedule_expression_timezone = "Asia/Tokyo"
schedule_expression = "cron(0 8 ? * 2-6 *)"
target
呼び出したいサービスの ARN と、サービスを呼び出す権限を定義した IAM Role の ARN を設定します。
target {
arn = aws_codebuild_project.example.arn
role_arn = aws_iam_role.example.arn
target.input
サービスにパラメータを渡したい場合は input に設定をします。以下は CodeBuild に 環境変数を渡すときの例。CodeBuild で設定できるパラメータは AWS CodeBuild API Reference | StartBuild を参照。
target {
...
input = jsonencode({
environmentVariablesOverride = [
{
name = "MY_VARIABLE",
type = "PLAINTEXT"
value = "bar",
},
]
})
その他のサービスで設定ができるパラメータは、Using templated targets - EventBridge Scheduler と、各サービスの API Reference を確認すると良いでしょう。
cron の定義とパラメータが異なる Schedule をいくつか定義したい場合
cron の定義とパラメータだけが異なる Schedule をいくつか定義したい場合は、以下のように for_each
を使うとコード量が減ります。
variable "cron_schedules" {
description = "cron schedule list and parameters"
type = map(object({
hour = number
minute = number
my_variable = string
}))
default = {
"0700" = { hour = 7, minute = 0, my_variable = "foo" },
"0800" = { hour = 8, minute = 0, my_variable = "bar" },
"0900" = { hour = 9, minute = 0, my_variable = "baz" },
}
}
resource "aws_scheduler_schedule" "example" {
for_each = var.cron_schedules
name = each.key
...
schedule_expression = "cron(${each.value["minute"]} ${each.value["hour"]} ? * 2-6 *)"
...
target {
...
input = jsonencode({
environmentVariablesOverride = [
{
name = "MY_VARIABLE",
value = each.value["my_variable"],
type = "PLAINTEXT"
},
]
})
}
}