LoginSignup
4
1

More than 1 year has passed since last update.

AMIやスナップショットを AWS CLI で一気に削除する

Last updated at Posted at 2022-05-04

1.AMIとスナップショットの一覧を取得する

ここはCloudShell で実施している。

1-1.AMIの一覧を取得する

aws ec2 describe-images --owners <対象AWSアカウントID> を実行すると、以下のようにAMIの詳細がJSON形式でずらずら出てくる。この情報の中から--queryオプションで必要な情報(今回はImageId)を抜き出す。

$ aws ec2 describe-images --owners <対象AWSアカウントID>
{
    "Images": [
        {
            "Architecture": "x86_64",
            "CreationDate": "2022-05-02T10:24:47.000Z",
            "ImageId": "ami-xxxxxxxxxxxxxxxxx",
            "ImageLocation": "<対象AWSアカウントID>/AMI01_sakujo-test-ec202",
            "ImageType": "machine",
            "Public": false,
            "OwnerId": "<対象AWSアカウントID>",
            "PlatformDetails": "Linux/UNIX",
            "UsageOperation": "RunInstances",
            "State": "available",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "SnapshotId": "snap-xxxxxxxxxxxxxxxxx",
                        "VolumeSize": 8,
                        "VolumeType": "gp2",
                        "Encrypted": false
                    }
                }
            ],
            "Description": "AMI01_sakujo-test-ec202",
            "EnaSupport": true,
            "Hypervisor": "xen",
            "Name": "AMI01_sakujo-test-ec202",
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SriovNetSupport": "simple",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "AMI01_sakujo-test-ec202"
                }
            ],
            "VirtualizationType": "hvm"
        },
        :
        :

対象AWSアカウント内のImageIdの一覧

aws ec2 describe-images \
  --owners <対象AWSアカウントID>  \
  --query 'Images[].{Id1:ImageId}' \
  --output text

実行結果をテキストファイルに保存する。

sakujo_AMI_list.txt
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx

1-2.スナップショットの一覧を取得する

aws ec2 describe-snapshots --owner-ids <対象AWSアカウントID> を実行すると、以下のようにスナップショットの詳細がJSON形式でずらずら出てくる。この情報の中から--queryオプションで必要な情報(今回はSnapshotId)を抜き出す。

$aws ec2 describe-snapshots --owner-ids <対象AWSアカウントID>
{
    "Snapshots": [
        {
            "Description": "Created by CreateImage(i-xxxxxxxxxxxxxxxxx) for ami-xxxxxxxxxxxxxxxxx",
            "Encrypted": false,
            "OwnerId": "<対象AWSアカウントID>",
            "Progress": "100%",
            "SnapshotId": "snap-xxxxxxxxxxxxxxxxx",
            "StartTime": "2022-05-02T10:25:08.349000+00:00",
            "State": "completed",
            "VolumeId": "vol-xxxxxxxxxxxxxxxxx",
            "VolumeSize": 8,
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "AMI02_sakujo-test-ec202"
                }
            ],
            "StorageTier": "standard"
        },
        :
        :

対象AWSアカウント内のSnapshotIdの一覧

aws ec2 describe-snapshots \
    --owner-ids <対象AWSアカウントID> \
    --query 'Snapshots[].{Id1:SnapshotId}' \
    --output text

実行結果をテキストファイルに保存する。

sakujo_snapshot_list.txt
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx

2.AMIの削除

以降、Windows 10 にインストールした WSL で実施している。
※削除対象のAMIやスナップショットの数が100個くらいなら、削除権限のあるユーザでログインし CloudShell で削除実施してもよいが、CloudShell には以下のようなセッション制限があるため、長時間の操作に向かない。

  • 無操作状態が続いた場合は約20分でセッションが切れる
  • 約12時間連続で実⾏するとセッションが切れる
  • ⻑時間の操作には不向き

AMIを削除する以下シェルスクリプトを作成する。

sakujo_AMI.sh
#!/bin/bash
# 設定ファイル
ami_list=sakujo_AMI_list.txt
# 日付時刻を文字列にする
jikan=`date +"%Y-%m%d-%H%M-%S"`

# profile
profile_name=<設定したプロファイル名>
# 意図したIAMユーザか確認
aws sts get-caller-identity --profile $profile_name

while read row
do
  echo ":::::::::::::::::::::::::::delete this ami ${row}" >> log/ami_all_log_$jikan.txt 2>&1
  aws ec2 deregister-image --image-id ${row} --profile $profile_name >> log/ami_all_log_$jikan.txt  2>&1
  if [ $? -ne 0 ]; then
    echo ${row} >> log/ami_error_${jikan}.txt
  else
    echo ${row} >> log/ami_ok_${jikan}.txt
  fi
  echo ":::::::::::::::::::::::::::end" >> log/ami_all_log_$jikan.txt  2>&1
