Aurora for PostgreSQL の フルマネージド Blue/Green デプロイを試してみた

# はじめに
2022年のre:inventでMySQLのBlue/Greenデプロイが発表されてから約一年、PostgreSQL (Aurora/RDS) でもフルマネージドのBlue/GreenのGAが発表されました。

- [Amazon RDS Blue/Green Deployments now supports Aurora and RDS PostgreSQL](https://aws.amazon.com/jp/about-aws/whats-new/2023/10/amazon-rds-blue-green-deployments-aurora-rds-postgresql/)
- [New – Fully managed Blue/Green Deployment in Amazon Aurora PostgreSQL and Amazon RDS for PostgreSQL](https://aws.amazon.com/jp/blogs/database/new-fully-managed-blue-green-deployment-in-amazon-aurora-postgresql-and-amazon-rds-for-postgresql/)

# Blue/Green デプロイって何？
一般的なBlue/Greenデプロイとは、以下のような意味になります。
> ブルーグリーンデプロイメントとは現状の本番環境（ブルー）とは別に新しい本番環境（グリーン）を構築した上で、ロードバランサーの接続先を切り替えるなどして新しい本番環境をリリースする運用方法のこと [引用: 3分でわかる ブルーグリーンデプロイメント](https://xtech.nikkei.com/atcl/nxt/keyword/18/00002/070800077/)

データベースの場合には切り替え、切り戻しにおいてデータロストがあってはなりませんので、データの同期等を行わなくてはならず少し高度なテクニックが必要となっていました。

Aurora PostgreSQLにおける手動Blue/Greenデプロイの手法については、以下に記載がありますように、クローンデータベースを作成してデータ同期、切り替え等が必要となっていました。

- [Amazon Aurora PostgreSQL blue/green deployment using fast database cloning](https://aws.amazon.com/jp/blogs/database/amazon-aurora-postgresql-blue-green-deployment-using-fast-database-cloning/)

# PostgreSQL のBlue/Greenデプロイにおける制限事項
制限事項は以下のガイドに記載がありますが、重要な点としては **PostgreSQLの論理レプリケーション** を利用してデータをBlue環境からGreen環境にレプリケーションするため、論理レプリケーションで制限されている機能は許可されない、もしくはGreen環境の再作成が必要になります。
例えば、主キーのないテーブルに対してのUpdateやDeleteはそのままでは許可されません。

- [ブルー/グリーンデプロイの制限事項](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments-overview.html#blue-green-deployments-limitations)(2023/10/28時点では英語版のみ)

# Aurora for PostgreSQLのBlue/Greenデプロイ環境の構築

Aurora for postgreSQLでのBlue/Greenデプロイ環境を構築してみます。

#### 事前準備(前提の確認)

PostgreSQLベースのbule/Green デプロイは論理レプリケーションを利用するため、Blue側に以下のパラメータが設定されている必要があります。

- rds.logical_replication

こちらのパラメータが設定されていないと、環境構築時に以下のエラーが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/109f7502-939e-f957-b80d-79a2e9eddefb.png)

#### Blue/Greenデプロイ環境構築

Blue/Green デプロイは「アクション」から作成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/03961925-3d43-4247-316d-f82e6bb57305.png)

Green側の対象のエンジンバージョンは、Blue側のバージョン以上(今回 Blueは13.12)を選択することができます。(事前にGreen側のバージョンのパラメータグループは作成しておく必要があります)
今回は 15.4 を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/c2065db8-a5d2-3f91-15e2-ba96846621c8.png)

実行すると、以下のようにGreen側のクラスタがプロビジョンされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/ea3698c4-0f1c-b507-fac0-6d2579771cda.png)

![008-bgdeploy-provisioning-04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/fa62a39e-696a-31fd-0910-eda126992408.png)

![008-bgdeploy-provisioning-05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/9259bedd-be42-9741-e6e2-926bd8e0cef9.png)

#### Green環境の確認

###### Green環境へのデータのレプリケート確認
Blue側でデータを追加すると、Green側にもデータがレプリケートされていることが確認できます。

```SQL:Blue側へのデータ追加
$ psql -h bgdb01.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres -d bgdb01
psql (13.7, server 13.12)
SSL connection (protocol: TLSv1.2, cipher: AES128-SHA256, bits: 128, compression: off)
Type "help" for help.

bgdb01=> select * from test01;
  id  |   name   | testcol
------+----------+---------
 1    | hogehoge |       1
 2    | hogehoge |       2
(2 rows)

bgdb01=> insert into test01 values (0003,'hogehogehoge',03);
INSERT 0 1
bgdb01=> commit;
WARNING:  there is no transaction in progress
COMMIT
bgdb01=>
bgdb01=> select * from test01;
  id  |     name     | testcol
------+--------------+---------
 1    | hogehoge     |       1
 2    | hogehoge     |       2
 3    | hogehogehoge |       3
(3 rows)

```

```SQL:Green側での確認
$ psql -h bgdb01-instance-1-green-xxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres -d bgdb01
psql (13.7, server 15.4)
WARNING: psql major version 13, server major version 15.
         Some psql features might not work.
SSL connection (protocol: TLSv1.2, cipher: AES128-SHA256, bits: 128, compression: off)
Type "help" for help.

bgdb01=> select * from testb10;
ERROR:  relation "testb10" does not exist
LINE 1: select * from testb10;
                      ^
bgdb01=> select * from test01;
  id  |     name     | testcol
------+--------------+---------
 1    | hogehoge     |       1
 2    | hogehoge     |       2
 3    | hogehogehoge |       3
(3 rows)
```

###### Blue環境へのDDLの実行

Blue環境にDDLを実行すると、WARNINGが出力されます。
この状態でBlue/Greenの切り替えを実行しようとするとロールバックされてしまうため、Green環境を再作成する必要があります。

```SQL:Blue環境へのDDL実行
$ psql -h bgdb01.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres -d bgdb01
psql (13.7, server 13.12)
SSL connection (protocol: TLSv1.2, cipher: AES128-SHA256, bits: 128, compression: off)
Type "help" for help.

bgdb01=> create table test02 (id char(4) not null, name text not null, testcol integer, primary key(id));
WARNING:  command will not be replicated to the green instance: "CREATE TABLE"
CREATE TABLE
```

###### Blue環境へのupdate/deleteの実行(主キーがないテーブルに対して)

Blue環境の主キーがないテーブルに対してのupdate/deleteを行おうとすると、エラーが発生して実行できません。
```SQL:Blue環境への主キーがないテーブルへのupdate/delete
$ psql -h bgdb01.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres -d bgdb01
psql (13.7, server 13.12)
SSL connection (protocol: TLSv1.2, cipher: AES128-SHA256, bits: 128, compression: off)
Type "help" for help.

bgdb01=> insert into test03 values(1,current_timestamp);
INSERT 0 1
bgdb01=> commit;
WARNING:  there is no transaction in progress
COMMIT
bgdb01=> delete from test03;
ERROR:  cannot delete from table "test03" because it does not have a replica identity and publishes deletes
HINT:  To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.
```

# Aurora for PostgreSQLのBlue/Greenデプロイの切替

Blue/Greenの切り替えを実際に実施してみます。ブルー/グリーンデプロイのロールを選択し、アクションから「切り替え」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/0e41ac1d-8567-7d59-62d8-ab17662b1740.png)


