目次
はじめに
大規模なアカウントの場合、膨大な量のスナップショットがアカウント内にあって、どれが不要なものなのかわからない時ってあるかと思います。
そんな時にスナップショットとEBSボリュームIDを紐づけできたらいいなと思ってスクリプトを作成しました。
そして、詰まった個所があったので情報共有します。
やりたかったこと
「aws ec2 describe-snapshots」コマンドを使用して、スナップショットIDを一覧で取得し、「aws ec2 describe-volumes」コマンドでスナップショットの作成元であるボリュームIDを取得しようと考えていました。
例えば、1つのボリュームから複数のスナップショットが作成されたとき、以下のような形でリスト出力できたらなと考えていました。
ボリュームID,スナップショットID #ヘッダー部
VolumeAAA,Snapshot1
VolumeAAA<Snapshot2
VolumeAAA,Snapshot3
ですが、、、、うまくいきませんでした。
うまくいかなかった理由
結果から言うと、「aws ec2 describe-volumes」コマンドで取得できるボリュームIDについて勘違いしていたことが原因でした。
私が想像していた「aws ec2 describe-volumes」コマンドの実行結果は、「スナップショットIDの作成元ボリュームID(親)が返ってくる」と思っていました。
ですが実際には「指定したIDのスナップショットから作成されたボリュームID(子)が返ってくる」というものでした。
実際にスナップショットIDを取得し、それに紐づいたボリュームIDを取得することで動作を確認していきます。
実行環境
今回検証する環境のボリューム一覧とスナップショット一覧を見ていきます。
リージョンはバージニア北部で行っています。
まず初めに検証用にボリュームを3つ用意しました。
そして、検証用に作成したボリュームからスナップショットをそれぞれ作成しました。
ボリュームとスナップショットの親子関係を表すと図のようになります。
ボリュームが「親」でスナップショットが「子」とします。
検証
使用したスクリプトは以下になります。
仕組みを簡単に説明すると、リージョン内のスナップショットIDを一覧で取得し、スナップショットIDを1行ずつ読み込みます。
そして、読み込んだスナップショットIDに関連付けられたボリュームIDを取得します。
#!bin/bash
VolumeIdList="VolumeId-list.tmp"
SnapshotIdList="SnapshotId-list.tmp"
Regions="us-east-1"
OutputFile="Snapshot-VolumeID-List.csv"
echo "実行開始"
#csvのヘッダーを作成
echo "VolumeID,SnapshotID" > $OutputFile
#スナップショットIDのリストを取得する
aws ec2 describe-snapshots --owner-ids self --region=$Regions --query "Snapshots[*].[SnapshotId]" --output text > $SnapshotIdList
cat $SnapshotIdList | while read snapshotId
do
#指定したスナップショットのボリュームIDを取得する
aws ec2 describe-volumes --region=$Regions --filters "Name=snapshot-id,Values=$snapshotId" --query "Volumes[*].[VolumeId]" --output text > $VolumeIdList
cat $VolumeIdList | while read volumeId
do
#スナップショットIDとボリュームをCSVに出力する
echo "$volumeId,$snapshotId" >> $OutputFile
done
done
echo "実行完了"
rm $VolumeIdList $SnapshotIdList
一見するとスナップショットIDとボリュームIDがセットで取得できそうですが、ボリュームIDは取得できません。
ボリュームIDが取得できないか確認する前に、スナップショットIDが正常に取得できているのか確認してみます。
以下のコマンドの変数部分をちょっとだけ書き換えて、テキスト形式で出力してみます。
aws ec2 describe-snapshots --owner-ids self --region=$Regions --query "Snapshots[*].[SnapshotId]" --output text > $SnapshotIdList
スナップショットが一覧で取得できました。
次に以下のコマンドの変数部分を書き換えて、ボリュームIDを出力してみます。
aws ec2 describe-volumes --region=$Regions --filters "Name=snapshot-id,Values=$snapshotId" --query "Volumes[*].[VolumeId]" --output text > $SnapshotIdList
ボリュームIDは出力されませんでした。
ほかのスナップショットIDを指定してみても同様に何も出力されません。
ボリュームを復元
3つのスナップショットからそれぞれボリュームを復元しました。
冒頭に「aws ec2 describe-volumes」コマンドは「指定したIDのスナップショットから作成されたボリュームID(子)が返ってくる」ものだと説明しましたが、はたして本当なのかボリュームを復元してもう一度「aws ec2 describe-volumes」コマンドを実行してみます。
ちょっと名前の付け方失敗してわかりづらくなってますが、図のような親子関係になっています。
「Volume1」からみて「from-Snapshot1」のボリュームは孫にあたります。
この状態で再度「aws ec2 describe-volumes」コマンドを実行してみます。
「aws ec2 describe-snapshots」コマンドでスナップショットIDを確認します。
「aws ec2 describe-volumes」コマンドでボリュームIDを取得します。
今度はうまく取得できました!
スクリプトの実行
スナップショットIDと、スナップショットから作成されたボリュームIDをCSV形式で出力します。
出力された「Snapshot-VolumeID-List.csv」の中を見てみると、
スナップショットとスナップショットから作成されたボリュームIDが取得できていました!!
さいごに
取得できないボリュームIDがたくさんあって原因がわからずかなり悩んでいたのですが、検証してみて本当に良かったです。
皆さんもdescribe-volumesコマンドを使用する際は、返ってくる値がスナップショットの「作成元ボリュームID」なのか、「復元したボリュームID」なのか注意してください
これがわかるまでは本当にしんどかったです。。。。