sleep 3
done < ${ami_list}

AWS CLI でのプロファイル切り替え(スイッチロール)はAWS CLIでスイッチロール 2.ローカルにインストールしたAWS CLIでスイッチロールを参照。

同じディレクトリ配下は以下のようになっている。

~/sakujo_test$ ls -la
total 28
drwxr-xr-x  3 emi emi 4096 May  3 00:36 .
drwxr-xr-x 10 emi emi 4096 May  3 00:24 ..
drwxr-xr-x  2 emi emi 4096 May  3 00:33 log
-rw-r--r--  1 emi emi  131 May  2 20:24 sakujo_AMI_list.txt
-rw-r--r--  1 emi emi  713 May  3 00:23 sakujo_AMI.sh
-rw-r--r--  1 emi emi  138 May  3 00:35 sakujo_snapshot_list.txt
~/sakujo_test$

上記シェルスクリプト実行結果

$ bash sakujo_AMI.sh
{
    "UserId": "AROAxxxxxxxxxxxxxxxxx:<ユーザ名>",
    "Account": "<対象AWSアカウントID>",
    "Arn": "arn:aws:sts::<対象AWSアカウントID>:assumed-role/<ロール名>/<ユーザ名>"
}
$

logフォルダ配下

$ ls -la log/
total 24
drwxr-xr-x 2 emi emi 4096 May  3 00:33 .
drwxr-xr-x 3 emi emi 4096 May  3 00:36 ..
-rw-r--r-- 1 emi emi  480 May  3 00:29 ami_all_log_2022-0503-0029-37.txt
-rw-r--r-- 1 emi emi  110 May  3 00:29 ami_ok_2022-0503-0029-37.txt
$

ログ

ami_all_log_2022-0503-0029-37.txt
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
ami_ok_2022-0503-0029-37.txt
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx

3.スナップショットの削除

同様に、スナップショットを削除する以下のシェルスクリプトを作成する。

sakujo_snapshot.sh
#!/bin/bash
# 設定ファイル
snapshot_list=sakujo_snapshot_list.txt
# 日付時刻を文字列にする
jikan=`date +"%Y-%m%d-%H%M-%S"`

# profile
profile_name=<設定したプロファイル名>
# 意図したIAMユーザか確認
aws sts get-caller-identity --profile $profile_name

while read row
do
  echo ":::::::::::::::::::::::::::delete this snapshot ${row}" >> log/snapshot_all_log_$jikan.txt 2>&1
  aws ec2 delete-snapshot --snapshot-id ${row} --profile $profile_name >> log/snapshot_all_log_$jikan.txt  2>&1
  if [ $? -ne 0 ]; then
    echo ${row} >> log/snapshot_error_${jikan}.txt
  else
    echo ${row} >> log/snapshot_ok_${jikan}.txt
  fi
  echo ":::::::::::::::::::::::::::end" >> log/snapshot_all_log_$jikan.txt  2>&1
sleep 3
done < ${snapshot_list}

同じディレクトリ配下は以下のようになっている。

~/sakujo_test$ ls -la
total 28
drwxr-xr-x  3 emi emi 4096 May  3 00:36 .
drwxr-xr-x 10 emi emi 4096 May  3 00:24 ..
drwxr-xr-x  2 emi emi 4096 May  3 00:33 log
-rw-r--r--  1 emi emi  131 May  2 20:24 sakujo_AMI_list.txt
-rw-r--r--  1 emi emi  713 May  3 00:23 sakujo_AMI.sh
-rw-r--r--  1 emi emi  138 May  3 00:35 sakujo_snapshot_list.txt
-rw-r--r--  1 emi emi  760 May  3 00:23 sakujo_snapshot.sh
~/sakujo_test$

image.png

上記シェルスクリプト実行結果

$ bash sakujo_snapshot.sh
{
    "UserId": "AROAxxxxxxxxxxxxxxxxx:<ユーザ名>",
    "Account": "<対象AWSアカウントID>",
    "Arn": "arn:aws:sts::<対象AWSアカウントID>:assumed-role/<ロール名>/<ユーザ名>"
}
$

logフォルダ配下

