0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS CLIを使ってAMIからEC2をリストアする際に、リストア元のAMIのタグを引き継ぐ方法

Posted at

はじめに

今携わっているシステムでは、AWSを使っています。
通常時はEC2インスタンスを東京リージョンで稼働させ、月次でバックアップ(AMI、EBSスナップショット)を取得したうえ大阪リージョンに転送しています。
東京リージョンに大規模災害が発生する際に、大阪リージョンに転送されたAMIから、EC2インスタンスをリストアするためです。

リストア方法

世の中的にCloudformationやTerraformなどのIaCを活用してリストアする方法が主流になっていますが、おとなの事情により、シェルスクリプトにAWS CLIを叩く処理を記載し、リストア時に実行するというやり方を取っています。
なお、パラメータ等は外部JSONファイルに記載し、AWS CLIコマンドのオプションとして渡すようにしています。

AMIのタグが引き継がれない問題

AMIからEC2をリストアするには、以下のようにrun-instancesコマンドにAMI IDを渡すという方法を取りますが、このまま実行してもAMIに含まれるタグが引き継がれないので、リストア後に手動でタグを付与するという手間が発生する(一部オプションを省略しています)。
aws ec2 run-instances --image-id $IMAGE-ID 

AMIからタグを取得してインスタンスに付与する

run-instancesコマンドを実行する際に、tag-specificationオプションで

ResourceType=string,Tags=[{Key=string,Value=string},{Key=string,Value=string}]

のフォーマットに従ってタグを渡せば、タグ付きのインスタンスを作成できます。

でしたら、AMIからタグを取得し、それをtag-specificationに渡せば手動でタグをつける手間がなくなります。

AMIからタグを取得するには、以下のようにdescribe-imagesコマンドをフィルター付きで実行します。
aws ec2 describe-images --filters "Name=image-id,Values=$IMAGE_ID" --query 'Images[0].Tags[*]'

そしたらこのように、AMIのタグが返されます。

[
  {
    "Key": "Key1",
    "Value": "Value1"
  },
  {
    "Key": "Key2",
    "Value": "Value2"
  }
]

しかし、これをそのままtag-specificationに渡しても、エラーで終わってしまいます。
なぜなら、tag-specificationが必要としているフォーマットと異なるからです。

解決方法

以下のように、AMIから取得したタグから、

  • 角括弧を削除
  • ダブルクォーテーションを削除
  • スペースを削除
  • 改行を削除
  • コロンを=に置換
    などをし、整形します。
TAGS=`aws ec2 describe-images --filters "Name=image-id,Values=$IMAGE_ID" --query 'Images[0].Tags[*]' |tr -d '['|tr -d ']'|tr -d '"'|tr -d ' '|tr -d '\n'|tr ':' '='`

整形したタグを、変数化し、tag-specificationに渡します。

aws ec2 run-instances \
--image-id $IMAGE_ID \
--tag-specification ResourceType=instance,Tags="[$TAGS]" \
--cli-input-json file://${INSTANCE_NAME}.json \
--query "Instances[*].InstanceId" \
--output text

スクリプト

以上をまとめると、以下のようなスクリプトが出来上がります。

ec2-restore.sh
# リストア先のリージョン。今回は大阪リージョン
REGION="ap-northeast-3"

# インスタンス名。インスタンスのNameタグとしても定義されています。
INSTANCE_NAME="SAMPLE-INSTANCE"

# インスタンス名をキーに、作成日が一番新しいAMIのIDを取得する
IMAGE_ID=`aws ec2 describe-images \
--filters "Name=tag:Name,Values=$INSTANCE_NAME" \
--query "reverse(sort_by(Images[].{CreationDate:CreationDate, ImageId:ImageId},$CreationDate)) | [0].ImageId" --region $REGION |tr -d '"'`

# AMIから、タグを取得する
TAGS=`aws ec2 describe-images --filters "Name=image-id,Values=$IMAGE_ID" --query 'Images[0].Tags[*]' |tr -d '['|tr -d ']'|tr -d '"'|tr -d ' '|tr -d '\n'|tr ':' '='`

# AMIからインスタンスをリストアする。諸々パラメータは、${INSTANCE_JSON}.jsonという外部ファイルで渡しています。
INSTANCE_ID=`aws ec2 run-instances \
--image-id $IMAGE_ID \
--tag-specification ResourceType=instance,Tags="[$TAGS]" \
--cli-input-json file://${INSTANCE_NAME}.json \
--query "Instances[*].InstanceId" \
--output text`


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?