我が家ではSynologyNASを利用していますが、GlacierBackupというアプリを利用してSynologyNASのデータをS3 Glacierにバックアップしています。
バックアップの設定を見直した際、昔のボールトを削除することにしたので、削除する方法をまとめておきます。
S3 Glacierのボールトを削除する方法として、SDK・REST API・CLIのいずれかの利用が必要になりますが、今回はCLIツールを利用した削除を行っていきます。
※下記手順はAWSの公式ドキュメントを参考にしています。(Deleting an Archive in Amazon S3 Glacier Using the AWS Command Line Interface)
AWS CLIツールのインストール
AWS CLIは公式ドキュメントを参考にインストールします。(参考:AWS CLI の最新バージョンをインストールまたは更新します。)
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
次にprofileを作成します。profileの作成に必要なアクセスキーとシークレットキーは、事前にAWSコンソールのIAMで作成しておきます。
$ aws configure --profile your-profile-name
...
AWS CloudShellの起動(アーカイブ数が少ない人向け)
AWS CLIツールをインストールしても良いのですが、ボールト内のアーカイブ数が少ない場合、ブラウザで提供されているCloudShellで十分なので、AWSのコンソールにログインしてCloudShellを起動しましょう。
AWSコンソール右上の端末ボタンをクリックするとCloudShellが起動します。
ボールトの削除
ボールトの削除は下記手順で実施します。
- ボールト情報(ボールト名)の取得
- ボールトイベントリの取得ジョブ実行
- アーカイブの削除
- ボールトの削除
ボールトは、ボールト内に保存されているアーカイブが存在すると削除できないので、まず全てのアーカイブを削除する必要があります。また、アーカイブIDはボールトイベントリに記載されているので、ボールトイベントリの取得も必要になります。
各手順について、詳細を説明していきます。
ボールト情報の取得
ボールトの情報を取得します。アカウントIDは、AWSコンソールの右上にあるアカウント名からアカウントIDはコピーできます。下記の出力では、123,446件のアーカイブが含まれていることがわかります。
※--profileオプションは、awsコマンドでプロファイルを指定しているだけなので、デフォルトのプロファイルを利用している場合は不要です。
$ export AWS_ACCOUNT_ID=111122223333
$ export AWS_PROFILE=your-profilename
$ aws glacier list-vaults --account-id $AWS_ACCOUNT_ID --profile $AWS_PROFILE
{
"VaultList": [
{
"VaultARN": "arn:...",
"VaultName": "vault name",
"CreationDate": "2021-...",
"LastInventoryDate": "2022-...",
"NumberOfArchives": 123446,
"SizeInBytes": 392158741741
},
]
}
削除したいボールト名を環境変数に保存しておきます。
$ export AWS_VAULT_NAME="vault name"
ボールトイベントリのダウンロードジョブの実行
ボールト内のアーカイブIDを取得するため、ボールトイベントリをダウンロードします。この処理には数時間かかるので、途中で出力されるJobIDなどはどこかに保存しておきましょう。
ジョブを実行します。
# イベントリ取得用Jobの実行
$ aws glacier initiate-job --vault-name $AWS_VAULT_NAME --account-id $AWS_ACCOUNT_ID --profile $AWS_PROFILE --job-parameters "{\"Type\":\"inventory-retrieval\"}"
{
"location": "...",
"jobId": "..."
}
ジョブが正常に実行されているか、確認します。
$ export AWS_JOB_ID=...
$ aws glacier describe-job --vault-name $AWS_VAULT_NAME --account-id $AWS_ACCOUNT_ID --job-id $AWS_JOB_ID --profile $AWS_PROFILE
...
"CreationDate": "2023-04-19T01:25:57.830Z",
"Completed": false,
"StatusCode": "InProgress",
...
この処理は数時間かかるので、完了するまで待ちます(※ジョブ完了から24時間以上たつと取得したアーカイブIDが無効になるので、必ず24時間以内に下記の削除を終わらせてください。)。
ちなみに、ジョブが完了すると下記のような出力となります。
$ aws glacier describe-job --vault-name $AWS_VAULT_NAME --account-id $AWS_ACCOUNT_ID --job-id $AWS_JOB_ID --profile $AWS_PROFILE
...
"Completed": true,
"StatusCode": "Succeeded",
"StatusMessage": "Succeeded",
...
アーカイブの削除
上記で実行したイベントリ取得ジョブの出力にアーカイブIDが含まれているので、JSONファイルに出力します。
$ aws glacier get-job-output --vault-name $AWS_VAULT_NAME --account-id $AWS_ACCOUNT_ID --job-id $AWS_JOB_ID output.json --profile $AWS_PROFILE
{
"status": 200,
"acceptRanges": "bytes",
"contentType": "application/json"
}
JSONファイルの中身を確認してみます。各アーカイブ毎のIDが取得できているのが確認できます。
$ cat output.json | jq .
{
"VaultARN": "arn:aws:hoge",
"InventoryDate": "2022-..",
"ArchiveList": [
{
"ArchiveId": "archive-id",
"ArchiveDescription": "",
"CreationDate": "2021-...",
"Size": 15627,
"SHA256TreeHash": "hash"
},
{..}
}
]
すべてのアーカイブを一括で削除するために、シェルスクリプト(delete-archives.sh)を作成します。
下記のシェルスクリプトはGitHubのIssueを参考に作成しました(参考:AWS Glacier: Delete vault)。プロセッサー数(nprocコマンド)×2分の同時実行を可能にしています。
#!/usr/bin/env bash
file='./output.json'
id_file='./output-archive-ids.txt'
if [[ -z ${AWS_ACCOUNT_ID} ]] || [[ -z ${AWS_PROFILE} ]] || [[ -z ${AWS_VAULT_NAME} ]]; then
echo "Please set the following environment variables: "
echo "AWS_ACCOUNT_ID"
echo "AWS_VAULT_NAME"
echo "AWS_PROFILE"
exit 1
fi
echo "Started at $(date)"
echo -n "Getting archive ids from $file..."
if [[ ! -f $id_file ]]; then
cat $file | jq -r --stream ". | { (.[0][2]): .[1]} | select(.ArchiveId) | .ArchiveId" > $id_file 2> /dev/null
fi
total=$(wc -l $id_file | awk '{print $1}')
echo "got $total"
num=0
while read -r archive_id; do
num=$((num+1))
echo "Deleting archive $num/$total at $(date)"
aws glacier delete-archive --archive-id=${archive_id} --vault-name ${AWS_VAULT_NAME} --account-id ${AWS_ACCOUNT_ID} &
[ $( jobs | wc -l ) -ge $(($(nproc)*2)) ] && wait
done < "$id_file"
wait
echo "Finished at $(date)"
echo "Deleted archive ids are in $id_file"
アーカイブを削除します。今回の例ではアーカイブ数が多いのでバックグラウンドで実行するようにnohupを利用していますが、少ない場合nohupは必要ありません。
$ chmod +x delete-archives.sh
$ nohup ./delete-archives.sh > delete-archives.log 2>&1 &
$ tail -f delete-archives.log
削除できたかを確認しますが、アーカイブの削除が反映されるまで半日ー1日程度かかってしまいます。
$ aws glacier describe-job --vault-name $VAULT_NAME --account-id $ACCOUNT_ID
ボールトの削除
アーカイブを削除したら、ボールトを削除可能になるので、削除します。
$ aws glacier delete-vault --account-id $AWS_ACCOUNT_ID --vault-name $AWS_VAULT_NAME
削除されたかを確認します。
$ aws glacier list-vaults --account-id -
{
"VaultList": []
}
AWSのポータルからも削除されているはずです。
まとめ
S3 Glacierのボールトを削除する方法を紹介しました。
コンソールから操作できないのが面倒くさいですし、結果が返ってくるまでも結構時間がかかります。データの保存料がやすいので、このあたりはしょうがないかもしれませんね。