Answers:
在很大程度上受已经在其他答案中链接的博客文章和要旨的启发,这是我对问题的看法。
我确实使用了一些复杂的JMESpath函数来获取快照列表,而不需要tr
。
免责声明:使用时需要您自担风险,我会尽力避免出现任何问题并保持合理的默认值,但是如果这给您造成问题,我将不承担任何责任。
#!/bin/sh
# remove x if you don't want to see the commands
set -ex
# Some variable initialisation with sane defaults
DRUN='--dry-run'
DO_DELETE=${1:-'no'}
REGION=${2:-'eu-west-1'}
ACCOUNTID=${3:-'self'}
# Get two temporary files
SNAP_FILE=$(mktemp)
IMAGE_FILE=$(mktemp)
# Get the snapshot list and the volume list
aws --region "$REGION" ec2 describe-snapshots --owner-ids "$ACCOUNTID" --query 'Snapshots[*].[SnapshotId]' --output text > "$SNAP_FILE"
aws --region "$REGION" ec2 describe-images --owners "$ACCOUNTID" --filters Name=state,Values=available --query 'Images[*].BlockDeviceMappings[*].Ebs.[SnapshotId]' --output text > "$IMAGE_FILE"
# Check if the outputed command should be dry-run (default) or not
if [ "$DO_DELETE" = "IAMSURE" ]
then
DRUN=''
fi
# count each snapshot id, decrease when a volume reference it, print delete command for those with no volumes
awk -v REGION="$REGION" -v DRUN="$DRUN" '
FNR==NR { snap[$1]++; next } # increment snapshots and get to next line in file immediately
{ snap[$1]-- } # we changed file, decrease the snap counter when a volume reference it
END {
for (s in snap) { # loop over the snapshots
if (snap[s] > 0) { # if we did not decrese under 1 that means there is no volume referencing this snapshot
cmd="aws --region " REGION " " DRUN " ec2 delete-snapshot --snapshot-id " s
print(cmd)
}
}
}
' "$SNAP_FILE" "$IMAGE_FILE"
# Clean up the temp files
rm "$SNAP_FILE" "$IMAGE_FILE"
我希望脚本本身能够被足够注释。
默认用法(无参数)将列出当前帐户和区域eu-west-1的孤立快照的删除命令,提取:
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-81e5856a
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-95c68c7e
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-a3bf50bd
您可以将此输出重定向到文件以供查看,然后再采购以执行所有命令。
如果要脚本执行命令而不是打印命令,请替换print(cmd)
为system(cmd)
。
用法如下,脚本名为snap_cleaner
:
适用于us-west-1地区的空运行命令
./snap_cleaner no us-west-1
用于eu-central-1中的可用命令
./snap_cleaner IAMSURE eu-central-1
第三个参数可用于访问另一个帐户(我确实更喜欢以前将角色切换到另一个帐户)。
使用awk脚本作为oneliner精简了该脚本的版本:
#!/bin/sh
set -ex
# Some variable initialisation with sane defaults
DRUN='--dry-run'
DO_DELETE=${1:-'no'}
REGION=${2:-'eu-west-1'}
ACCOUNTID=${3:-'self'}
# Get two temporary files
SNAP_FILE=$(mktemp)
IMAGE_FILE=$(mktemp)
# Get the snapshot list and the volume list
aws --region "$REGION" ec2 describe-snapshots --owner-ids "$ACCOUNTID" --query 'Snapshots[*].[SnapshotId]' --output text > "$SNAP_FILE"
aws --region "$REGION" ec2 describe-images --owners "$ACCOUNTID" --filters Name=state,Values=available --query 'Images[*].BlockDeviceMappings[*].Ebs.[SnapshotId]' --output text > "$IMAGE_FILE"
# Check if the outputed command should be dry-run (default) or not
if [ "$DO_DELETE" = "IAMSURE" ]
then
DRUN=''
fi
# count each snapshot id, decrease when a volume reference it, print delete command for those with no volumes
awk -v REGION="$REGION" -v DRUN="$DRUN" 'FNR==NR { snap[$1]++; next } { snap[$1]-- } END { for (s in snap) { if (snap[s] > 0) { cmd="aws --region " REGION " " DRUN " ec2 delete-snapshot --snapshot-id " s; print(cmd) } } }' "$SNAP_FILE" "$IMAGE_FILE"
# Clean up the temp files
rm "$SNAP_FILE" "$IMAGE_FILE"
我在Rodrigue Koffi(bonclay7)的GitHub上使用了以下脚本,并且效果很好。
https://github.com/bonclay7/aws-amicleaner
命令:
amicleaner --check-orphans
从文档博客文章中,它可以做更多的事情:
实际上,它的作用还不止这些,到目前为止,它允许:
- 删除图像列表和相关快照
- 映射AMI:
- 使用名字
- 使用标签
- 过滤AMI:
- 由运行实例使用
- 来自自动缩放组(启动配置),且所需容量设置为0
- 从自动缩放组分离的启动配置中
- 指定要保留的AMI数
- 清理孤立快照
- 一点报告
这是一个可以帮助您查找孤立快照的脚本
comm -23 <(echo $(ec2-describe-snapshots --region eu-west-1 | grep SNAPSHOT | awk '{print $2}' | sort | uniq) | tr ' ' '\n') <(echo $(ec2-describe-images --region eu-west-1 | grep BLOCKDEVICEMAPPING | awk '{print $3}' | sort | uniq) | tr ' ' '\n') | tr '\n' ' '
(从这里开始)
您也可以从serverfault查看本文
PS当然,您可以更改区域以反映您的
PPS这里是更新的代码:
comm -23 \
<(echo $(aws ec2 describe-snapshots --region eu-west-1 |awk '/SNAPSHOT/ {print $2}' | sort -u) | tr ' ' '\n') \
<(echo $(aws ec2 describe-images --region eu-west-1 | awk '/BLOCKDEVICEMAPPING/ {print $3}' | sort -u) | tr ' ' '\n') | tr '\n' ' '
示例样例代码的作用是:
echo $(aws ec2 describe-snapshots --region eu-west-1 | awk '/SNAPSHOT/ {print $2}' | sort -u) | tr ' ' '\n')
将快照列表发送到STDOUT。此结构:
<(...)
创建虚拟临时文件处理程序以使comm
命令从两个“文件”中读取并进行比较
这是Daniil Yaroslavtsev所要求的GitHub Gist代码片段。
它使用所有映像及其快照的列表,并将ID与所有快照ID的列表进行比较。剩下的就是孤儿了。该代码的工作原理与上述答案相同,但格式更好,可读性更高。
该代码利用了带有--query Snapshots[*].SnapshotId
选项的JMESPath
(如果已经在您的发行版中,那么您也可以使用jp命令行实用程序。格式将输出格式为text --output text
。这是指向 API参考和一些示例的链接。比长长的grep / awk / sort / uniq / tr管链更优雅。
Todd Walton的警告:不要误会使用不同查询语言来解析JSON文档的'jq'实用程序。
我编写了snapshots.py脚本,该脚本遍历所有快照(在已定义的区域列表中)并生成report.csv
。该文件包含有关所有快照引用的实例,AMI和卷的信息。
还有命令以交互方式删除悬空快照。