LoginSignup
5
0

More than 1 year has passed since last update.

TerraformでEventBridge SchedulerのAtスケジュールを使って時限起動するLambdaを自動構築する

Last updated at Posted at 2022-12-10

はじめに

2022/11/10にEventBridgeにアップデートが入り、これまでのスケジュール方法以外にAtな起動がAsia/Tokyoのタイムゾーンの時間記述で作成できるようになった。これは超便利!
Terraformも2022/11/25に早々に対応されたようだ。

ということで、さっそくTerraformでサクッと自動構築をしてみよう。

起動するLambda

シンプルにイベントデータを表示するだけで作っておく。

example.py
import pprint

def lambda_handler(event, context):
  pprint.pprint(event)

上記を実行するLambdaの定義として以下のようにTerraformで作成する。
権限はこの後EvnetBridge Scheduler側のサービスロールに付与するため、Lambda Permissionの設定は不要のようだ。

################################################################################
# Lambda                                                                       #
################################################################################
data "archive_file" "example" {
  type        = "zip"
  source_dir  = "../scripts/example"
  output_path = "../outputs/example.zip"
}

resource "aws_lambda_function" "example" {
  depends_on = [
    aws_cloudwatch_log_group.lambda,
  ]

  function_name    = local.lambda_function_name
  filename         = data.archive_file.example.output_path
  role             = aws_iam_role.lambda.arn
  handler          = "example.lambda_handler"
  source_code_hash = data.archive_file.example.output_base64sha256
  runtime          = "python3.9"

  memory_size = 128
  timeout     = 600
}

################################################################################
# IAM Role for Lambda                                                          #
################################################################################
resource "aws_iam_role" "lambda" {
  name               = local.iam_role_name_lambda
  assume_role_policy = data.aws_iam_policy_document.lambda_assume.json
}

data "aws_iam_policy_document" "lambda_assume" {
  statement {
    effect = "Allow"

    actions = [
      "sts:AssumeRole",
    ]

    principals {
      type = "Service"
      identifiers = [
        "lambda.amazonaws.com",
      ]
    }
  }
}

resource "aws_iam_role_policy" "lambda_custom" {
  name   = local.iam_policy_name_lambda
  role   = aws_iam_role.lambda.name
  policy = data.aws_iam_policy_document.lambda_custom.json
}

data "aws_iam_policy_document" "lambda_custom" {
  statement {
    effect = "Allow"

    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ]

    resources = [
      "*",
    ]
  }
}

################################################################################
# CloudWatch Logs                                                              #
################################################################################
resource "aws_cloudwatch_log_group" "lambda" {
  name              = "/aws/lambda/${local.lambda_function_name}"
  retention_in_days = 3
}

################################################################################
# Lambda Permission                                                            #
################################################################################
resource "aws_lambda_permission" "allow_apigateway" {
  statement_id  = "AllowExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.example.function_name
  principal     = "scheduler.amazonaws.com"
}

EventBridge Schedulerを動かすのに必要なIAMロール

IAMロールは以下のように作成する。信頼関係されたエンティティのサービスとしてscheduler.amazonaws.comを指定しよう。
今回は単純にLambda実行するだけなので、個別の権限としてはlambda:InvokeFunctionがあれば良い。

################################################################################
# IAM Role for EventBridge Scheduler                                           #
################################################################################
resource "aws_iam_role" "eventbridge_scheduler" {
  name               = local.iam_role_name_eventbridge_scheduler
  assume_role_policy = data.aws_iam_policy_document.eventbridge_scheduler_assume.json
}

data "aws_iam_policy_document" "eventbridge_scheduler_assume" {
  statement {
    effect = "Allow"

    actions = [
      "sts:AssumeRole",
    ]

    principals {
      type = "Service"
      identifiers = [
        "scheduler.amazonaws.com",
      ]
    }
  }
}

resource "aws_iam_role_policy" "eventbridge_scheduler_custom" {
  name   = local.iam_policy_name_eventbridge_scheduler
  role   = aws_iam_role.eventbridge_scheduler.name
  policy = data.aws_iam_policy_document.eventbridge_scheduler_custom.json
}

data "aws_iam_policy_document" "eventbridge_scheduler_custom" {
  statement {
    effect = "Allow"

    actions = [
      "lambda:InvokeFunction",
    ]

    resources = [
      "*",
    ]
  }
}

EvnetBridge Schedulerの定義

さて、↑ここまでで準備は整ったので、あとは本丸のEventBridge Schedulerの定義だ。
ポイントは、schedule_expressionでatで指定している点だ。これはschedule_expression_timezoneで指定したタイムゾーンで動いてくれる。flexible_time_windowは、時間をずらして起動したい場合等に使えるが今回はOFFにする。targetで↑で作ったLambdaとIAMロールのARNを指定すれば準備完了だ。

################################################################################
# EventBridge Scheduler                                                        #
################################################################################
resource "aws_scheduler_schedule_group" "example" {
  name = local.eventbridge_scheduler_group_name
}

resource "aws_scheduler_schedule" "example" {
  name       = local.eventbridge_scheduler_schedule_name
  group_name = aws_scheduler_schedule_group.example.name

  state = "ENABLED"

  schedule_expression = "at(2022-12-10T22:18:00)"
  schedule_expression_timezone = "Asia/Tokyo"

  flexible_time_window {
    mode = "OFF"
  }

  target {
    arn      = aws_lambda_function.example.arn
    role_arn = aws_iam_role.eventbridge_scheduler.arn
  }
}

EvnetBridge SchedulerがLambdaに渡すイベントの形式

さて、上記で実行したLambdaの結果をCloudWatchで確認すると、以下のようにJSONが出力されている。
残念ながら、timeの部分はUTCになってしまうが、いつ起動予定のタスクだったかは確認できるようだ。

{
  "account": "XXXXXXXXXXXX",
  "detail": "{}",
  "detail-type": "Scheduled Event",
  "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "region": "ap-northeast-1",
  "resources": [
    "arn:aws:scheduler:ap-northeast-1:XXXXXXXXXXXX:schedule/eventbridge-scheduler-example-group/eventbridge-scheduler-example-schedule"
  ],
  "source": "aws.scheduler",
  "time": "2022-12-10T13:18:00Z",
  "version": "0"
}

これで、Atで時限起動するLambdaを簡単に作れるようになった!

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0