Amazon Aurora × Terraform で注意したい仕様
はじめに
初めて Terraform でマルチ AZ 対応の Aurora を構築しようとしたり、グローバルデータベースを利用する際、いくつかの制約に直面することがあるかと思います。
今回は私が Aurora を構築する際に遭遇した、悩ましい仕様についてご紹介したいと思います。
最初に知っておくと実装が少しスムーズになるかもしれません。参考になれば幸いです。
※なお、本記事の内容は 2025年3月3日現在の情報に基づいています。今後、内容が古くなる場合がありますのでご了承ください。
Terraform で Aurora インスタンスを記述する際にライター / リーダーの指定ができない
一般に Amazon Aurora クラスターは、1 台のプライマリ(ライター)インスタンスと複数台のリードレプリカ(リーダー)インスタンスで構成されます。
しかし、Terraform の aws_rds_cluster_instance
リソースには、ライター/リーダーの役割を明示的に指定するプロパティが存在しません。 そのため、最初に作成されたインスタンスが自動的にライターとして設定され、以降に作成されるインスタンスはリーダーとなります。
resource "aws_rds_cluster" "example" {
cluster_identifier = "example-cluster"
engine = "aurora-mysql"
database_name = "exampledb"
master_username = "admin"
master_password = "password"
}
resource "aws_rds_cluster_instance" "instance" {
count = 3
identifier = "example-instance-${count.index}"
cluster_identifier = aws_rds_cluster.example.id
instance_class = "db.r6g.large"
}
上記のコードでは、count パラメータを使用して3つのインスタンスを作成していますが、最初に作成されたインスタンスがライターとなり、残りはリーダーとして設定されます。
それでは、もし以下のようなコードを書いた場合はどうでしょうか。
resource "aws_rds_cluster" "example" {
cluster_identifier = "example-cluster"
engine = "aurora-mysql"
database_name = "exampledb"
master_username = "admin"
master_password = "password"
}
resource "aws_rds_cluster_instance" "writer" {
identifier = "example-writer"
cluster_identifier = aws_rds_cluster.example.id
instance_class = "db.r6g.large"
}
resource "aws_rds_cluster_instance" "reader" {
identifier = "example-reader"
cluster_identifier = aws_rds_cluster.example.id
instance_class = "db.r6g.large"
}
このコードでは、ライターとリーダーを 1 台ずつ作ろうとして、明示的に writer と reader という名前をつけています。
しかし Terraform 側では 「最初に作成されたものがライター、それ以降はリーダー」 というルールで動作するため、例えば terraform destroy
→ terraform apply
を実行すると、異なるインスタンスがライターになってしまい、意図しない結果になる可能性があります。
以下のように昔から要望されていますが、実現されていません。
なぜこのような仕様になっているのか、AI によると以下の理由を挙げてくれました。
理由 | 説明 |
---|---|
Aurora のライター/リーダーは AWS が自動管理 | AWS のフェイルオーバー機能と競合するため、Terraform では指定不可。 |
Terraform は静的管理ツールで、動的なロール変更に対応しない | AWS 側での自動変更を Terraform が認識できず、状態のズレが発生する。 |
Aurora はクラスター単位で管理され、個々のインスタンスの役割は AWS に委ねられる | Terraform で個別にライター/リーダーを制御する設計になっていない。 |
Terraform で指定できたとしても、フェイルオーバー後に状態が崩れる |
terraform apply が意図しない状態変更を引き起こす可能性がある。 |
なるほど、ライター/リーダーという役割は AWS による自動フェイルオーバーによって動的に変化しうるものなので、 Terraform のような宣言的な設定で制御すべきではないのかもしれません。そう考えると納得です。
このように、 Terraform で全て管理することは難しいため、もしライター/リーダーで異なる設定値を適用したい場合などは、AWS のコンソール画面で行うことも検討すると良さそうです。
グローバルデータベースの Aurora Serverless v2 は一時停止が実施できない
こちらは Terraform とは直接関係ありませんが、グローバルデータベースを使用して複数リージョンでリードレプリカを構築する場合は覚えておくと良さそうなので、ご紹介します。
例えば、開発環境や検証用環境など、RDS を使用していない時間帯は、コストを抑えるために利用を一時停止したいケースがあると思います。
停止する方法は、手動による停止や自動一時停止が挙げられますが、このとき Aurora クラスターがグローバルデータベースに紐づいている(スタンドアロンでない)場合、一時停止が実施できないことがあります。
下図: 警告が出ていてクラスターを一時停止できない状態
以下、公式ドキュメントを参照しました。
You can't stop or start the Aurora DB clusters in your global database individually.
グローバルデータベース内の Aurora DB クラスターを個別に停止または起動することはできません。
You can only stop and start a cluster that's part of an Aurora global database if it's the only cluster in the global database.
You can't stop and start a cluster that has a cross-Region read replica.
グローバルデータベースの一部であるクラスターは、それがグローバルデータベース内の唯一のクラスターである場合にのみ停止および起動できます。
通常、グローバルデータベースは、異なるリージョンで複数のクラスター(プライマリ・セカンダリ)を扱うケースがほとんどかと思います。しかしその場合、クラスターの一時停止を実施できないということを認識しておく必要がありそうです。
また、Aurora Serverless v2 は 一定時間アクティビティがないと自動的に一時停止し、コストを削減できます。
しかし、グローバルデータベースの Aurora Serverless v2 では、この自動一時停止機能が適用されません。
こちらも公式ドキュメントに記載があります。
If your cluster is the primary cluster in an Aurora global database, Aurora doesn't automatically pause the Aurora Serverless v2 writer instance. That's because a constant level of activity is needed on the writer instance to manage the other clusters in the global database. Because the writer instance remains active, any Aurora Serverless v2 reader instances with failover priority zero or one also don't auto-pause.
クラスターが Aurora グローバルデータベースのプライマリクラスターである場合、Aurora は Aurora Serverless v2 ライターインスタンスを自動的に一時停止しません。これは、グローバル データベース内の他のクラスターを管理するために、ライターインスタンスで一定レベルのアクティビティが必要であるためです。ライターインスタンスはアクティブなままなので、フェイルオーバー優先度が 0 または 1 の Aurora Serverless v2 リーダーインスタンスも自動的に一時停止しません。
Aurora Serverless v2 instances in the secondary clusters of an Aurora Global Database don't automatically pause. If a DB cluster is promoted to a standalone cluster, then the auto-pause feature becomes effective if all the other conditions are met.
Aurora Global Database のセカンダリクラスター内の Aurora Serverless v2 インスタンスは自動的に一時停止しません。DB クラスターがスタンドアロンクラスターに昇格された場合、他のすべての条件が満たされていれば自動一時停止機能が有効になります。
このように、グローバルデータベースを使用していると、一部の条件を除いて RDS の一時停止がほぼできないようです。
これまで単一リージョンでデータベースを運用してきた時は、任意のタイミングで一時停止をすることで使用していない期間のコストを抑えることができていましたが、マルチリージョンで運用する場合は、一時停止についてかなりの制約があるので注意しましょう。
Discussion