Techfirm Cloud Architect Blog

テックファーム株式会社クラウドインフラグループのブログ

【AWS】EC2の自動起動/停止をTerraformで実装

はじめに

以前、こちらの記事でAmazon EventBridgeを使った、EC2の起動・停止を自動化する方法、を紹介しました。

techblog.techfirm.co.jp

この仕組みを、Terraformで作成している環境に追加する機会がありましたので、コードを紹介します。

前提

今回は既存環境への追加を前提とするため、追加に必要なコードのみ記載します。
また、起動・停止時間や対象は前回の記事同様とします。

  • 東京リージョンのオンデマンドEC2インスタンス1台が対象
  • 月~金曜日の10:00~19:00の間だけ起動し、それ以外の曜日・時間は停止状態にする

Terraformコード解説

IAMロール作成

まず、IAMロール作成部分のコードです。
前記事「EventBridge用IAMロールの作成」の部分です。

resource "aws_iam_role" "role_eventbridge_control_ec2" {
  name = "role-eventbridge-control-ec2"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": [
         "events.amazonaws.com"
         ]
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "role_eventbridge_control_ec2" {
  role       = aws_iam_role.role_eventbridge_control_ec2.id
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole"
}

まず上部のaws_iam_roleリソースでIAMロールを作成しています。
その中で、信頼ポリシーを前記事と同じものにしています。
さらに下部のaws_iam_role_policy_attachmentリソースでAmazonSSMAutomationRoleのポリシーをアタッチしています。

EventBridge起動用ルール作成

次に、EventBridgeの起動用ルールを作成します。

resource "aws_cloudwatch_event_rule" "eventbridge_control_ec2_start" {
  name        = "eventbridge-control-ec2-start"
  is_enabled  = true

  # 月~金の朝10:00に起動
  schedule_expression = "cron(0 1 ? * MON-FRI *)"
}

resource "aws_cloudwatch_event_target" "eventbridge_control_ec2_start" {
  target_id = "StartInstance"
  rule      = aws_cloudwatch_event_rule.eventbridge_control_ec2_start.name
  arn       = "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartEC2Instance:$DEFAULT"
  role_arn  = aws_iam_role.role_eventbridge_control_ec2.arn

  input = <<EOF
{
  "InstanceId": ["i-0123456789abcde"]
}
EOF
}

まず、上部のaws_cloudwatch_event_ruleリソースでルール名、有効化(/無効化)、スケジュールを設定しており、前記事同様のCron式で実行スケジュールを指定しています。
is_enabled = falseで作成すると、無効化状態で作成することができるので、動かす前にAWSマネジメントコンソールから確認を行えます。

次に、下部のaws_cloudwatch_event_targetリソースで実行する内容を設定しています。
arnで実行するSSMドキュメント、role_arnで使用するIAMロール、inputで実行時に渡す内容を指定しています。
なお、複数台同時に指定したい場合はInstanceId部分を以下のように変更します。
"InstanceId": ["i-0123456789abcde", "i-000000000000000"]

EventBridge停止用ルール作成

同じように、EventBridgeの停止用ルールを作成します。

resource "aws_cloudwatch_event_rule" "eventbridge_control_ec2_stop" {
  name        = "eventbridge-control-ec2-stop"
  is_enabled  = true

  # 月~金の夜19:00に止める
  schedule_expression = "cron(0 10 ? * MON-FRI *)"
}

resource "aws_cloudwatch_event_target" "eventbridge_control_ec2_stop" {
  target_id = "StopInstance"
  rule      = aws_cloudwatch_event_rule.eventbridge_control_ec2_stop.name
  arn       = "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StopEC2Instance:$DEFAULT"
  role_arn  = aws_iam_role.role_eventbridge_control_ec2.arn

  input = <<EOF
{
  "InstanceId": ["i-0123456789abcde"]
}
EOF
}

ほとんど同じですが、target_idをStopInstanceに、実行するSSMドキュメントをAWS-StopEC2Instanceに変更しています。
また、スケジュールのCron式を19時に動くよう変更しています。

以上で、Terraformのコード説明は終わりです。
ご自身の環境でinit ~ plan ~ applyを行い、環境に適用することで、対象としたEC2の自動起動・自動停止を行うリソースが作成できます。

作成したリソースをAWSマネジメントコンソール上から確認したい場合は、前記事を参考にしてみてください。
techblog.techfirm.co.jp

おわりに

今回は、以前ご紹介したEC2自動起動・自動停止の仕組みを、Terraformで実装するコードを解説しました。
Terraformで管理している環境へ追加する際の参考になれば幸いです。

参考

  1. Resource: aws_cloudwatch_event_rule(Terraformドキュメント) https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule
  2. Resource: aws_cloudwatch_event_target(Terraformドキュメント) https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target.html