データベースのスナップショットを作成したアカウントから別アカウントにコピーする
はじめに
データベースのスナップショットを作成した AWS アカウントから別の AWS アカウントにコピーしたい場合、スナップショットがデフォルトの KMS キー(alias: aws/rds
)で暗号化されていると共有できません。
2つの記事を読むと、別のアカウントにスナップショットを共有するためには、スナップショットをカスタマーマネージドキー(以下:CMK)で暗号化する必要があります。
- Amazon RDS の手動 DB スナップショットまたは Aurora DB クラスタースナップショットを他の AWS アカウントと共有するにはどうすればよいですか? - AWS re:Post
- 暗号化された Amazon Aurora スナップショットを別のアカウントと共有するにはどうすればよいですか? - AWS re:Post
私自身スナップショットの暗号化に使用する KMS キーが共有元、共有先、どちらのアカウントに作成するのか最初わかりませんでした。
調べてみると、AWS のドキュメントには以下のようなことが書いてあります。
スナップショットの暗号化に使用された AWS KMS key を、スナップショットにアクセスできるようにするすべてのアカウントと共有します。 KMS キーポリシーに他のアカウントを追加することで、KMS キーを別の AWS アカウントと共有できます。
さらに AWSの情報センターでは、ターゲットアカウントに、ソースアカウント内のカスタム AWS KMS キーへのアクセスを許可する
方法について記述があります。
つまりKMS のキーは共有元
の AWS アカウントにあり、それを別アカウント(共有先
)に共有することで暗号化されたスナップショットを別アカウントに共有することができるそうです。
今回は、AWS のアーキテクチャ図と一緒に説明している記事が少なく、イメージしづらかったことから自ら検証してみようと思います。
成果物
https://github.com/kntks/blog-code/tree/main/2024/02/copy-rds-snapshot
アーキテクチャ
AWS アカウントを2つ用意します。
Sandbox-1
がスナップショット共有元アカウントで、Sandbox-2
が共有先アカウントです。
以下の画像にあるアーキテクチャを Terraform で作成します。
手順
これから検証する内容の簡単な手順を示します。
- Terraform で環境構築、共有元アカウントに Aurora クラスターと DB インスタンスを作成。
- 踏み台サーバから DB に簡単なデータを Insert する
- デフォルトキーでスナップショットを作成する
- CMK でスナップショットのコピーを作成する
- 共有先アカウントにスナップショットを共有する
- 共有先アカウントでスナップショットから DB を復元する
検証
1. 環境構築
Terraform は 2024 年 1 月現在最新の 1.7.0 を使用します。
RDS のデフォルトキー
Aurora MySQL クラスターと DB インスタンスの作成が完了すると、AWS マネージド型キーに RDS のデフォルトキー(alias: aws/rds
)が作成されます。
AWS マネージドキー は、お客様のアカウントにある KMS キーであり、AWS KMS と統合されている AWS のサービスがお客様に代わって作成し、管理し、使用します。デフォルトでは、RDS AWS マネージドキー (aws/rds) が暗号化に使用されます。
RDS のデフォルトキーのキーポリシー
```json { "Version": "2012-10-17", "Id": "auto-rds-2", "Statement": [ { "Sid": "Allow access through RDS for all principals in the account that are authorized to use RDS", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:CreateGrant", "kms:ListGrants", "kms:DescribeKey" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "rds.ap-northeast-1.amazonaws.com", "kms:CallerAccount": "891377404752" } } }, { "Sid": "Allow direct access to key metadata to the account", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::891377404752:root" }, "Action": [ "kms:Describe*", "kms:Get*", "kms:List*", "kms:RevokeGrant" ], "Resource": "*" } ] } ```2. 踏み台サーバから DB に簡単なデータを Insert する
※ 共有元アカウントでの作業
まず、Aurora MySQL のエンドポイントを確認します。
データベースを作成すると AWS Secret Manager にシークレットが自動で作成されます。そこから root のパスワードを取得します
踏み台サーバのインスタンス ID を取得し、セッションを開始します。
踏み台サーバを立ち上げる際に user_data に mysql client をインストールするスクリプトを入れているので、mysql コマンドが使えるはずです。
踏み台サーバから DB にアクセスします。
参考:Amazon Aurora DB クラスターへの接続 - AWS Documentation
共有先のアカウントでスナップショットから DB を作成したときにデータが入っているかを確認したいため、この作業では、データベースにデータを入れておきます。
Terraform では、database_name
を example
にしたので、use example;
でデータベースを変更できます。
データを作成します。
データが入ったので、問題なさそうです。
3. デフォルトキーでスナップショットを作成する
※ 共有元アカウントでの作業
データベースからスナップショットを作成します。
スナップショットの取得
ボタンを押します。
4. CMK でスナップショットのコピーを作成する
これで RDSのデフォルトキーで暗号化されたスナップショットが取得できます。
Terraform であらかじめ作成していた CMK を設定します。
スナップショットをコピー
のボタンを押した後、example-db-copy-1
のスナップショットが作成されました。
5. 共有先アカウントにスナップショットを共有する
※ 共有元アカウントでの作業
example-db-copy-1
をクリックすると以下のページに遷移します。アクション
からスナップショットの共有
を選択してください。
アクセス許可に Sandbox-2
の AWS アカウントID を入れ、追加
ボタンを押します。
そのあと、保存
ボタンを押してください。
6. 共有先アカウントでスナップショットから DB を復元する
ここからは Sandbox-2
のアカウントでの作業です。
Sandbox-2
のアカウントに移動します。RDS のページに行った後、自分と共有
のタブを確認すると共有されたスナップショットが確認できました。
このスナップショットから復元してみます。
スナップショットを復元
のページが長いため、変更点だけまとめました。
設定 | 値 |
---|---|
DBインスタンス識別子 | example-db-2 |
インスタンスの設定 | 値 |
---|---|
バースト可能クラス | (ラジオボタンにチェックを入れる)db.t3.medium |
接続 | 値 | 補足 |
---|---|---|
VPC | example-vpc | Terraaform で作成済 |
パブリックアクセス | なし | |
VPC セキュリティグループ | 既存の選択 | |
既存の VPC セキュリティグループ | example-db-2 | Terraform で作成済 |
アベイラビリティーゾーン | ap-northeast-1 |
Sandbox-1の時と同じ要領で DB に接続します。パスワードは Sandbox-1 で DB に接続した時と同じです。
Sandbox-2 のアカウントに作成した DB でもデータを復元することができました。
片付け
Sandbox-2 では、DB を手動で作成したので、先に DB を AWS マネジメントコンソールから削除します。
そのあと、Terraform からすべてのリソースを削除します。
さいごに
Sandbox-1 アカウントからスナップショットを取得し、共有することで Sandbox-2 アカウントで復元することができました。
Sandbox-2 でスナップショットを復元した後のデータベースパスワードは、Sandbox-1 のときと同じですが、Sandbox-2 側の AWS Secret Manager にシークレットが作成されるわけではありません。自分で設定する必要があります。
今回の検証では、操作する IAM が Administrator だったため、Sandbox-2 側の IAM について何もしませんでした。ポリシーや PermissionSet の設計をしている組織では、共有先の AWS アカウントでスナップショットを復元するときの権限には注意したほうがよさそうです。
トラブルシューティング
updating policy: MalformedPolicyDocumentException: The new key policy will not allow you to update the key policy in the future
とりあえず、KMS を作成しようと以下のような Terraform を作成したところ、 terraform apply
のタイミングでエラーになりました。
エラー文を読んでみると、ポリシーの更新中: MalformedPolicyDocumentException: 新しいキーポリシーでは将来キーポリシーを更新できません。
と書かれています。
以下の記事では、権限が足りないため発生している事象であることが説明されています。
セーフティチェックの 1 つが、キーポリシーのプリンシパルに CreateKey API と PutKeyPolicy API を実行するために必要な許可があることを確認します。このチェックにより、AWS KMS キーが管理不能になる可能性がなくなります。つまり、キーポリシーを変更したり、キーを削除したりできなくなります。
エラーを解決するために強めの権限をつけてみると解消しました。
Aurora DBクラスターに接続できない
パスワードを入力したにもかかわらず、MySQL がスタートしない場合は、DB に関連している Security Group のルールが間違っている可能性があります。
今回は、EC2 インスタンスに関連していたサブネットからの通信を Security Group が許可していませんでした。