切り替えを選択すると、スイッチオーバ―の条件が出てきます。ここでタイムアウトの設定等も行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/9034d82d-2f4d-a0ec-26b3-4f5cacf4c3b2.png)


切り替えにあたっての最終的な注意事項等も表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/5021637e-23aa-0d3e-50ca-26963e311eaa.png)

切り替えを実行すると、ステータスが「切り替え」となり、元のBlue環境が -old1 となり、元のGreen環境が昇格します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/879129c7-3250-06db-2de6-124964558801.png)

切り替えが完了すると、Blue/Greenの紐づけも解除され、各々独立したデータベースが残ります。old側やデプロイロールは削除可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/1c3acc6c-b49e-99b9-d96b-d87f637c96a5.png)


#### 切り替え時のイベント

切り替えを実施したタイミングのログは以下のようになり、1,2分で切り替えが行われていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/9e53019f-93ec-c73c-62ae-304b827b88f0.png)

#### 切り替えログ

Auroraのエンドポイントに毎秒インサートするスクリプトを切り替え時に実行していました。65番目のinsertがタイムアウトでエラーになっており、約2分程度 間隔があいてました。(タイムアウトをまってしまったので、実際の切り替え時間はもう少し短い可能性があります)
```shell:インサート実行ログ
INSERT 0 1
WARNING:  there is no transaction in progress
COMMIT
63
INSERT 0 1
WARNING:  there is no transaction in progress
COMMIT
64
psql: error: could not connect to server: Connection timed out
        Is the server running on host "bgdb01.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com" (10.12.52.122) and accepting
        TCP/IP connections on port 5432?
65
INSERT 0 1
WARNING:  there is no transaction in progress
COMMIT
66
```

```shell:インサート時刻
  63 | 2023-10-28 11:08:32.167017
  64 | 2023-10-28 11:08:33.195218
  66 | 2023-10-28 11:10:44.495658
```

# まとめ
Aurora for PostgreSQLのフルマネージドBlue/Greenデプロイの切り替えを試してみました。手動で環境を構築して切り替えを行うのに比べると格段に利用しやすいかと思います。
一方、今回は小規模な環境での確認となったため、機能的な確認にとどまりますが、論理レプリケーションを利用するため実際には同期確認等の性能面でのケアが必要になってくるはずです。そのあたりの注意点も機能紹介blogのベストプラクティスに記載がありますので、利用を検討される際にはご確認頂ければと思います。