RDSのBlue/Green Deploymentをやってみた


# Agenda

今回は、以下のことを解説します。
- RDS Blue/Green Deploymentの概要
- RDS Blue/Green Deploymentデプロイメントの使い方

本動画は以下の方を対象にしています
- RDS Blue/Green Deploymentデプロイを使うメリットが知りたい
- RDS Blue/Green Deploymentデプロイのやり方を知りたい

# RDS Blue/Green Deploymentとは？

![rds-bg-ex01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/696d6d40-e236-d995-c55b-ec1fcb5db4d7.png)

まず、Blue/Green Deploymentとは、本番環境（Blue）とステージング環境（Green）を使って、
システム変更作業をダウンタイムなしに行うことができるデプロイ方式です。

Blue/Green Deploymentはとても便利なシステムです。

本番環境（Blue）はそのままにして、ステージング環境（Green）で変更を行えます。
このやり方だと、テスト中に本番環境への影響を防げます。

この機能をデータベースにも応用したのが、今回紹介するRDS Blue/Green Deploymentです。

![rds-bg-ex02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/f7e2a623-4456-9759-2158-5089de7991a0.png)

たとえば、新しいデータベースのアップグレードを考えているとき、まずGreen環境でアップグレードを行って、問題がないか確認する。
確認が終わったら、Greenを新しい本番環境として切り替えます。
これで、アップグレード中のダウンタイムがほとんどなくなり、リスクも低減されます。

なのでAmazon AuroraのBlue/Green Deploymentは、データベースの変更を安全かつ迅速に行うのにとても有効な手段です。

データベースをBlue/Green Deploymentするというのが発表された時は衝撃を覚えました。
去年発表され、最近正式にGAされてたので、データベースを運用している方は是非とも押さえておきたい機能のひとつです。

## RDSのBlue/Greenデプロイの仕組み

では、どのようにRDS上でBlue/Green Deploymentを実現しているのでしょうか。

![rds-bg-ex03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/8540f4b7-3287-1bbd-3b63-317ec20b4bc9.png)

まず、AWS上でBlue/Green Deploymentを作成すると、
現在の本番環境（Blue）とGreenがステージング環境（Green）が作られます。

![rds-bg-ex04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/437b4fb3-1a04-7cf1-1c41-ab492dfa5339.png)

Green環境は本番環境のコピーで、レプリケーションを使って設定がコピーされてます。
この時、Green環境のクラスター名とインスタンス名の末尾にランダムな文字列が追加されます。
Blue/Green Deployment作成時に、Green環境でデータベースクラスターの変更やアップグレード、パラメーターの変更を行うことが可能です。
もちろん、この時点で本番環境には影響ありません。
デフォルトでは、Blue環境のReaderインスタンスから設定をコピーしますが、
Blue環境のプライマリDBからGreen環境のプライマリDBに設定をコピーすることも可能です。

![rds-bg-ex05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/757a3186-956b-4e7c-0b0f-147f128e9b09.png)

Blue/Green Deployment作成後はステージング環境作業をしていきます。
DBスキーマや、インスタンスクラスの変更、動作テストなどができます。
この時、Green環境のDBクラスターはデフォルトで書き込み処理が許可されているので、
必要に応じてReadOnlyに設定しておくことが公式で推奨されています。

![rds-bg-ex06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/d9c570a6-736c-29bf-d1bd-ab989ffe8b8f.png)

十分にテストして問題なければ、Greenを新しい本番環境として切り替えます。
切り替えは、だいたい1分未満で完了するので、従来のリリース作業よりもダウンタイムを短く抑えられます。

![rds-bg-ex07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/c7b88039-1698-57b9-11c8-83a67dc9d6a6.png)

これでGreen環境が新本番環境となり、Blue/Green Deploymentが完了しました。

旧本番環境のBlue環境は手動で削除しない限りはそのまま残ります。
万が一、不具合が発生した場合はすぐにBlue環境にロールバックが可能です。
すぐに利用しない場合は一時停止しておくことでコストを抑えられますし、不要であればそのまま手動削除してしまっても良いです。

以上がBlue/Green Deploymentの流れとなります。

## Blue/Green Deploymentの制限事項

Blue/Green Deploymentを利用するにあたって、いくつか注意事項があります。

たとえば、今回のハンズオンではAurora MySQLを使っていくわけですが、
MySQLバージョン8.0.11〜8.0.13はバグの影響でBlueグリーンデプロイが使えないようです。

また、Blueグリーンデプロイは、以下の機能ではサポートしていません
- RDS Proxy
- クロスリージョンリードレプリカ
- AWS CloudFormation
- マルチAZクラスターデプロイ etc.

PostgreSQLを利用する場合でも、使えない機能もいくつかあるようですので、
実際に業務で利用する場合は公式ドキュメントを確認しましょう。


