diff options
Diffstat (limited to 'scrub-old-amis.py.in')
-rw-r--r-- | scrub-old-amis.py.in | 72 |
1 files changed, 0 insertions, 72 deletions
diff --git a/scrub-old-amis.py.in b/scrub-old-amis.py.in deleted file mode 100644 index 34d7be3..0000000 --- a/scrub-old-amis.py.in +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | @PYTHON@ | ||
2 | |||
3 | import re | ||
4 | import yaml | ||
5 | import boto3 | ||
6 | |||
7 | |||
8 | # All Alpine AMIs should match this regex if they're valid | ||
9 | AMI_RE = re.compile("^Alpine-(\d+\.\d+)(?:-r(\d+))?-Hardened-EC2") | ||
10 | |||
11 | |||
12 | # Load current AMI version from config | ||
13 | with open("alpine-ami.yaml") as fp: | ||
14 | ami_cfg = yaml.full_load(fp)["variables"] | ||
15 | current = (float(ami_cfg["alpine_release"]), int(ami_cfg["ami_release"])) | ||
16 | |||
17 | |||
18 | # Fetch all matching AMIs | ||
19 | amis = [] | ||
20 | |||
21 | for region in boto3.session.Session().get_available_regions("ec2"): | ||
22 | ec2 = boto3.client("ec2", region_name=region) | ||
23 | |||
24 | for image in ec2.describe_images(Owners=["self"])["Images"]: | ||
25 | match = AMI_RE.match(image["Name"]) | ||
26 | if not match: | ||
27 | continue | ||
28 | |||
29 | os_rel, ami_rel = match.groups() | ||
30 | amis.append(( | ||
31 | region, image["ImageId"], | ||
32 | image["BlockDeviceMappings"][0]["Ebs"]["SnapshotId"], | ||
33 | float(os_rel), int(ami_rel) if ami_rel else 0)) | ||
34 | |||
35 | |||
36 | # Determine the set to discard based region and version | ||
37 | ok_regions = set() | ||
38 | discards = [] | ||
39 | |||
40 | # Cluster candidates by region/version pair, newest in a region first. | ||
41 | # This should result in the first match for a region always being the newest | ||
42 | # AMI for that region and all subsequent matches in the region being old. | ||
43 | # Even so we must keep track of regions with current images on the off-chance | ||
44 | # that a region only has old images. In that case we want to preserve the old | ||
45 | # images till we can publish new ones manually so users can still launch | ||
46 | # Alpine systems without interruption. | ||
47 | candidates = sorted(amis, key=lambda i: (i[0], (i[1], i[3])), reverse=True) | ||
48 | |||
49 | for ami in candidates: | ||
50 | (region, ami, snapshot), version = ami[:3], ami[3:] | ||
51 | |||
52 | if version > current: | ||
53 | print("{} has AMI '{}' newer than current".format(region, ami)) | ||
54 | continue | ||
55 | elif version == current: | ||
56 | ok_regions.add(region) | ||
57 | continue | ||
58 | elif version < current and region in ok_regions: | ||
59 | discards.append((region, ami, snapshot)) | ||
60 | else: | ||
61 | print("Not discarding old image in {}".format(region)) | ||
62 | continue | ||
63 | |||
64 | |||
65 | # Scrub the old ones | ||
66 | for region, image, snapshot in discards: | ||
67 | print("Removing image '{}', snapshot '{}' in {}".format( | ||
68 | image, snapshot, region)) | ||
69 | |||
70 | ec2 = boto3.client("ec2", region_name=region) | ||
71 | ec2.deregister_image(ImageId=image) | ||
72 | ec2.delete_snapshot(SnapshotId=snapshot) | ||