のぴぴのメモ

自分用のLinuxとかの技術メモ

RDS KMS暗号化されてるDBインスタンスをスナップショットで別リージョンにコピーする検証(AWS CLI)

はじめに

RDSをKMSの鍵で暗号化する場合、RDSインスタンスがあるそれぞれのリージョンKMS鍵(CMK:Customer Master Key)で暗号化しますが、DBスナップショットで、他リージョンにDBをコピーする場合、鍵はどうなるのかということを確認するための検証手順です。

結論としては、他リージョンにDBスナップショットをコピーする時にコピー先リージョンのCMKを指定することになります。

f:id:nopipi:20191008201217p:plain:w500

検証環境

  • この検証はAWS CLIをセットアップしたMacで実施
    • bash環境なので、Linuxなどbash環境下であれば実行はできると思います。
  • AWS CLIのプロファイルは設定済み前提
  • プロファイルのIAMロール(IAMユーザ)にはAdministratorAccessポリシーがある前提
  • 検証ではRDS(MySQL)を利用
  • オプションのMySQL書き込み用のEC2インスタンスが既存であることが前提

AWS CLIによる検証手順

(1) 検証設定

CLIに渡すパラメータのいくつかを、シェルの変数として事前設定しています。

#作業端末のプロファイル指定(デフォルトでない場合適時変更して下さい)
PROFILE=default

#東京リージョンの設定
# 実際に検証する環境に合わせて、RDSをデプロイする先のVPCのIPと、サブネットのIDを変更してください。
REGION_SRC=ap-northeast-1
REGION_SRC_VPCID="vpc-8e6c5ce9"
REGION_SRC_SUBNETS="subnet-48cfe313 subnet-a2448189 subnet-0214e64a"

#シンガポールリージョンの設定
# 実際に検証する環境に合わせて、RDSをデプロイする先のVPCのIPと、サブネットのIDを変更してください。
REGION_DST=ap-southeast-1
REGION_DST_VPCID="vpc-0bcdca6c"
REGION_DST_SUBNETS="subnet-8307a0da subnet-1eae4578 subnet-58cdd511"

#RDS設定
RDS_INSTANCE_CLASS=db.m5.large
RDS_ENGIN=MySQL
RDS_ENGIN_VERSION=8.0.16
RDS_DB_ADMIN=admin
RDS_DB_ADMIN_PASSWD=password

AWS_ACCOUNT=$(
aws --profile ${PROFILE} --region ${REGION_SRC} --output text \
    sts get-caller-identity --query 'Account' )

(2) KMSキー作成

RDS暗号化に利用するKMSキーを、東京リージョン、シンガポールリージョンそれぞれで作成します。

f:id:nopipi:20191008201222p:plain:w500

(2)-(a) 送付元リージョンでのKMSキー作成
SRC_KEY_ID=$( \
aws --profile ${PROFILE} --region ${REGION_SRC} --output text \
    kms create-key \
	    --description Key_For_Source_Snapshot \
	    --origin AWS_KMS \
	--query 'KeyMetadata.KeyId' )

aws --profile ${PROFILE} --region ${REGION_SRC} \
    kms create-alias \
	    --alias-name alias/Key_For_Source_Snapshot \
	    --target-key-id ${SRC_KEY_ID}
(2)-(b) 送付先リージョンでのKMSキー作成
DST_KEY_ID=$( \
aws --profile ${PROFILE} --region ${REGION_DST} --output text \
    kms create-key \
	    --description Key_For_Source_Snapshot \
	    --origin AWS_KMS \
	--query 'KeyMetadata.KeyId' )

aws --profile ${PROFILE} --region ${REGION_DST} \
    kms create-alias \
	    --alias-name alias/Key_For_Destination_Snapshot \
	    --target-key-id ${DST_KEY_ID}

(3)東京リージョンのRDS作成

セキュリティーグループを作成とRDSのサブネットグループを作成し、RDSを作成します。

f:id:nopipi:20191008201231p:plain:w500

(3)-(a) SecurityGroup作成
SRC_RDS_SG_ID=$( \
aws --profile ${PROFILE} --region ${REGION_SRC} --output text \
    ec2 create-security-group \
        --group-name SgForRdsMySQL \
        --description "SG for RDS MySQL" \
        --vpc-id ${REGION_SRC_VPCID} \
	--query 'GroupId' )

aws --profile ${PROFILE} --region ${REGION_SRC} \
    ec2 authorize-security-group-ingress \
        --group-id ${SRC_RDS_SG_ID} \
        --protocol tcp \
        --port 3306 \
        --cidr 0.0.0.0/0
(3)-(b) RDS作成(サブネットグループ作成)
aws --profile ${PROFILE} --region ${REGION_SRC} \
    rds create-db-subnet-group \
        --db-subnet-group-name rds_mysql \
        --db-subnet-group-description "KMS TEST for RDS MySQL" \
        --subnet-ids ${REGION_SRC_SUBNETS}
