のぴぴのメモ

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

KMS暗号化されてるEC2インスタンスのAMI取得し別リージョンにコピーする検証(AWS CLI)

はじめに

KMS鍵(CMK)で暗号化したEBSを持つEC2インスタンスのAMIを取得し、別リージョンにコピーする場合、鍵がどうなるのかという確認をCLIで確認したエビデンスです。

結論としては、他リージョンにAMIをコピーする時にコピー先リージョンのCMKを指定することになります。
こちらのRDSの検証と同じ結果です。
nopipi.hatenablog.com

検証環境

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

AWS CLIによる検証手順

(1) 検証設定

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

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

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

#シドニーリージョンの設定
# 実際に検証する環境に合わせて、RDSをデプロイする先のVPCのIPと、サブネットのIDを変更してください。
REGION_DST=ap-southeast-2
REGION_DST_VPCID=vpc-01cfe566
REGION_DST_SUBNET=subnet-1f292656
REGION_DST_EC2_KEY_PAIR=KEY_PAIR_NAME

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

(2) KMSキー作成

EC2インスタンス(EBS)暗号化に利用するKMSキーを、コピー元リージョン、コピー先リージョンそれぞれで作成します。

(2)-(a) コピー元リージョンでのKMSキー作成
SRC_KEY_ID=$( \
aws --profile ${PROFILE} --region ${REGION_SRC} --output text \
    kms create-key \
	    --description "CMK to test Ec2 instance encryption" \
	    --origin AWS_KMS \
	--query 'KeyMetadata.KeyId' )

aws --profile ${PROFILE} --region ${REGION_SRC} \
    kms create-alias \
	    --alias-name alias/Key_To_Test_Instance_Encription \
	    --target-key-id ${SRC_KEY_ID}
(2)-(b) コピー先リージョンでのKMSキー作成
DST_KEY_ID=$( \
aws --profile ${PROFILE} --region ${REGION_DST} --output text \
    kms create-key \
	    --description "CMK to test Ec2 instance encryption" \
	    --origin AWS_KMS \
	--query 'KeyMetadata.KeyId' )

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

(3)コピー元リージョンのEC2作成

セキュリティーグループを作成し、EC2インスタンスを作成します。

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

aws --profile ${PROFILE} --region ${REGION_SRC} \
    ec2 authorize-security-group-ingress \
        --group-id ${SRC_EC2_SG_ID} \
        --protocol tcp \
        --port 22 \
        --cidr 0.0.0.0/0
(3)-(b) EC2インスタンス作成
# Block-device-mappings用のJSON作成
JsonBlockDeviceMappings='
[
    {
        "DeviceName":"/dev/xvda",
        "Ebs":{
            "VolumeType": "gp2",
            "VolumeSize":8,
            "DeleteOnTermination":true,
            "Encrypted": true,
            "KmsKeyId": "'"${SRC_KEY_ID}"'"
        }
    }
]
'

# EC2インスタンスの起動
aws --profile ${PROFILE} --region ${REGION_SRC} \
    ec2 run-instances \
        --count 1 \
        --instance-type t2.micro \
        --image-id ${REGION_SRC_AMZL2_AMI_ID} \
        --key-name ${REGION_SRC_EC2_KEY_PAIR} \
        --monitoring Enabled=true \
        --security-group-ids ${SRC_EC2_SG_ID} \
        --subnet-id ${REGION_SRC_SUBNET} \
        --associate-public-ip-address \
        --block-device-mappings "${JsonBlockDeviceMappings}" \
        --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=EC2-KMS-TEST-SRC}]'
    
# EC2インスタンスのID取得
SRC_INSTANCE_ID=$(
aws --profile ${PROFILE} --region ${REGION_SRC} --output text \
    ec2 describe-instances \
        --filters "Name=tag:Name,Values=EC2-KMS-TEST-SRC" \
    --query 'Reservations[*].Instances[*].InstanceId'
)

(4) (オプション)コピー元リージョンのEC2でファイルを作成する