## ハンズオン概要

それでは今回のハンズオンについて説明します。

今回はサンプルのデータベースを作成したAurora MySQLのバージョンアップをBlue/ブリーんデプロイでやってみようと思います。

まず、以下を前提条件にハンズオンを進めていきます
- AWSアカウントは作成済みであること
- 簡単なLinux、MySQLコマンドが使えること（知らなくてもハンズオンは一応できます）
- AWS CloudFormationの使い方を知っていること（動画を見れば一応できます）

![rds-bg-ex08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/7877fc19-b2b1-4aa3-c016-d3910b0555f5.png)

流れは以下の通りです
1. CloudFormationでハンズオン環境構築
2. EC2からAuroraに対してサンプルDBを作成
3. Blue/Green Deployment作成
4. 切り替え
5. 後片付け

それではやっていきましょう。

# ハンズオン編

## スタック作成

CloudFormtaionテンプレートからスタックを作成します。
利用するCloudFormationテンプレートは以下の`aurora-bg-cfn.yml`に記載ありますのでそちらを利用ください。

https://github.com/bamtech1904/aws-hacks/tree/main/008_aurora-blue-green-deploy

**※リージョンは`ap-northeast-1(東京リージョン)`を指定するのを忘れないでください**

![rds-bg-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/0578c92f-5f98-0ae3-ac9a-18b288b8af23.png)

作成完了後、AuroraのWriterエンドポイントをコピーしておく

![rds-bg-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/d8e0c0ac-e88b-6525-9725-7eac83608a3f.png)



## サンプルDB作成

EC2にセッションマネージャーで接続をしましょう。
EC2コンソール画面から`aurora-bg-dev-ec2`を選択し、セッションマネージャーに接続。

![rds-bg-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/9470ca44-eaa1-372b-8af5-c8d917847043.png)
![rds-bg-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/e6f83655-69fa-ffdf-b4a6-b42b06f607b2.png)

デフォルトのec2-userで作業をしていく

```sh
sh-5.2$ bash
[ssm-user@ip-192-168-10-100 bin]$ sudo su -
[root@ip-192-168-10-100 ~]# su - ec2-user
[ec2-user@ip-192-168-10-100 ~]$
```

EC2にセッションマネージャー接続し、SQLファイル作成
サンプルのSQLファイルはGitHubリポジトリにおいています。
`create-sample-db.sql`です。

```sh
[ec2-user@ip-192-168-10-100 ~]$ vi create-sample-db.sql
[ec2-user@ip-192-168-10-100 ~]$ cat create-sample-db.sql
-- データベースの作成
CREATE DATABASE `test-db`;

-- 新しいデータベースに接続
USE `test-db`;

-- 社員情報を格納するテーブルの作成
CREATE TABLE `employees` (
    `employee_id` INT NOT NULL AUTO_INCREMENT,
    `employee_name` VARCHAR(100) NOT NULL,
    PRIMARY KEY (`employee_id`)
);

-- テストデータの挿入（オプション）
INSERT INTO `employees` (`employee_name`) VALUES ('hogehoge');
INSERT INTO `employees` (`employee_name`) VALUES ('fugafuga');
```

作成したSQLファイルをDBに投入しましょう。

```sh
$ mysql -h <AuroraのWriterエンドポイント名> -u rdsroot -pPassW0rd < ./create-sample-db.sql

[ec2-user@ip-192-168-10-100 ~]$ mysql -h dev-aurora-bg-db.cluster-cedmf6a17cts.ap-northeast-1.rds.amazonaws.com -u rdsroot -pPassW0rd < ./create-sample-db.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
```

Auroraに接続し、サンプルデータを確認

```sql
mysql> USE `test-db`;
Database changed
mysql> SELECT * FROM employees;
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
|           1 | hogehoge      |
|           2 | fugafuga      |
+-------------+---------------+
2 rows in set (0.01 sec)
```



## Blueグリーンデプロイ作成

RDSのデータベース画面を選択し、クラスターを選択し、
[Actions]-[Create Blue/Green Deployment]を選択

![rds-bg-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/c012fdc4-7642-b550-6351-788508641755.png)

エンジンバージョンを変えて[Create staging environment]を選択

![rds-bg-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/492bc8ac-c1fb-bd86-3cf1-d1fe3ea26e01.png)

以下のようにGreen環境を作成し始める。
しばらく待つ。

![rds-bg-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/cd6b7855-c821-4511-c12e-479854b2be0d.png)

以下でダウンタイムが発生しないか確認しておきましょう。
```sh
$ while :; do mysqladmin ping -u rdsroot -pPassW0rd -h ${DBホスト名}; date; sleep 1; done
```

グリーン環境が完成

![rds-bg-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/501fa5a7-3ca9-70cf-ce20-c2d83f781057.png)

