Как очистить потерянные снимки AWS EC2?


22

В итоге мы получили достаточное количество снимков AWS EC2, в которых AMI был удален, но снимок оставлен гнить. Я хотел бы, чтобы не ручной способ выявления и удаления этих сирот сэкономил нам деньги и пространство.

В идеале я думаю, что bash-скрипт использует CLI , но мой AWS-fu слабый. Я предполагаю, что кто-то делал это раньше, но я не могу найти сценарий, который действительно работает.

В лучшем случае это также проверит тома и очистит их, но это может быть лучше для второго вопроса.


Моя версия на питоне. Как пользоваться и ссылка на
GitHub

Ответы:


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-скриптом в качестве единого участника:

#!/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"

Magnific! И кроме как из «следовать» (которое ИМО должно быть «следует»), я думаю, что этот ответ следует рассматривать как образец постов высокого качества. Единственная вещь, которая кажется немного избыточной, это отказ от ответственности (все, что вы используете от чего-то на сайте SE, сопровождается «используйте это на свой страх и риск»). Я могу думать только о 1 дополнительном улучшении, которое вы можете добавить: указание, если вы действительно тестировали этот скрипт, и если да, то как подвести итоги его тестирования (что-то вроде «работает как задумано»?). Очевидно, что если вы уже используете его сами, это еще лучше.
Pierre.Vriens

@pierre написал это сегодня утром, частично протестированный, вероятно, войдет в наш конвейер сегодня днем, и, хотя я согласен с общей идеей «предоставляется как есть», уровень риска удаления «резервной копии» высок, и я чувствую, что должен подчеркнуть это даже больше.
Тенсибай

Хм, поэтому мы можем привлечь вас к запуску бесплатного сервиса написания кода для такого рода потребностей DevOps (с некоторыми прикрепленными оговорками) ... интересно! Я предлагаю позже (когда настанет время) добавить небольшое обновление (в конце), например « мой сценарий вошел в наш конвейер сегодня днем ».
Pierre.Vriens

@ Pierre.Vriens Я сказал, вероятно, не гарантия, может быть на следующей неделе или позже;)
Tensibai

1
Отлично, спасибо за редактирование! Работает точно так, как задумано.
Алекс

5

Я использовал следующий скрипт на GitHub Родрига Коффи (bonclay7), и он работает довольно хорошо.

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команда читала из двух «файлов» и сравнивала их


Вы проверяли это? Я нашел ту же статью, но не могу заставить ее работать. Если вы можете, ошибка пользователя на моем конце, но я боюсь, что это может быть устаревшим в зависимости от возраста статьи.
Алекс


Команда см. Изменилась, используйте aws ec2 описать / удалить
Tensibai

1
Я нашел тот же источник, но цепочка hero awk sort и uniq огорчает мою сторону программиста оболочки, завтра я
опубликую

1
Прекрасно для меня, просто хотел предоставить вам (конструктивную) обратную связь, чтобы вы знали, что то, что, вероятно, похоже на обычный английский для эксперта (как и вы), выглядит для меня почти как китайский, хорошо? PS: и это не звучит по-фламандски ... Оставьте мне дополнительный комментарий, если вы хотите уведомить меня после того, как вы закончите (если вы хотите, чтобы мой обновленный отзыв потом).
Pierre.Vriens

2

Вот фрагмент кода GitHub Gist именно того, о чем вы просите Даниила Ярославцева.

Он использует список всех изображений и их снимков и сравнивает идентификаторы со списком всех идентификаторов снимков. Все, что осталось - осиротевшие. Код работает по тому же принципу, что и ответ выше, но лучше отформатирован и немного более читабелен.

Код использует JMESPath с --query Snapshots[*].SnapshotIdопцией (вы также можете использовать утилиту командной строки jp для этого, если она уже есть в вашем дистрибутиве. Форматирует вывод как текст --output text. Вот ссылка на API-ссылку и несколько примеров. Это немного более элегантный, чем длинная цепочка труб grep / awk / sort / uniq / tr.

Предупреждение от Тодда Уолтона : не путайте с утилитой jq, которая использует другой язык запросов для анализа документов json.


Просто FYI, утилита командной строки jq - это не тот же язык запросов JSON, который использует команда «aws». Команда "aws" использует JMESPath.
Тодд Уолтон

Спасибо за указание на это. Я узнал что-то новое сегодня.
Иржи Клауда

0

Я написал скрипт snapshots.py, который перебирает все снимки (в определенном списке регионов) и генерирует report.csv. Этот файл содержит информацию об экземпляре, AMI и томе, на который ссылаются все снимки.

Существует также команда для интерактивного удаления висячих снимков.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.