開発環境のAmazon Auroraクラスターを利用時間外に自動停止してコスト削減する

f:id:liquid-tech:20211029131215p:plain

はじめに

こんにちは!Liquidインフラチームの野々山です。

この投稿では、AWS EventBridgeとAWS Systems Managerを用いて、Amazon Auroraクラスターの起動・停止を自動制御する方法を紹介します。

サンプルのterraformコードも掲載していますので、もし機会がありましたら試してみてください!


背景

Liquid eKYCでは、主にAWSを用いてインフラ構築を行っています。

サービス提供開始から2年ほど経過し、サービスの利用者数の増加や機能追加とともに、AWSの利用料も増加の一途をたどっています。そのためインフラチームでは、安定したインフラ基盤を提供できるリソースを保ちつつ、様々なコスト削減に取り組んでいます。

コスト削減に対するアプローチはいくつかありますが、今回紹介するAuroraクラスターの起動・停止制御は「時間単位の従量制費用を削減する」類の一部になります。


方針

  • AWS Systems ManagerでAWSが提供しているドキュメント AWS-StartStopAuroraCluster を利用してAuroraクラスタを制御します。
  • AWS EventBridgeで、平日おおよそエンジニアが開発環境を利用開始・終了する時刻にルールが実行されるよう設定し、クラスターを起動・停止します。
    • Liquidでは個々人のワークスタイルに合わせるために、朝晩少し長めに開発環境を稼働させています。組織の方針次第ですが、働きづらくなるような行き過ぎたコスト削減は極力行わないよう気をつけています。
  • 上記利用を目的としたIAMロール・ポリシーを設定します。
  • terraformで構成管理します。

設定方法

前提として

  • Auroraクラスター cluster01 が存在する
  • terraformはバージョン1.0.1、AWS providerはバージョン3.57.0を使用する
  • 東京リージョン(ap-northeast-1)を使用する

ものとします。

1. IAMロール及びポリシーの設定

# IAM role
resource "aws_iam_role" "aurora_startstop" {
  name               = "aurora-startstop-role"
  path               = "/"
  assume_role_policy = data.aws_iam_policy_document.assume_aurora_startstop_role.json
}

data "aws_iam_policy_document" "assume_aurora_startstop_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = [
        "events.amazonaws.com",
        "rds.amazonaws.com",
        "ssm.amazonaws.com"
      ]
    }
  }
}

# IAM policy
resource "aws_iam_policy" "aurora_startstop" {
  name        = "aurora-startstop-policy"
  path        = "/"
  description = "autora startstop policy"
  policy      = data.aws_iam_policy_document.aurora_startstop.json
}

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

    actions = [
      "rds:DescribeDBClusters",
      "rds:StartDBCluster",
      "rds:StopDBCluster",
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "ssm:*",
    ]

    resources = ["*"]
  }
}

# IAM role policy attachment
resource "aws_iam_role_policy_attachment" "aurora_startstop" {
  role = aws_iam_role.aurora_startstop.name
  policy_arn = aws_iam_policy.aurora_startstop.arn
}
  • サンプルとして用意をしていますので、適宜リソースの制限を加えてください。

2. EventBridge Ruleの設定

# 平日の8時00分にクラスターを起動する
resource "aws_cloudwatch_event_rule" "start_aurora_cluster01" {
  name        = "start-aurora-cluster01"
  description = "Starts an Amazon Aurora DB cluster: cluster01"
  schedule_expression = "cron(00 23 ? * SUN-THU *)"
  is_enabled = true
}

# 平日の22時00分にクラスターを停止する
resource "aws_cloudwatch_event_rule" "stop_aurora_cluster01" {
  name        = "stop-aurora-cluster01"
  description = "Stops an Amazon Aurora DB cluster: cluster01"
  schedule_expression = "cron(0 13 ? * MON-FRI *)"
  is_enabled = true
}
  • schedule_expressionUTCで以下の記法で設定します:
  • is_enabled で 有効/無効の切り替えを行えるので、クラスターを常時起動したままにしたい場合は false を指定してapplyすれば、すぐに自動起動・停止を無効化できます。
  • (EventBridgeの前身はCloudWatch Eventsのため、terraformのリソース名には「cloudwatch」がそのまま残っています。)

3. EventBridge Targetの設定

resource "aws_cloudwatch_event_target" "start_aurora_cluster01" {
  arn       = "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartStopAuroraCluster:$DEFAULT"
  rule      = aws_cloudwatch_event_rule.start_aurora_cluster01.name
  role_arn  = aws_iam_role.aurora_startstop.arn
  input = <<INPUT
{
    "Action": [
        "Start"
    ],
    "ClusterName": [
        "cluster01"
    ]
}
INPUT
}

resource "aws_cloudwatch_event_target" "stop_aurora_cluster01" {
  arn       = "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartStopAuroraCluster:$DEFAULT"
  rule      = aws_cloudwatch_event_rule.stop_aurora_cluster01.name
  role_arn  = aws_iam_role.aurora_startstop.arn
  input = <<INPUT
{
    "Action": [
        "Stop"
    ],
    "ClusterName": [
        "cluster01"
    ]
}
INPUT
}
  • input 内の
    • ActionStart or Stop のいずれかを設定します
    • ClusterName :起動・停止をしたいクラスター名を設定します

4. 変更の反映

上記リソースをterraform applyします。


動作確認

上記をapplyすると、EventBridgeルール<https://ap-northeast-1.console.aws.amazon.com/events/home?region=ap-northeast-1#/rules>に以下が追加されます:

f:id:liquid-tech:20211029105130p:plain

ルールの編集画面にアクセスすると、ローカルタイムゾーンで直近10回イベントがいつトリガーされるか確認できます:

f:id:liquid-tech:20211029105234p:plain

Systems Managerのオートメーションの実行<https://ap-northeast-1.console.aws.amazon.com/systems-manager/automation/executions?region=ap-northeast-1>ページにアクセスすると、直近実行されたAuroraクラスターの起動・停止に成功したか確認することができます。

f:id:liquid-tech:20211029105247p:plain


参考

本対応の際、以下のサイトを参考にさせていただきました:

また、下記ページ内に制約事項として記載のある条件に該当するクラスター(Aurora グローバルデータベースの一部であるクラスターやAurora マルチマスタークラスターなど)に対しては、本投稿で記載した方法では設定できない可能性があります。条件に該当しないか事前に確認することをおすすめします。


おわりに

本記事で紹介した方法で、開発環境でのAurora利用料を大きく削減することができました。 インフラコストの削減対応は地道なものも多いですが

  • エンジニアとして、ビジネス上の収益改善を考えダイレクトにコミットできる
  • インフラリソースの持つキャパシティを正しく把握し、アーキテクチャへの理解を深められる

ような価値のある機会と個人的にとらえているので、他業務とうまく折り合いをつけながら継続して取り組みたいと思います!