From 52fbeb09019836edbc4938129c9022c57dfb2ec4 Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Sun, 12 Nov 2017 23:55:09 +0000 Subject: Add ECS AMI mapper --- .gitignore | 1 + make_ecs_ami_yaml.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 .gitignore create mode 100755 make_ecs_ami_yaml.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34422ef --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.py3 diff --git a/make_ecs_ami_yaml.py b/make_ecs_ami_yaml.py new file mode 100755 index 0000000..dda23da --- /dev/null +++ b/make_ecs_ami_yaml.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# +# Create a YAML mapping that is sutible for use in a CloudFormation template of +# the current ECS AMIs based on those published in the documentation. The +# script attempts to be as fault-tolerant as possible while still producing +# sane data. +# +# Assumptions: +# The script looks for a table where the first row (td) contains a set of +# headers (th), one of which has the text 'AMI ID' and the other of which is +# 'Region'. Given these it will extract the region/ami-id pairs. +# + +import re +import yaml +import requests +from bs4 import BeautifulSoup + +AMI_URL = ("https://docs.aws.amazon.com/AmazonECS/latest/" + "developerguide/ecs-optimized_AMI.html") + +AMI_RE = re.compile("^ami-[0-9a-f]+$") + +soup = BeautifulSoup(requests.get(AMI_URL).text, "html.parser") + +# Find the AMI table and column indicies +ami_table, id_index, region_index = None, None, None +for table in soup.find_all("table"): + # Only want header rows for identification + ths = table.tr.find_all('th') + if len(ths) < 2: + continue + + # Pick out the column mappings and hold onto their indicies + for i, th in enumerate(ths): + if th.text.lower() == "region": + region_index = i + + if th.text.lower() == "ami id": + ami_table = table + id_index = i + + # Indicies may be zero + if ami_table and region_index != None and id_index != None: + break + +# Indicies may be zero +if ami_table == None or id_index == None or region_index == None: + raise Exception("No AMI table found") + +# Build the AMI map +ami_map = {} +for row in ami_table.find_all("tr"): + # Must not be a header (th) row + tds = row.find_all("td") + if len(tds) < max(id_index, region_index): + continue + + region = tds[region_index].text + ami_id = tds[id_index].text + + # Sanity check the AMI ID in-case we mis-identified a row + if not AMI_RE.match(ami_id): + continue + + ami_map[region] = {"AMI": ami_id} + +# Validate that there at least enough AMIs (min 4 because there are currently 4 +# big US regions) +if len(ami_map) < 4: + raise Exception("Not enough AMIs found") + +# Output AMI map as YAML +print(yaml.dump({"ECSRegionImages": ami_map}, + default_flow_style=False, explicit_start=True)) -- cgit v1.2.3