## グリン環境の確認

作成したBlueグリーンを選択すると、
Blue環境とグリーン環境の情報が確認できる

![rds-bg-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/0f73aa4a-0552-d3a1-dc1a-9dce05f40571.png)

![rds-bg-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/a7e0a954-14fd-91f2-0937-fe5e799ee712.png)

![rds-bg-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/d6958e33-63fe-0cfe-b956-ce62294b83d2.png)

グリーン環境のDBに試しに接続してみる

```sql
[ec2-user@ip-192-168-10-100 ~]$ mysql -h dev-aurora-bg-db-green-ajyguq.cluster-cedmf6a17cts.ap-northeast-1.rds.amazonaws.com -u rdsroot -pPassW0rd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 372
Server version: 8.0.32 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test-db            |
+--------------------+
5 rows in set (0.00 sec)

mysql> USE test-db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SHOW TABLES;
+-------------------+
| Tables_in_test-db |
+-------------------+
| employees         |
+-------------------+
1 row in set (0.01 sec)

mysql> SELECT * FROM employees;
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
|           1 | hogehoge      |
|           2 | fugafuga      |
+-------------+---------------+
2 rows in set (0.00 sec)
```

また、リアルタイムでレプリケーション同期しているので、
Blue環境のDBを変更すれば、即時でグリーン環境にも設定は変更される。

試しにBlue環境のDBにデータを追加してみる。

```sql
sh-5.2$ mysql -h dev-aurora-bg-db.cluster-cedmf6a17cts.ap-northeast-1.rds.amazonaws.com -u rdsroot -pPassW0rd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 666
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test-db            |
+--------------------+
5 rows in set (0.01 sec)

mysql> USE test-db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT * FROM employees;
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
|           1 | hogehoge      |
|           2 | fugafuga      |
+-------------+---------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO `employees` (`employee_name`) VALUES ('morimori');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM employees;
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
|           1 | hogehoge      |
|           2 | fugafuga      |
|           3 | morimori      |
+-------------+---------------+
3 rows in set (0.00 sec)
```

Green環境にデータが追加されたかを確認

```sql
ec2-user@ip-192-168-10-100 ~]$ mysql -h dev-aurora-bg-db-green-ajyguq.cluster-cedmf6a17cts.ap-northeast-1.rds.amazonaws.com -u rdsroot -pPassW0rd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 372
Server version: 8.0.32 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> USE test-db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> SELECT * FROM employees;
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
|           1 | hogehoge      |
|           2 | fugafuga      |
+-------------+---------------+
2 rows in set (0.00 sec)

mysql>
mysql> SELECT * FROM employees;
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
|           1 | hogehoge      |
|           2 | fugafuga      |
|           3 | morimori      |
+-------------+---------------+
3 rows in set (0.00 sec)
```

## グリーン環境に切り替え

Blueグリーンを選択し、[Actions]-[Switch over]を選択

![rds-bg-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/b54731da-a4be-ca10-a494-4620439612a6.png)

Switch over画面で、タイムアウト値を設定
タイムアウト値は30秒〜1時間まで設定可能。
タイムアウト値までに切り替えが完了しない場合、変更が全てロールバックされる

![rds-bg-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/388b6e7d-3689-c412-31f9-a12ece4ab9bc.png)

スイッチオーバー開始

![rds-bg-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/8dfd55f2-39ef-0c29-83b5-4b15991c5923.png)

グリーン環境のDB名がBlueに統一される

![rds-bg-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/aa566f61-45fb-625b-6c67-96ed2f31cffe.png)

切り替えが完了
約2分で完了

![rds-bg-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/ae6524d7-f6a4-76a7-13cd-107100e5f9be.png)

切り替え後のグリーン環境を確認すると
エンドポイント名などのBlue環境のものが引きつがれる

![rds-bg-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/9ad2b3f4-0de5-d9aa-73a3-da057dfb63ec.png)

Blue環境は切り替え後もそのまま残るので、不要になったら手動で削除する。
エンドポイント名に-oldがつく

![rds-bg-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/82e66d89-27ac-e187-845c-b4ed2668b9da.png)

CloudFormationパスワードが変更で切るか確認

![rds-bg-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/eeff47d7-d658-ded1-852b-43c76648b3c4.png)

hogehoge

Passwordも変更され始めた。
Blueグリーン後も、CLoudFormationは問題なく利用できる。

![rds-bg-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/375b351e-5bcf-4e50-7e8e-a543113dd84d.png)


## 後片付け

Stackを削除しておく。

BlueグリーンとBlueグリーンデプロイは手動で削除しておく。

![rds-bg-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524408/c67b3334-fafd-10fe-f2c8-08b81973c0b4.png)

# まとめ

終わり

# 参考リンク

[Using Amazon RDS Blue/Green Deployments for database updates](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)