概要

Auroraクラスターの検証をしていて、とある理由で停止しておきたいけど、しばらくは削除したくないというときがある。
Auroraは自動的に停止7日後に自動で起動してきてしまう。
そこで、なんとかできないか色々見てたらEventBridgeと会社の同僚氏から提案されたSSMオートメーションの組み合わせが一番良かったので記録しておきます。

構成

  • Auroraクラスター
  • EventBridgeルール
  • SSMオートメーション

Terraform

まず、必要なIAMを作成する。
対象のクラスターに対してのみ、参照と停止の権限を付与する。

resource "aws_iam_role" "stop_db_clusters" {
  name               = "automation-stop-db-clusters"
  assume_role_policy = data.aws_iam_policy_document.stop_db_clusters.json
  inline_policy {
    name = "automation-stop-db-clusters"
    policy = jsonencode(
      {
        "Version" : "2012-10-17",
        "Statement" : [
          {
            "Sid" : "rds",
            "Effect" : "Allow",
            "Action" : [
              "rds:StopDBCluster",
              "rds:DescribeDBClusters"
            ],
            "Resource" : [
              "arn:aws:rds:ap-northeast-1:123456789:cluster:example-db1",

            ]
          },
          {
            "Sid" : "ssm",
            "Effect" : "Allow",
            "Action" : "ssm:*",
            "Resource" : "*"
          }
        ]
      }

    )
  }
}

data "aws_iam_policy_document" "stop_db_clusters" {
  statement {
    sid    = "StopDBClusters"
    effect = "Allow"
    principals {
      type = "Service"
      identifiers = [
        "rds.amazonaws.com",
        "ssm.amazonaws.com",
        "events.amazonaws.com"
      ]
    }
    actions = [
      "sts:AssumeRole"
    ]
  }
}

つぎにEventBridge RuleFinished updating DB parameter group というイベントを検知する。
この EventBridge Rule はご存知の方は言わずもがなではあるが、AWSの各種イベントをキャプチャしてルールにマッチしたらそれをトリガーにして発火する。
下記では、複数のクラスターを対象とするべく、for_eachを使って、各クラスターとインスタンスを指定している。

resource "aws_cloudwatch_event_rule" "stop_db_clusters" {
  for_each    = var.stop_db_clusters
  name        = "stop-db-cluster-${each.value["cluster"]}"
  description = "stop-db-cluster-${each.value["cluster"]}"

  event_pattern = jsonencode({
    "detail-type" : ["RDS DB Instance Event"],
    "source" : ["aws.rds"],
    "detail" : {
      "EventCategories" : ["configuration change"],
      "SourceType" : ["DB_INSTANCE"],
      "SourceArn" : ["arn:aws:rds:ap-northeast-1:123456789:db:${each.value["instance"]}"],
      "Message" : ["Finished updating DB parameter group"]
    }
  })
}

SSMのオートメーションにある AWS-StartStopAuroraCluster をEventBridgeのターゲットに指定して、停止する。
クラスターごとに作成するようにfor_eachでループしている。

resource "aws_cloudwatch_event_target" "stop_db_clusters" {
  for_each = var.stop_db_clusters
  arn      = "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartStopAuroraCluster:$DEFAULT"
  rule     = aws_cloudwatch_event_rule.stop_db_clusters[each.key].name
  role_arn = aws_iam_role.stop_db_clusters.arn
  input    = <<INPUT
{
    "Action": [
        "Stop"
    ],
    "ClusterName": [
        "${each.value["cluster"]}"
    ]
}
INPUT
}

variablesにクラスターとトリガー対象となるインスタンス名を指定する。

variable "stop_db_clusters" {
  type = map(any)
  default = {
    db01 = {
      cluster  = "example-db1-cluster",
      instance = "example-db1-01"
    }
    db02 = {
      cluster  = "example-db2-cluster",
      instance = "example-db2-cluster-01"
    }
  }
}

以上で、Auroraクラスターが起動してすぐに、停止状態になるようになる。

まとめ

1クラスターを短期間だけ停止するなら手動でも良いが、わりかし検知したりタイミングによっては停止を忘れたりしてしまう。
SSMのAutoMationは使ったことがなかったが、難しい実装を行うことなく、停止処理ができるのでオススメ。

カテゴリー: AWSRDS