如何清理孤立的AWS EC2快照?


22

我们最终获得了删除了AMI的大量AWS EC2快照,但是这些快照被遗弃了。我想要一种非手动的方式来识别和删除这些孤儿,以节省我们的金钱和空间。

理想情况下,我在考虑使用CLIbash脚本,但是我的AWS-fu很弱。我以为以前有人这样做过,但是我找不到真正有效的脚本。

在最佳情况下,这也将检查体积并清理体积,但这可能更适合第二个问题。


我在python上的版本。如何使用和github链接
E.Big

Answers:


13

在很大程度上受已经在其他答案中链接的博客文章和要旨的启发,这是我对问题的看法。

我确实使用了一些复杂的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"

太棒了!除了“跟随”(IMO应该是“跟随”)之外,我认为此答案应被视为高质量帖子的样本。免责声明(其中SE网站上某人使用的任何内容都带有“自担风险”),其中似乎唯一有点多余。我只能想到您可能需要添加的另外一项改进:指示您是否测试了该脚本,如果可以,则如何总结其测试结果(例如“按设计工作”?)。显然,如果您已经使用过它,那就更好了。
Pierre.Vriens

@pierre今天早上写了它,经过了部分测试,可能会在今天下午进入我们的渠道。尽管我同意“按原样提供”的总体思路,但是删除“备份”的风险很高,我觉得我应该强调一下更。
Tensibai

嗯,所以我们可以帮助您启动针对这些DevOps需求的免费代码编写服务(附带一些免责声明字符串)...有趣!我建议稍后(时间合适时)添加一个小更新(最后),例如“ 我的脚本今天下午进入了我们的管道 ”。
Pierre.Vriens

@ Pierre.Vriens我说过,可能不能保证,也可能会在下周或更晚;)
Tensibai

1
完美,谢谢编辑!完全按预期工作。
亚历克斯(Alex)

5

我在Rodrigue Koffi(bonclay7)的GitHub上使用了以下脚本,并且效果很好。

https://github.com/bonclay7/aws-amicleaner

命令:

amicleaner --check-orphans

从文档博客文章中,它可以做更多的事情:

实际上,它的作用还不止这些,到目前为止,它允许:

  • 删除图像列表和相关快照
  • 映射AMI:
    • 使用名字
    • 使用标签
  • 过滤AMI:
    • 由运行实例使用
    • 来自自动缩放组(启动配置),且所需容量设置为0
    • 从自动缩放组分离的启动配置中
  • 指定要保留的AMI数
  • 清理孤立快照
  • 一点报告

3

这是一个可以帮助您查找孤立快照的脚本

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命令从两个“文件”中读取并进行比较


你测试了吗?我找到了同一篇文章,但无法正常工作。如果可以的话,用户错误会终止,但是我担心根据文章的年龄可能会过时。
Alex

@Alex,可以检查它的明天
罗密欧尼诺夫

命令已更改,请使用aws ec2描述/删除
Tensibai

1
我确实找到了相同的来源,但是链接英雄awk sort和uniq使我的shell编码器感到难过,我明天将发布我的版本:)
Tensibai

1
对我来说很好,只是想向您提供一些(建设性的)反馈,让您知道,对于像您这样的专家来说,普通英语看起来很像普通中文,好吗?PS:而且听起来也不像佛兰德语...如果您想在完成后通知我,请给我多条评论(如果您想要我的最新反馈)。
Pierre.Vriens

2

是Daniil Yaroslavtsev所要求的GitHub Gist代码片段。

它使用所有映像及其快照的列表,并将ID与所有快照ID的列表进行比较。剩下的就是孤儿了。该代码的工作原理与上述答案相同,但格式更好,可读性更高。

该代码利用了带有--query Snapshots[*].SnapshotId选项的JMESPath (如果已经在您的发行版中,那么您也可以使用jp命令行实用程序。格式将输出格式为text --output text。这是指向 API参考和一些示例的链接。比长长的grep / awk / sort / uniq / tr管链更优雅。

Todd Walton的警告:不要误会使用不同查询语言来解析JSON文档的'jq'实用程序。


仅供参考,JQ命令行实用程序是一样的JSON查询语言什么的“AWS”命令使用。“ aws”命令使用JMESPath。
Todd Walton

感谢您指出这一点。我今天学到了一些新东西。
吉里·克劳达

0

我编写了snapshots.py脚本,该脚本遍历所有快照(在已定义的区域列表中)并生成report.csv。该文件包含有关所有快照引用的实例,AMI和卷的信息。

还有命令以交互方式删除悬空快照。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.