AWS CLI Windows 每日 EBS 快照批处理

AWS CLI Windows Batch for daily EBS snapshot

TL;TR

aws describe-snapshots return 快照列表是否从最新到最旧排序?

详情:

我想用 AWS CLI 为 Windows 创建每日 EBS 快照。

我的脚本执行此操作:

  1. 为特定卷创建快照;
  2. 标记快照;
  3. 仅存储最大数量的具有相同标签的快照并删除其他。

问题是第3点。 当我获得快照列表时,我需要将列表从最旧到最新排序并删除最旧的快照。

我找到的解决方案很简单,我使用相同标签的快照列表:

aws ec2 describe-snapshots --region %AWS_REGION% --output=text --filters "Name=volume-id,Values=%AWS_VOLUME_ID%" "Name=tag:CreatedBy,Values=%TAGVALUE%"  --query Snapshots[].SnapshotId>%OUTSNAPSHOTS%

现在,假设列表是从最新到最旧的快照排序,使用 sort /r %OUTSNAPSHOTS% 以相反的顺序(从最旧到最新)循环列表,使用 skip=%AWS_MAX_BACKUPS% 跳过一些,并删除快照:

for /f "tokens=2 skip=%AWS_MAX_BACKUPS%" %%s in ('sort /r %OUTSNAPSHOTS%') do (
    aws ec2 delete-snapshot --region %AWS_REGION% --snapshot-id %%s
)

我的假设正确吗?是 describe-snapshots return 快照列表,从新到旧排序?

完整代码:

@echo OFF

:: Configuration Begin
SET AWS_BACKUP_NAME=Foo
SET AWS_MAX_BACKUPS=5
SET AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SET AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SET AWS_REGION=eu-west-1
SET AWS_VOLUME_ID=id-XXXXXXXXXXXXXX
:: Configuration End

:: Current path
SET CURRPATH=%cd%\

:: Get the current date/time according to os
set X=
for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x

:: Set date parts
set DATE_YEAR=%X:~0,4%
set DATE_MONTH=%X:~4,2%
set DATE_DAY=%X:~6,2%
set DATE_HOUR=%X:~8,2%
set DATE_MINUTE=%X:~10,2%
set DATE_SECOND=%X:~12,2%
set DATE_FRACTIONS=%X:~15,6%
set DATE_OFFSET=%X:~21,4%

:: Set the snapshot description with AWS_BACKUP_NAME and current date/time
set SNAPSHOT_DESCRIPTION=%AWS_BACKUP_NAME%-Backup-%DATE_YEAR%-%DATE_MONTH%-%DATE_DAY%_%DATE_HOUR%-%DATE_MINUTE%-%DATE_SECOND%-%DATE_FRACTIONS%

:: Set a file for the aws-cli output
set OUTCREATESNAPSHOT="%CURRPATH%%SNAPSHOT_DESCRIPTION%.txt"

:: 1. Create the snapshot
aws ec2 create-snapshot --region %AWS_REGION% --output=text --description %SNAPSHOT_DESCRIPTION% --volume-id %AWS_VOLUME_ID% --query SnapshotId>%OUTCREATESNAPSHOT%

:: Get the snapshot id from output file
set /p SNAPSHOTID=<%OUTCREATESNAPSHOT%

:: Set the snapshot with a tag
set TAGVALUE=AutomatedBackup%AWS_BACKUP_NAME%

:: 2. Add the tag on the snapshot
aws ec2 create-tags --region %AWS_REGION% --resource %SNAPSHOTID% --tags Key=CreatedBy,Value=%TAGVALUE%

:: Set a file for the aws-cli output
set OUTSNAPSHOTS="%CURRPATH%%AWS_VOLUME_ID%_SNAPSHOTS.txt"

:: Get the snapshots with the current tag
aws ec2 describe-snapshots --region %AWS_REGION% --output=text --filters "Name=volume-id,Values=%AWS_VOLUME_ID%" "Name=tag:CreatedBy,Values=%TAGVALUE%"  --query Snapshots[].SnapshotId>%OUTSNAPSHOTS%

:: 3. Loop on the reverses list but skip the first AWS_MAX_BACKUPS and delete the others
for /f "tokens=2 skip=%AWS_MAX_BACKUPS%" %%s in ('sort /r %OUTSNAPSHOTS%') do (
    aws ec2 delete-snapshot --region %AWS_REGION% --snapshot-id %%s
)

您无法保证快照会按日期排序。

您可以通过在命令中添加 jq 库来实现

aws ec2 describe-snapshots --region %AWS_REGION% \
      --filters "Name=volume-id,Values=%AWS_VOLUME_ID%" "Name=tag:CreatedBy,Values=%TAGVALUE%" \
| jq -r '.Snapshots | sort_by(.StartTime)[] | .SnapshotId' > %OUTSNAPSHOTS%

我删除了查询参数和文本输出,因为我只是将整个 JSon 作为 jq 参数推送。 jq 将按日期过滤和排序,将获取 SnapshotId 值并将其作为文本推送到脚本其余部分的输入。

列表将按最新快照排在列表末尾的顺序排列,您可以确定它将始终如此。