はじめに
こんにちは。Strategic AI Group所属の太田寛明です。
ある環境A(例えば本番環境)のAmazon RDS DBインスタンスを別アカウントB(例えば検証環境)にバックアップ&リストアする作業を自動化する機会があったので、その手法について紹介します。
自動化する方法は様々1あると思いますが、今回はGitHub Actionsを利用しました。複数のAWS CLIコマンドを各アカウントごとに日次で定期実行します。
バックアップリストアの実装
RDS DBインスタンスをアカウント間でバックアップリストアする方法に関しては、AWSの公式ドキュメントに記載があります。
Amazon RDS DB インスタンスを別の VPC またはアカウントに移行する
別の AWS アカウントに移行
次の図は、Amazon RDS DB インスタンスを別の AWS アカウントに移行するワークフローを示しています。
この手法を踏まえて、本番環境のDBを別アカウントの検証環境にコピーしたい場合は、次のプロセスを踏むことになります。
- 環境AのDBのスナップショットを作成(上図の(1)(2))
- スナップショットを環境Bのアカウントに共有(上図の(3))
- 共有されたスナップショットから検証環境上でDBを復元(上図の(4)(5))
これらのプロセスは、AWS Management Console、AWS CLI、RDS APIのいずれを用いても実現することが可能です。
今回はAWS CLIコマンド2を用いた実装を自動化したので、この実装に基づいて各プロセスをもう少し詳しく紹介していきます。
1. 本番環境のDBのスナップショットを作成
Amazon RDSのスナップショットには自動スナップショットと手動スナップショットの2種類が存在します。
基本的に自動スナップショットをもとにDBを復元すればいいわけですが、今回は別アカウントにスナップショットを共有する必要があるため、以下に従って手動スナップショットを作成する必要があります。
DB スナップショットの共有
自動 DB スナップショットを共有するには、自動 DB スナップショットをコピーしてそのコピーを共有することで、手動スナップショットを作成します。
実装例は次のようになります。
ここで、初めにスナップショットを削除しているのは、同一名称のものが既に存在する場合には新しくスナップショットを作成できないからです。
過去分のスナップショットは、基本的に自動スナップショットという形で別途保持されていると思うので、手動スナップショットの名称は毎回固定で問題ないかと思います。
# スナップショット削除 |
参照(公式ドキュメント)
2. スナップショットを検証環境のアカウントに共有
本番環境で作成した手動スナップショットを検証環境のアカウントでも参照できるように共有します。
実装例は次のようになります。
aws rds modify-db-snapshot-attribute \ |
参照(公式ドキュメント)
3. 共有されたスナップショットから検証環境上でDBを復元
いよいよDBの復元ですが、AWS KMSによる暗号化を行った際、1つ注意点があります。
以下の制限により、カスタマーマネージドキーを使用してスナップショットを暗号化する必要がありました。
暗号化されたスナップショットの共有
スナップショットを共有した AWS アカウント のデフォルト KMSキーを使用して暗号化されたスナップショットを共有することはできません。
…
デフォルトの KMS キーの問題を回避するには、次のタスクを実行します。
- カスタマーマネージドキーを作成し、そのキーへのアクセス権を付与する
- ソースアカウントからスナップショットをコピーして共有する
- ターゲットアカウントに共有したスナップショットをコピーします
このため、他アカウントから共有された暗号化済みの手動スナップショットを利用してDBインスタンスを復元したい場合は、指示された回避策に従って再びスナップショットのコピーを作成し、それをもとにDBインスタンスの復元を行う必要があります。
共有されたスナップショットのコピー
前述した通り、まずは本番環境から共有された暗号化済みのスナップショットを検証環境上でコピーします。
実装例は次のようになります。
ここで、コマンドcopy-db-snapshot
のオプション--source-db-snapshot-identifier
について、以下制約が存在するため、共有されたスナップショット識別子はARNとして取得しています。
copy-db-snapshot
--source-db-snapshot-identifier
(string)
…
If you are copying from a shared manual DB snapshot, this parameter must be the Amazon Resource Name (ARN) of the shared DB snapshot.
# スナップショット削除 |
参照(公式ドキュメント)
スナップショットからDBインスタンスを復元
続いて検証環境上でコピーしたスナップショットをもとに、DBインスタンスを復元します。
実装例は次のようになります。
# DBインスタンス削除 |
参照(公式ドキュメント)
バックアップリストアの自動化
さて、バックアップリストアの実装で作成したファイル達を各アカウントでそれぞれ手動実行することで、検証環境上に本番環境のDBを復元できるようになりました。
いよいよ本題のGitHub Actionsでの自動化です。aws-actions/configure-aws-credentials
を使用すれば、指定したIAMロールでAWS CLIコマンドを実行できるので、ここではバックアップリストアの実装で作成したファイル達を実行するために必要なIAMロールの設定について説明しようと思います。
一般的にaws-actions/configure-aws-credentials
を使用してAWS CLIコマンドを実行するために必要な設定については、Terraform とGitHub Actions等を参考にしてみてください。
必要なIAMロールの設定
バックアップリストアの実装で作成したファイル達が正常に実行されるためには、以下ポリシーがIAMロールに付与されており、アクセスが許可されている必要があります。
- AWS CLIコマンド実行のために必要なポリシー
- 検証環境上での本番環境のAWS KMSキーの使用に必要なポリシー
1つずつ見ていきましょう。
AWS CLIコマンド実行のために必要なポリシー
バックアップリストアの実装を踏まえると、本番/検証環境で以下AWS CLIコマンド群を実行できるようにする必要があると分かります。
- スナップショットの削除と複製(本番環境と検証環境の両方)
delete-db-snapshot
wait db-snapshot-deleted
describe-db-snapshots
copy-db-snapshot
wait db-snapshot-available
- スナップショットの共有(本番環境のみ)
modify-db-snapshot-attribute
- DBインスタンスの削除復元(検証環境のみ)
delete-db-instance
wait db-instance-deleted
restore-db-instance-from-db-snapshot
wait db-instance-available
以下では、それぞれのコマンド群の実行に必要なポリシーの実装例を挙げています。
要件によっては、さらに細かくカスタマイズする必要もあると思うので参考程度に留めて役立ててもらえればと思います。
また、本番/検証環境のそれぞれのアカウントごとに、実行すべきコマンド群が異なるので注意して設定してください。
スナップショットの削除複製に必要なポリシーの実装例
本番環境と検証環境の両方のアカウントで必要になります。
{ |
スナップショットの共有に必要なポリシーの設定例
本番環境のアカウントでのみ必要になります。
{ |
DBインスタンスの削除復元に必要なポリシーの設定例
検証環境のアカウントでのみ必要になります。
{ |
検証環境上での本番環境のAWS KMSキーの使用に必要なポリシー
本番環境での設定
スナップショットの暗号化に使用したカスタマーマネージドキーのKMSキーポリシーにて、共有先の検証環境のアカウントをキーユーザーに指定することで、検証環境上でそのKMSキーへのアクセスを許可できるようになります。
具体的には次の2つのステートメントについて、検証環境のアカウントにKMSキーへのアクセス許可を与える必要があります。
{ |
{ |
参照(公式ドキュメント)
検証環境での設定
上記設定により本番環境側は、このKMSキーに対するアクセス許可を検証環境に与えました。
しかし実際に検証環境上でKMSキーを使用できるようにするためには、このKMSキーを使用するロールに対して検証環境側からアクセス許可を与える必要もあります。
具体的には以下ポリシーを作成し、IAMロールに付与する必要があります。
これによってようやく、本番環境から共有されたスナップショットを検証環境上にコピーできるようになります。
{ |
参照(公式ドキュメント)
GitHub Actions ワークフローを作成する
必要なIAMロールを設定できたので、あとはGitHub Actionsのワークフローを作成すればバックアップリストア作業を自動化できます。
アカウントごとに適切なIAMロールをaws-actions/configure-aws-credentials
で指定した後に、次の2つのシェルスクリプトを、対応するアカウントごとに順次実行します。
backup_prod.sh
:本番環境で実行restore_stg.sh
:検証環境で実行(ただし、backup_prod.sh
の実行完了後)
実装例は以下の通りです。
name: restore-rds-stg-from-prod |
さいごに
今回は、RDS DBインスタンスをアカウント間でバックアップリストアする方法とGitHub Actionsを用いた自動化の方法を紹介させていただきました。もしRDS DBのバックアップ方法に悩んでいる方がいれば試してみてください。
また、今回紹介した方法は、同一リージョン内でバックアップリストアする方法です。リージョン間のコピーは少し複雑性が増すらしく、少しカスタマイズする必要があるかもしれませんので注意してください。
- 1.他にもAWS CodeBuildを用いたりする方法等があります。一方でAWS Lambdaは時間的制約がシビアであるため、DBのバックアップリストアには不向きです。 ↩
- 2.RDSに関するAWS CLIコマンドの一覧は以下を参照してください。 https://docs.aws.amazon.com/cli/latest/reference/rds ↩