0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EC2インスタンスを定期的に起動・停止する(EventBridgeSchedulerを使って)

Posted at

概要

RDSへアクセスする際によくある構成として、EC2インスタンスの踏み台サーバーを作成してアクセスすることがあると思います。
例に漏れず現場でもそのような構成でRDSにアクセスしているのですが、
コストカット施策の一環で踏み台サーバーの稼働時間を平日日中だけにしたいという要件が降ってきました。

ネット上ではEventBridgeルールによるスケジュール設定が割と溢れているのですが、
せっかくならより高性能なEventBridge Schedulerを使ってやりたいなぁと思い頑張ってみました。
https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/scheduler.html

作った時のハマった点も含めて紹介していこうかと思います。

既にあるEC2インスタンスに対してEventBridgeSchedulerを割り当てる想定で記載していきます。
VPCやサブネット,EC2インスタンスの立て方などに関しては割愛します。

EventSchedulerで利用するロールの作成

EventSchedulerから起動するために必要なロール、ポリシーを作成します。
jump-hostというロール名にしています。

# 自動起動,停止の権限
data "aws_caller_identity" "self" {}
resource "aws_iam_role" "jump-host" {
  name               = "jump-host"
  assume_role_policy = file("./resources/assume_policy.json")
}
resource "aws_iam_policy" "jump-host" {
  name   = "jump-host"
  policy = templatefile("./resources/policy.json", {
    account-id : data.aws_caller_identity.self.id
  } )
}
resource "aws_iam_role_policy_attachment" "jump-host" {
  role       = aws_iam_role.jump-host.id
  policy_arn = aws_iam_policy.jump-host.arn
}

IAMロールに紐づけるassumeポリシーの詳細です。
今回はEventBridge Schedulerから使われる想定のため、Principalにscheduler.amazonaws.comを記載してます。

./resources/assume_policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": ["scheduler.amazonaws.com"]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

IAMロールに紐づけるポリシーの詳細です。

EC2インスタンスを定期起動・停止する方法はいくらかあると思います。
(SystemsMangaerのオートメーション機能とかもそれっぽい形でできそうなんだということが調べていて知りました)

今回の手順ではEC2に対して直接APIを投げるシンプルな形にしようかと思うので、StartInstances,StopInstancesAPIを叩くことにします。
よってEC2インスタンスを起動・停止させたいため以下のようなポリシーを設定します。

./resources/policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:StartInstances",
        "ec2:StopInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:${account-id}:instance/*",
        "arn:aws:license-manager:*:${account-id}:license-configuration:*"
      ]
    }
  ]
}

EventSchedulerの作成

まずはソースから。

resource "aws_scheduler_schedule" "jump-host-stop" {
  name = "jump-host-stop"
  description = "踏み台サーバの停止"
  schedule_expression = "cron(0 21 ? * MON-FRI *)"
  schedule_expression_timezone = "Asia/Tokyo"
  flexible_time_window {
    mode = "OFF"
  }
  target {
    arn      = "arn:aws:scheduler:::aws-sdk:ec2:stopInstances"
    role_arn = aws_iam_role.jump-host.arn
    input    = <<EOF
{
  "InstanceIds": ["${aws_instance.jump-host.id}"]
}
EOF
  }
}

resource "aws_scheduler_schedule" "jump-host-start" {
  name = "jump-host-start"
  description = "踏み台サーバーの起動"
  schedule_expression = "cron(0 8 ? * MON-FRI *)"
  schedule_expression_timezone = "Asia/Tokyo"
  flexible_time_window {
    mode = "OFF"
  }
  target {
    arn      = "arn:aws:scheduler:::aws-sdk:ec2:startInstances"
    role_arn = aws_iam_role.jump-host.arn
    input    = <<EOF
{
  "InstanceIds": ["${aws_instance.jump-host.id}"]
}
EOF
  }
}

肝となるのがtargetブロックです。

  target {
    arn      = "arn:aws:scheduler:::aws-sdk:ec2:startInstances"
    role_arn = aws_iam_role.jump-host.arn
    input    = <<EOF
{
  "InstanceIds": ["${aws_instance.jump-host.id}"]
}
EOF
  }

ターゲットの指定方法はいくつかあるのですが、
より汎用的な指定方法としてarnにユニバーサルターゲットを指定する方法があります。
ここにStartInstances,StopInstancesとパラメーターとしてEC2インスタンスのidを渡してあげれば無事にスケジュール登録完了となります。
https://docs.aws.amazon.com/ja_jp/scheduler/latest/UserGuide/managing-targets-universal.html

書式としてはこんな感じになります。
arn:aws:scheduler:::aws-sdk:service:apiAction

で、ここ、私のつまずきポイントだったのですが、
apiActionキャメルケースで書く必要があります。
(StartInstancesのドキュメントとか大文字でかかれているので、ここにつまずき小一時間持ってかれました)

まとめ

EventBridgeSchedulerを利用してEC2インスタンスを定期的に起動・停止する方法についてまとめてみました。
ルールに比べてタイムゾーン指定できたり色々と便利ですね。
少しずつルールから書き換えていきたいと思います。

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?