作成したEC2にsshログインし、ファイルを作成します。

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

echo 'Hello World!!' > test.txt 

(5)コピー元リージョンのEC2のAMI取得

作成したEC2インスタンスのAMIを取得します。
データの静止点を取るため最初にインスタンスを停止し、AMIを取得します。
EBSが暗号化されている場合、AMI(正確にはAMI用に取得されたEBSのスナップショット)もインスタンスのEBSと同じCMKで暗号化されます。

(5)-(a) EC2インスタンス停止
aws --profile ${PROFILE} --region ${REGION_SRC} \
    ec2 stop-instances \
        --instance-ids ${SRC_INSTANCE_ID}
(5)-(b) AMI取得
#AMI取得
aws --profile ${PROFILE} --region ${REGION_SRC} \
    ec2 create-image \
        --instance-id ${SRC_INSTANCE_ID} \
        --name "SRC_INSTANCE_AMI"

#取得したAMIのID取得
SRC_AMI_ID=$(
aws --profile ${PROFILE} --region ${REGION_SRC} --output text \
    ec2 describe-images \
        --filters "Name=name,Values=SRC_INSTANCE_AMI"  \
    --query 'Images[*].{ID:ImageId}'
)

(6)取得したAMIの他リージョンへのコピー

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

#AMIのコピー
aws --profile ${PROFILE} --region ${REGION_DST} \
    ec2 copy-image \
        --source-image-id ${SRC_AMI_ID} \
        --source-region ${REGION_SRC} \
        --name COPY_AMI_FROM_SRC_REGION \
        --encrypted \
        --kms-key-id ${DST_KEY_ID}

#コピーしたAMIのID取得
DST_AMI_ID=$(
aws --profile ${PROFILE} --region ${REGION_DST} --output text \
    ec2 describe-images \
        --filters "Name=name,Values=COPY_AMI_FROM_SRC_REGION"  \
    --query 'Images[*].{ID:ImageId}'
)

(7)コピー先リージョンでAMIからインスタンスを起動

セキュリティーグループを作成し、コピー元リージョンからコピーしたAMIからインスタンスを起動します。

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

aws --profile ${PROFILE} --region ${REGION_DST} \
    ec2 authorize-security-group-ingress \
        --group-id ${DST_EC2_SG_ID} \
        --protocol tcp \
        --port 22 \
        --cidr 0.0.0.0/0
(7)-(b) EC2インスタンス作成
# EC2インスタンスの起動
aws --profile ${PROFILE} --region ${REGION_DST} \
    ec2 run-instances \
        --count 1 \
        --instance-type t2.micro \
        --image-id ${DST_AMI_ID} \
        --key-name ${REGION_DST_EC2_KEY_PAIR} \
        --monitoring Enabled=true \
        --security-group-ids ${DST_EC2_SG_ID} \
        --subnet-id ${REGION_DST_SUBNET} \
        --associate-public-ip-address \
        --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=EC2-KMS-TEST-DST}]'

(8) (オプション)コピー元リージョンのEC2でファイルを確認する

作成したEC2にsshログインし、コピー元リージョンで作成したファイルがあるか確認します。

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

ll
cat test.txt 

(追加確認)EBSスナップショットの他リージョンコピーの場合

EBSスナップショットを他リージョンにコピーする場合も、スナップショットコピー時にコピー先リージョンのCMKを指定します。

#コピー元リージョンで、AMI作成時に作成されたEBSスナップショットを設定
#"Created by CreateImage(i-xxxxx) for ami-xxxx"という説明のスナップショット
SRC_SNAPSHOT_ID=snap-06e05677d40f66db5

#EBSスナップショットを他リージョンにコピー
aws --profile ${PROFILE} --region ${REGION_DST} \
    ec2 copy-snapshot \
        --source-snapshot-id ${SRC_SNAPSHOT_ID} \
        --source-region ${REGION_SRC} \
        --encrypted \
        --kms-key-id ${DST_KEY_ID}