(3)-(c) RDS作成(MySQLインスタンス作成)
aws --profile ${PROFILE} --region ${REGION_SRC} \
    rds create-db-instance \
    --db-instance-identifier Test-RDS-MySQL \
    --db-instance-class ${RDS_INSTANCE_CLASS} \
    --engine ${RDS_ENGIN} \
    --engine-version ${RDS_ENGIN_VERSION} \
    --allocated-storage 20 \
    --master-username ${RDS_DB_ADMIN} \
    --master-user-password ${RDS_DB_ADMIN_PASSWD} \
    --backup-retention-period 3 \
    --vpc-security-group-ids ${SRC_RDS_SG_ID} \
    --no-publicly-accessible \
    --db-subnet-group-name rds_mysql \
    --storage-encrypted \
    --kms-key-id ${SRC_KEY_ID}

(4) (オプション)東京リージョンRDS(MySQL)にデータを書き込む

RDSと同じVPC上のEC2から、RDSにアクセスしテーブル作成とデータインサートを行います。

#sshで、RDSのあるVPC上のEC2にログインして下記を実行

sudo yum -y install mysql

mysql -h <RDSのエンドポイントURL> -u admin -p
#パスワード(password)入力

MySQL > CREATE DATABASE sampledb;
MySQL > USE sampledb;
MySQL > 
CREATE TABLE IF NOT EXISTS `sample` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL DEFAULT 'hoge',
  PRIMARY KEY(`id`)
);
MySQL > INSERT INTO sample( name ) VALUES ( '鈴木' );
MySQL > COMMIT;
MySQL > SELECT * FROM sample;
MySQL > quit

(5)東京リージョンのRDS スナップショットの取得

RDSを作成し、DBインスタンスが起動したらスナップショットを手動取得します。
暗号化されたRDSから取得されたスナップショットは暗号されており、KMSでDBを暗号化している場合同じCMKでスナップショットも暗号化されます。

f:id:nopipi:20191008201235p:plain:w500

aws --profile ${PROFILE} --region ${REGION_SRC} \
    rds create-db-snapshot \
        --db-instance-identifier Test-RDS-MySQL \
        --db-snapshot-identifier snapshot-for-cross-region-replication-src-db

(6)取得したスナップショットのシンガポールリージョンにコピー

東京リージョンで取得したスナップショットを、シンガポールリージョンにコピーします。
コピー先のシンガポールリージョンで実行しているところに注意ください。(--reogionオプション指定を見てください)

f:id:nopipi:20191008201241p:plain:w500

aws --profile ${PROFILE} --region ${REGION_DST} \
    rds copy-db-snapshot \
        --source-db-snapshot-identifier arn:aws:rds:${REGION_SRC}:${AWS_ACCOUNT}:snapshot:snapshot-for-cross-region-replication-src-db \
        --target-db-snapshot-identifier snapshot-for-cross-region-replication-dst-db \
        --source-region ${REGION_SRC} \
        --kms-key-id ${DST_KEY_ID}

(7)シンガポールリージョンでスナップショットからRDSを作成

セキュリティーグループを作成とRDSのサブネットグループを作成し、東京リージョンからコピーしたスナップショットからRDSインスタンスを複製します。スナップショットからのインスタンスの複製には" restore-db-instance-from-db-snapshot"を利用します。

f:id:nopipi:20191008201247p:plain:w500

(7)-(a) SecurityGroup作成
DST_RDS_SG_ID=$( \
aws --profile ${PROFILE} --region ${REGION_DST} --output text \
    ec2 create-security-group \
        --group-name SgForRdsMySQL \
        --description "SG for RDS MySQL" \
        --vpc-id ${REGION_DST_VPCID} \
	--query 'GroupId' )

aws --profile ${PROFILE} --region ${REGION_DST} \
    ec2 authorize-security-group-ingress \
        --group-id ${DST_RDS_SG_ID} \
        --protocol tcp \
        --port 3306 \
        --cidr 0.0.0.0/0
(7)-(b) RDS作成(サブネットグループ作成)
aws --profile ${PROFILE} --region ${REGION_DST} \
    rds create-db-subnet-group \
        --db-subnet-group-name rds_mysql \
        --db-subnet-group-description "KMS TEST for RDS MySQL" \
        --subnet-ids ${REGION_DST_SUBNETS}
(7)-(c) RDS作成(MySQLインスタンスのスナップショットからの復元)
aws --profile ${PROFILE} --region ${REGION_DST} \
    rds restore-db-instance-from-db-snapshot \
        --db-instance-identifier Test-RDS-MySQL-DST \
        --db-snapshot-identifier snapshot-for-cross-region-replication-dst-db \
        --vpc-security-group-ids ${DST_RDS_SG_ID} \
        --db-subnet-group-name rds_mysql

(8) (オプション)シンガポールリージョンRDS(MySQL)のデータを確認する

復元したRDSで、東京リージョンでインサートしたデータがあるか確認します。

#sshで、RDSのあるVPC上のEC2にログインして下記を実行

sudo yum -y install mysql

mysql -h <RDSのエンドポイントURL> -u admin -p
#パスワード(password)入力

MySQL > USE sampledb;
MySQL > SELECT * FROM sample;
MySQL > quit