summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2017-11-12 23:55:09 +0000
committerMike Crute <mike@crute.us>2017-11-12 23:55:09 +0000
commit52fbeb09019836edbc4938129c9022c57dfb2ec4 (patch)
treeebd037d8f111f8a70bebb2233dab25588df7d08b
downloadaws-tools-52fbeb09019836edbc4938129c9022c57dfb2ec4.tar.bz2
aws-tools-52fbeb09019836edbc4938129c9022c57dfb2ec4.tar.xz
aws-tools-52fbeb09019836edbc4938129c9022c57dfb2ec4.zip
Add ECS AMI mapper
-rw-r--r--.gitignore1
-rwxr-xr-xmake_ecs_ami_yaml.py75
2 files changed, 76 insertions, 0 deletions
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 @@
1#!/usr/bin/env python3
2#
3# Create a YAML mapping that is sutible for use in a CloudFormation template of
4# the current ECS AMIs based on those published in the documentation. The
5# script attempts to be as fault-tolerant as possible while still producing
6# sane data.
7#
8# Assumptions:
9# The script looks for a table where the first row (td) contains a set of
10# headers (th), one of which has the text 'AMI ID' and the other of which is
11# 'Region'. Given these it will extract the region/ami-id pairs.
12#
13
14import re
15import yaml
16import requests
17from bs4 import BeautifulSoup
18
19AMI_URL = ("https://docs.aws.amazon.com/AmazonECS/latest/"
20 "developerguide/ecs-optimized_AMI.html")
21
22AMI_RE = re.compile("^ami-[0-9a-f]+$")
23
24soup = BeautifulSoup(requests.get(AMI_URL).text, "html.parser")
25
26# Find the AMI table and column indicies
27ami_table, id_index, region_index = None, None, None
28for table in soup.find_all("table"):
29 # Only want header rows for identification
30 ths = table.tr.find_all('th')
31 if len(ths) < 2:
32 continue
33
34 # Pick out the column mappings and hold onto their indicies
35 for i, th in enumerate(ths):
36 if th.text.lower() == "region":
37 region_index = i
38
39 if th.text.lower() == "ami id":
40 ami_table = table
41 id_index = i
42
43 # Indicies may be zero
44 if ami_table and region_index != None and id_index != None:
45 break
46
47# Indicies may be zero
48if ami_table == None or id_index == None or region_index == None:
49 raise Exception("No AMI table found")
50
51# Build the AMI map
52ami_map = {}
53for row in ami_table.find_all("tr"):
54 # Must not be a header (th) row
55 tds = row.find_all("td")
56 if len(tds) < max(id_index, region_index):
57 continue
58
59 region = tds[region_index].text
60 ami_id = tds[id_index].text
61
62 # Sanity check the AMI ID in-case we mis-identified a row
63 if not AMI_RE.match(ami_id):
64 continue
65
66 ami_map[region] = {"AMI": ami_id}
67
68# Validate that there at least enough AMIs (min 4 because there are currently 4
69# big US regions)
70if len(ami_map) < 4:
71 raise Exception("Not enough AMIs found")
72
73# Output AMI map as YAML
74print(yaml.dump({"ECSRegionImages": ami_map},
75 default_flow_style=False, explicit_start=True))