AWS Backupの復旧ポイントからEC2を別のAZへ、プライベートIPを指定してリストアする
こんにちは、林です。
AWS BackupでEC2をリストアするとき、元とは別のAZにリストアしたいことがあります。
たとえばAZ障害のときに、別のAZのサブネットへ同じ構成で立て直す場合です。
コンソールの復元画面ではサブネットを選択できるので、別のAZへのリストアは可能です。
ただし、プライベートIPを指定することができません。

AWS CLIの start-restore-job であれば、リストア先のAZとプライベートIPの両方を指定することができます。この記事では、その手順をご紹介します。
前提
この記事では、次の構成を例にします。ap-northeast-1a のインスタンスを、ap-northeast-1c のサブネットに、プライベートIPを変えてリストアします。
| 項目 | 元 | リストア先 |
|---|---|---|
| AZ | ap-northeast-1a | ap-northeast-1c |
| サブネット | subnet-0axxxxxxxxxxxxxxx | subnet-09xxxxxxxxxxxxxxx |
| プライベートIP | 10.2.1.54 | 10.2.2.54 |
| セキュリティグループ | sg-0cxxxxxxxxxxxxxxx | 変更なし |

リストアの前に決めておくのは、リストア先のサブネットとプライベートIPの2つです。
サブネットは元のインスタンスと同じVPC内で別のAZにあるもの、プライベートIPはそのサブネットのCIDRから未使用のアドレスを選んでください。
実行環境は、jq がインストール済みのAWS CloudShellを想定しています。
< > は前の手順で控えた値に置き換えてください。
AZ・サブネットID・プライベートIPは例の値のままなので、こちらも環境に合わせて置き換えてください。
手順
1. 復旧ポイントのARNを確認する
aws backup list-recovery-points-by-backup-vault \
--backup-vault-name sample-backup-vault \
--query 'RecoveryPoints[].[CreationDate,Status,RecoveryPointArn]' --output table
使用する復旧ポイントの RecoveryPointArn を控えておきます。CreationDate はUTC表示です。
2. リストア先を書き換えたメタデータを作る
復旧ポイントに記録された元のインスタンスの設定値(メタデータ)を取り出し、リストア先に合わせて書き換えます。
2-1. メタデータを取り出す
aws backup get-recovery-point-restore-metadata \
--backup-vault-name sample-backup-vault \
--recovery-point-arn <手順1のRecoveryPointArn> \
| jq '.RestoreMetadata' > restore.json
2-2. AZをリストア先に書き換える
# Placement の値はJSON文字列なので、fromjson で展開して書き換え、@json で文字列に戻す
# "ap-northeast-1c" をリストア先のAZに置き換える
jq '.Placement = (.Placement | fromjson | .AvailabilityZone = "ap-northeast-1c" | @json)' \
restore.json > tmp.json && mv tmp.json restore.json
2-3. サブネットとプライベートIPをリストア先に書き換える
# 元インスタンスの NetworkInterfaceId と PrivateIpAddress、外側の SubnetId と SecurityGroupIds は削除する
# "subnet-09xxxxxxxxxxxxxxx" をリストア先のサブネットID、"10.2.2.54" をリストア後のプライベートIPに置き換える
jq '.NetworkInterfaces = (.NetworkInterfaces | fromjson
| map(del(.NetworkInterfaceId, .PrivateIpAddress, .SecondaryPrivateIpAddressCount, .Ipv6AddressCount)
| .SubnetId = "subnet-09xxxxxxxxxxxxxxx"
| .PrivateIpAddresses = [{Primary: true, PrivateIpAddress: "10.2.2.54"}])
| @json)
| del(.SubnetId, .SecurityGroupIds)' \
restore.json > tmp.json && mv tmp.json restore.json
2-4. 内容を確認する
jq '.Placement | fromjson' restore.json
{
"AvailabilityZone": "ap-northeast-1c",
"GroupName": "",
"Tenancy": "default"
}
jq '.NetworkInterfaces | fromjson' restore.json
[
{
"AssociatePublicIpAddress": true,
"DeleteOnTermination": true,
"Description": "",
"DeviceIndex": 0,
"Groups": [
"sg-0cxxxxxxxxxxxxxxx"
],
"Ipv6Addresses": [],
"PrivateIpAddresses": [
{
"Primary": true,
"PrivateIpAddress": "10.2.2.54"
}
],
"SubnetId": "subnet-09xxxxxxxxxxxxxxx",
"InterfaceType": "interface",
"Ipv4Prefixes": [],
"Ipv6Prefixes": []
}
]
AvailabilityZone・SubnetId・PrivateIpAddress がリストア先の値になっていて、NetworkInterfaceId が消えていれば書き換えはOKです。
3. リストアを実行する
aws backup start-restore-job \
--recovery-point-arn <手順1のRecoveryPointArn> \
--iam-role-arn arn:aws:iam::123456789012:role/sample-backup-role \
--idempotency-token restore-<実行日時 YYYYMMDDhhmm> \
--metadata file://restore.json
出力された RestoreJobId を控えておきます。
再実行するときは --idempotency-token を別の値にしてください。同じ値だと新しいリストアは始まりません。
4. リストアジョブの完了を待つ
aws backup describe-restore-job --restore-job-id <手順3のRestoreJobId> \
--query '{Status:Status,PercentDone:PercentDone,StatusMessage:StatusMessage,CreatedResourceArn:CreatedResourceArn}'
{
"Status": "COMPLETED",
"PercentDone": "100.00%",
"StatusMessage": null,
"CreatedResourceArn": "arn:aws:ec2:ap-northeast-1:123456789012:instance/i-0bxxxxxxxxxxxxxxx"
}
Status が COMPLETED になるまで繰り返し実行します。PENDING / RUNNING の場合は処理中で、FAILED の場合は StatusMessage にエラーの内容が出ています。
CreatedResourceArn 末尾の i- から始まる文字列が新しいインスタンスIDです。
5. リストア先を確認する
aws ec2 describe-instances --instance-ids <新しいインスタンスID> \
--query 'Reservations[].Instances[].{AZ:Placement.AvailabilityZone,SubnetId:SubnetId,PrivateIp:PrivateIpAddress}'
[
{
"AZ": "ap-northeast-1c",
"SubnetId": "subnet-09xxxxxxxxxxxxxxx",
"PrivateIp": "10.2.2.54"
}
]
aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=<新しいインスタンスID> \
--query 'Volumes[].{Device:Attachments[0].Device,VolumeId:VolumeId,AZ:AvailabilityZone}'
[
{
"Device": "/dev/sda1",
"VolumeId": "vol-0fxxxxxxxxxxxxxxx",
"AZ": "ap-northeast-1c"
},
{
"Device": "/dev/sdb",
"VolumeId": "vol-0axxxxxxxxxxxxxxx",
"AZ": "ap-northeast-1c"
}
]
インスタンスもボリュームもリストア先のAZに作られており、プライベートIPは指定した値になっていますね。ボリュームはAZを指定しなくても、リストア先のAZに作られます。

まとめ
AWS CLIを使って、AWS Backupの復旧ポイントからEC2を別のAZにプライベートIPを指定してリストアしてみました。ポイントは次の3つです。
- 別のAZへのリストアはコンソールでもできるが、プライベートIPまで指定するならAWS CLIを使う
- メタデータは、
PlacementのAZとNetworkInterfacesのサブネット・プライベートIPを書き換える - ボリュームはAZを指定しなくても、リストア先のAZに作られる
リストア後は、通常のリストアと同じく、停止保護や自動復旧、タグなどの引き継がれない設定を設定し直す作業が必要です。引き継がれない設定については、こちらの記事にまとめています。
この記事がどなたかの参考になれば幸いです。最後までご覧いただきありがとうございました!
参考







