こんにちは😺 カスタマーサクセス部の山本です。
AWS Summit Tokyo の「Amazon Aurora の技術とイノベーションDeep dive」というセッションで、Aurora の Blue/Green デプロイメントについて学びました。
参考リンク:Amazon Aurora の技術とイノベーションDeep dive
実際に試してみたところ、以下の制約に引っかかってしまいました。
ブルー/グリーンデプロイでは、AWS Secrets Manager を使用したマスターユーザーのパスワード管理はサポートされていません。
参考:Aurora 用 Amazon RDS ブルー/グリーンデプロイの概要
この制約は、ブルー環境で Secrets Manager を使用して管理しているマスターユーザーのパスワードを、グリーン環境には引き継げないという意味だと考えました。
そこで、一度自身で作成したパスワードで マスターユーザーのパスワードを管理するようにクラスターを変更し、Blue/Green デプロイを実施することにしました。デプロイ完了後に再び AWS Secrets Manager を使用したパスワード管理に戻しました。
もし、デプロイ後にマスターユーザーのパスワードが変わることでアプリケーションに問題が発生する場合、この手順は参考にならないかもしれません。
ただし、アプリケーションでマスターユーザーを使用することは推奨されていないため、そのようなケースは稀だと思います。
アプリケーションではマスターユーザーを直接使用しないことを強くお勧めします。代わりに、アプリケーションに必要な最小の特権で作成されたデータベースユーザーを使用するというベストプラクティスに従ってください。
参考:マスターユーザーアカウント権限 - Amazon Aurora
目次です。
- 検証シナリオ
- ブルー環境の Aurora クラスター作成
- Blue/Green デプロイでは、AWS Secrets Manager を使用したマスターユーザーのパスワード管理はサポートされていない
- ブルー環境のクラスターで、マスターユーザーのパスワードを自身で作成したパスワードに変更する
- Blue/Green デプロイを実施する
- 新しいクラスターでマスターユーザーのパスワードを Secret Manager で管理するように変更する
- ブルー環境のクラスターを削除する
- 切り替えたグリーン環境のクラスターを Terraform にインポートする
- まとめ
- 余談
検証シナリオ
Terraform を使用して Aurora Postgres Serverless v2 を作成しています。
切り替え後に、ブルー環境のクラスターを削除して Terraform の管理から外し、グリーン環境のクラスターを Terraform にインポートします。
ブルー環境は Aurora Postgres v15 で作成しています。
グリーン環境作成時に v16 にアップグレードします。
ブルー環境の Aurora クラスター作成
Terraform バージョン
- Terraform v1.9.3 on darwin_arm64
AWS Provider
- 5.60.0
- provider.tf
terraform { required_providers { aws = { source = "hashicorp/aws" version = "5.60.0" } } } provider "aws" { region = "ap-northeast-1" }
- rds.tf
vpc_security_group_ids
とsubnet_ids
には検証環境に作成済みの実際のリソース ID を入れて実行しました。- パラメータグループは、v15 と v16 のもの、両方を作成しています。
- Blue/Green デプロイをするため、クラスターパラメータグループでは、
rds.logical_replication
を 1 に設定しています。
resource "aws_rds_cluster" "test" { cluster_identifier = "provisioning-rds" db_subnet_group_name = aws_db_subnet_group.test.name db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.test15.name engine_version = "15.4" engine = "aurora-postgresql" engine_mode = "provisioned" enable_http_endpoint = true iam_roles = [] master_username = "postgres" manage_master_user_password = true enable_global_write_forwarding = false network_type = "IPV4" serverlessv2_scaling_configuration { max_capacity = 16 min_capacity = 2 } vpc_security_group_ids = ["sg-xxxxx"] skip_final_snapshot = true } resource "aws_rds_cluster_instance" "test" { cluster_identifier = aws_rds_cluster.test.cluster_identifier db_subnet_group_name = aws_rds_cluster.test.db_subnet_group_name db_parameter_group_name = aws_db_parameter_group.test15.name engine = aws_rds_cluster.test.engine engine_version = aws_rds_cluster.test.engine_version identifier = "rds-1" instance_class = "db.serverless" } resource "aws_db_subnet_group" "test" { name = "test_db_group" subnet_ids = ["subnet-xxxxx","subnet-xxxxx"] } resource "aws_rds_cluster_parameter_group" "test15" { name = "test-aurora-postgresql15-cluster" family = "aurora-postgresql15" description = "for aurora-postgresql15" parameter { name = "rds.logical_replication" value = "1" apply_method = "pending-reboot" } } resource "aws_db_parameter_group" "test15" { name = "test-aurora-postgresql15-instance" family = "aurora-postgresql15" description = "for aurora-postgresql15" } resource "aws_rds_cluster_parameter_group" "test16" { name = "test-aurora-postgresql16-cluster" family = "aurora-postgresql16" description = "for aurora-postgresql16" parameter { name = "rds.logical_replication" value = "1" apply_method = "pending-reboot" } } resource "aws_db_parameter_group" "test16" { name = "test-aurora-postgresql16-instance" family = "aurora-postgresql16" description = "for aurora-postgresql16" } resource "aws_ssm_parameter" "db_endpoint" { name = "jdbc_url" type = "String" value = aws_rds_cluster.test.endpoint } resource "aws_ssm_parameter" "reference_test" { name = "reference" type = "String" value = aws_ssm_parameter.db_endpoint.value }
Blue/Green デプロイでは、AWS Secrets Manager を使用したマスターユーザーのパスワード管理はサポートされていない
Terraform で作成した Aurora クラスターで Blue/Green デプロイを実行してみましょう。 実際に、Secrets Manager を使用してマスターユーザーを管理している状態では、Blue/Green デプロイを実行できません。
ブルー環境のクラスターで、マスターユーザーのパスワードを自身で作成したパスワードに変更する
クラスターを変更します。
セルフマネージドにチェックを入れます。
任意のパスワードを設定します。既存の Secrets Manager から取得したものを設定し、現在のパスワードと同じにしました。
「すぐに適用」にチェックを入れ、更新します。
変更中になります。
変更が完了しました。
Blue/Green デプロイを実施する
Blue/Green デプロイを実施します。
同意します。
Terraform で作成したパラメータグループを指定します。
「ステージング環境の作成」を押します。
プロビジョニングしています。
v15 から v16 にアップデートしています。
「ステージング環境の作成」を押してから 30 分ほどで、切り替え可能な状態になりました。
切り替え前にグリーン環境を使用して、アプリケーションのテストを十分に実施します。
ブルー環境からグリーン環境へのレプリケーションとの競合が発生しないよう、グリーン環境では可能な限り読み取り操作のみテストします。
その後、切り替えます。
切り替えが完了しました。
EC2 から psql で接続していたセッションでは、一回コネクションが終了し、再接続しました。
新しいクラスターでマスターユーザーのパスワードを Secret Manager で管理するように変更する
新しいクラスターでマスターユーザーのパスワードを Secret Manager で管理するように変更します。 ここで、マスターユーザーのパスワードが変わります。
変更が完了しました。
ブルー環境のクラスターを削除する
まず、Blue/Green デプロイを削除します。
次に、古くなり未使用のブルー環境のインスタンスを削除します。
古くなり未使用のブルー環境のクラスターを削除します。
切り替えたグリーン環境のクラスターを Terraform にインポートする
state ファイルから旧クラスター・インスタンスと terraform のリソースの関連付けを削除
state ファイルでは旧クラスター・インスタンスと terraform のリソースが関連づいているため、削除します。
terraform state rm aws_rds_cluster.test
terraform state rm aws_rds_cluster_instance.test
rds.tf の編集
新しいクラスターの設定内容に合わせ、以下の編集をしました。
engine_version
- 15.4 から 16.2 に変更
db_cluster_parameter_group_name
- 15 を 16 に変更
db_parameter_group_name
- 15 を 16 に変更
- v15 用のクラスター・DBパラメータグループのリソースを削除
resource "aws_rds_cluster" "test" { cluster_identifier = "provisioning-rds" db_subnet_group_name = aws_db_subnet_group.test.name db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.test16.name engine_version = "16.2" engine = "aurora-postgresql" engine_mode = "provisioned" enable_http_endpoint = true iam_roles = [] master_username = "postgres" manage_master_user_password = true enable_global_write_forwarding = false network_type = "IPV4" serverlessv2_scaling_configuration { max_capacity = 16 min_capacity = 2 } vpc_security_group_ids = ["sg-xxxxxx"] skip_final_snapshot = true } resource "aws_rds_cluster_instance" "test" { cluster_identifier = aws_rds_cluster.test.cluster_identifier db_subnet_group_name = aws_rds_cluster.test.db_subnet_group_name db_parameter_group_name = aws_db_parameter_group.test16.name engine = aws_rds_cluster.test.engine engine_version = aws_rds_cluster.test.engine_version identifier = "rds-1" instance_class = "db.serverless" } resource "aws_db_subnet_group" "test" { name = "test_db_group" subnet_ids = ["subnet-xxxxx","subnet-xxxxx"] } resource "aws_rds_cluster_parameter_group" "test16" { name = "test-aurora-postgresql16-cluster" family = "aurora-postgresql16" description = "for aurora-postgresql16" parameter { name = "rds.logical_replication" value = "1" apply_method = "pending-reboot" } } resource "aws_db_parameter_group" "test16" { name = "test-aurora-postgresql16-instance" family = "aurora-postgresql16" description = "for aurora-postgresql16" } resource "aws_ssm_parameter" "db_endpoint" { name = "jdbc_url" type = "String" value = aws_rds_cluster.test.endpoint } resource "aws_ssm_parameter" "reference_test" { name = "reference" type = "String" value = aws_ssm_parameter.db_endpoint.value }
import.tf の作成
新しいクラスターをインポートする tf を作成します。
import { to = aws_rds_cluster.test id = "provisioning-rds" } import { to = aws_rds_cluster_instance.test id = "rds-1" }
terraform apply
し切り替えたグリーン環境のクラスターを Terraform にインポートする
terraform apply
し、インポートします。
v15 用のパラメータグループ2つが destroy となり、新クラスター・インスタンスがインポートされます。
1 件の change は enable_global_write_forwarding
に関する既知の事象でした。詳細は以下の記事を確認ください。
【Terraform】Aurora クラスターをリストアする - サーバーワークスエンジニアブログ
無事、完了しました。
最後に、今後の apply では import.tf は不要になるため、削除しました。
まとめ
Secret Manager でマスターユーザーのパスワードを管理する環境で、Aurora の Blue/Green デプロイを実施しました。
ひと手間かかるものの、Blue/Green デプロイの恩恵を受けることができます。
最後に、Blue/Green デプロイには様々な制約がございますので、以下のドキュメントは十分にご参照ください。
Aurora 用 Amazon RDS ブルー/グリーンデプロイの概要 - Amazon Aurora
余談
一度はやってみたかった、八ヶ岳の南北縦走をしてきました。
山梨県の小淵沢から、長野県の蓼科山までの 42 km 、ひたすら山を走りました。
標高 1000m の道の駅から、最高峰である標高 2899m の赤岳まで登り上げ、その後も最後までアップダウンが続く厳しいコースでした。
岩場が多く、かなり神経を使いました。
16 時間も走ったので、その後のお風呂も気持ちよく、夜もよく眠れていい休日でした。
なかなか達成感もあります。
赤岳
南アルプス
登山を楽しむ人達
天狗岳
蓼科山