$ ls -la log/
total 24
drwxr-xr-x 2 emi emi 4096 May  3 00:33 .
drwxr-xr-x 4 emi emi 4096 May  3 00:53 ..
-rw-r--r-- 1 emi emi  480 May  3 00:29 ami_all_log_2022-0503-0029-37.txt
-rw-r--r-- 1 emi emi  110 May  3 00:29 ami_ok_2022-0503-0029-37.txt
-rw-r--r-- 1 emi emi  510 May  3 00:33 snapshot_all_log_2022-0503-0033-26.txt
-rw-r--r-- 1 emi emi  115 May  3 00:33 snapshot_ok_2022-0503-0033-26.txt
emi@LAPTOP-AOJR4Q2P:~/sakujo_test$

ログ

snapshot_all_log_2022-0503-0033-26.txt
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx
:::::::::::::::::::::::::::end
snapshot_ok_2022-0503-0033-26.txt
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx

4.参考:--dry-run オプション

AWS CLI コマンドに--dry-runオプションを付けると、実際にはアクションをしないで、コマンドが実行されるかどうか確かめることができる。

4-1.AMI削除コマンドに--dry-runオプションをつける

sakujo_AMI_dry_run.sh
#!/bin/bash
# 設定ファイル
ami_list=sakujo_AMI_list.txt
# 日付時刻を文字列にする
jikan=`date +"%Y-%m%d-%H%M-%S"`

# profile
profile_name=<設定したプロファイル名>
# 意図したIAMユーザか確認
aws sts get-caller-identity --profile $profile_name

while read row
do
  echo ":::::::::::::::::::::::::::delete this ami ${row}" >> log/ami_all_log_$jikan.txt 2>&1
  aws ec2 deregister-image --image-id ${row} --profile $profile_name --dry-run >> log/ami_all_log_$jikan.txt  2>&1
  if [ $? -ne 0 ]; then
    echo ${row} >> log/ami_error_${jikan}.txt
  else
    echo ${row} >> log/ami_ok_${jikan}.txt
  fi
  echo ":::::::::::::::::::::::::::end" >> log/ami_all_log_$jikan.txt  2>&1
sleep 3
done < ${ami_list}

上記シェルスクリプト実行結果

$ bash sakujo_AMI_dry_run.sh
{
    "UserId": "AROAxxxxxxxxxxxxxxxxx:<ユーザ名>",
    "Account": "<対象AWSアカウントID>",
    "Arn": "arn:aws:sts::<対象AWSアカウントID>:assumed-role/<ロール名>/<ユーザ名>"
}
$

ログ

ami_all_log_2022-0503-0021-58.txt
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this ami ami-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
ami_error_2022-0503-0021-58.txt
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx
ami-xxxxxxxxxxxxxxxxx

4-2.スナップショット削除コマンドに--dry-runオプションをつける

--dry-runオプションをつけると、実際にコマンドは実行せず、実行できるかどうかを確認することができる。

sakujo_snapshot_dry_run.sh
#!/bin/bash
# 設定ファイル
snapshot_list=sakujo_snapshot_list.txt
# 日付時刻を文字列にする
jikan=`date +"%Y-%m%d-%H%M-%S"`

# profile
profile_name=20220326_srtest_emiki_PU
# 意図したIAMユーザか確認
aws sts get-caller-identity --profile $profile_name

while read row
do
  echo ":::::::::::::::::::::::::::delete this snapshot ${row}" >> log/snapshot_all_log_$jikan.txt 2>&1
  aws ec2 delete-snapshot --snapshot-id ${row} --profile $profile_name --dry-run >> log/snapshot_all_log_$jikan.txt  2>&1
  if [ $? -ne 0 ]; then
    echo ${row} >> log/snapshot_error_${jikan}.txt
  else
    echo ${row} >> log/snapshot_ok_${jikan}.txt
  fi
  echo ":::::::::::::::::::::::::::end" >> log/snapshot_all_log_$jikan.txt  2>&1
sleep 3
done < ${snapshot_list}

上記シェルスクリプト実行結果

$ bash sakujo_snapshot_dry_run.sh
{
    "UserId": "AROA3KKBATVH7Z7JKDWVN:emiki_cli_user",
    "Account": "<対象AWSアカウントID>",
    "Arn": "arn:aws:sts::<対象AWSアカウントID>:assumed-role/<ロール名>/<ユーザ名>"
}
$

ログ

snapshot_all_log_2022-0503-0018-44.txt
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeleteSnapshot operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeleteSnapshot operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeleteSnapshot operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeleteSnapshot operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeleteSnapshot operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
:::::::::::::::::::::::::::delete this snapshot snap-xxxxxxxxxxxxxxxxx

An error occurred (DryRunOperation) when calling the DeleteSnapshot operation: Request would have succeeded, but DryRun flag is set.
:::::::::::::::::::::::::::end
snapshot_error_2022-0503-0018-44.txt
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx
snap-xxxxxxxxxxxxxxxxx

参考

4
1
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
4
1