AWSのリージョン名一覧を作ってみた

WebスクレイピングしてAWSリージョン名の一覧を作ってみました。
2024.04.18

こんにちは。サービス開発室の武田です。

AWSの「リージョン名」といわれてピンと来るでしょうか?ap-northeast-1のことだったり、アジアパシフィック (東京)のことだったり微妙に場所によって指すものが変わります。

紛らわしいので、このエントリではap-northeast-1などは「リージョンコード」、アジアパシフィック (東京)などは「リージョン名」と呼ぶことにします。

さて「リージョンコードの一覧」は簡単に作成できますね。というか各リージョンで処理をしたいケースは頻出なので、むしろ「よくある操作」と言えるでしょう。たとえばAWS CLIであれば次のようなコマンドで一発です。

$ aws ec2 describe-regions --all-regions --query 'Regions[].[RegionName]' --output text
ap-south-2
ap-south-1
eu-south-1
eu-south-2
me-central-1
il-central-1
ca-central-1
eu-central-1
eu-central-2
us-west-1
us-west-2
af-south-1
eu-north-1
eu-west-3
eu-west-2
eu-west-1
ap-northeast-3
ap-northeast-2
me-south-1
ap-northeast-1
sa-east-1
ap-east-1
ca-west-1
ap-southeast-1
ap-southeast-2
ap-southeast-3
ap-southeast-4
us-east-1
us-east-2

それでは、「リージョン名の一覧」を作ってください、と言われるとどうですか?マネジメントコンソールにはその一覧があるわけですので、どうにかしてAPIで取得できないか、と考えた人は多いはずです。しかし残念ながら、そのようなAPIは執筆時点でないようです。

というわけで、なくても頑張って作ってみようというのがこのエントリの趣旨です。

一覧作ってみた

はい、できあがったのがこちらのJSONです。

{
  "ap-south-2": {
    "en_us": "Asia Pacific (Hyderabad)",
    "ja_jp": "アジアパシフィック (ハイデラバード)",
    "ko_kr": "아시아 태평양(하이데라바드)"
  },
  "ap-south-1": {
    "en_us": "Asia Pacific (Mumbai)",
    "ja_jp": "アジアパシフィック (ムンバイ)",
    "ko_kr": "아시아 태평양(뭄바이)"
  },
  "eu-south-1": {
    "en_us": "Europe (Milan)",
    "ja_jp": "欧州 (ミラノ)",
    "ko_kr": "유럽(밀라노)"
  },
  "eu-south-2": {
    "en_us": "Europe (Spain)",
    "ja_jp": "欧州 (スペイン)",
    "ko_kr": "유럽(스페인)"
  },
  "me-central-1": {
    "en_us": "Middle East (UAE)",
    "ja_jp": "中東 (アラブ首長国連邦)",
    "ko_kr": "중동(UAE)"
  },
  "il-central-1": {
    "en_us": "Israel (Tel Aviv)",
    "ja_jp": "イスラエル (テルアビブ)",
    "ko_kr": "이스라엘(텔아비브)"
  },
  "ca-central-1": {
    "en_us": "Canada (Central)",
    "ja_jp": "カナダ (中部)",
    "ko_kr": "캐나다(중부)"
  },
  "eu-central-1": {
    "en_us": "Europe (Frankfurt)",
    "ja_jp": "欧州 (フランクフルト)",
    "ko_kr": "유럽(프랑크푸르트)"
  },
  "eu-central-2": {
    "en_us": "Europe (Zurich)",
    "ja_jp": "欧州 (チューリッヒ)",
    "ko_kr": "유럽(취리히)"
  },
  "us-west-1": {
    "en_us": "US West (N. California)",
    "ja_jp": "米国西部 (北カリフォルニア)",
    "ko_kr": "미국 서부(캘리포니아 북부)"
  },
  "us-west-2": {
    "en_us": "US West (Oregon)",
    "ja_jp": "米国西部 (オレゴン)",
    "ko_kr": "미국 서부(오레곤)"
  },
  "af-south-1": {
    "en_us": "Africa (Cape Town)",
    "ja_jp": "アフリカ (ケープタウン)",
    "ko_kr": "아프리카(케이프타운)"
  },
  "eu-north-1": {
    "en_us": "Europe (Stockholm)",
    "ja_jp": "欧州 (ストックホルム)",
    "ko_kr": "유럽(스톡홀름)"
  },
  "eu-west-3": {
    "en_us": "Europe (Paris)",
    "ja_jp": "欧州 (パリ)",
    "ko_kr": "유럽(파리)"
  },
  "eu-west-2": {
    "en_us": "Europe (London)",
    "ja_jp": "欧州 (ロンドン)",
    "ko_kr": "유럽(런던)"
  },
  "eu-west-1": {
    "en_us": "Europe (Ireland)",
    "ja_jp": "欧州 (アイルランド)",
    "ko_kr": "유럽(아일랜드)"
  },
  "ap-northeast-3": {
    "en_us": "Asia Pacific (Osaka)",
    "ja_jp": "アジアパシフィック (大阪)",
    "ko_kr": "아시아 태평양(오사카)"
  },
  "ap-northeast-2": {
    "en_us": "Asia Pacific (Seoul)",
    "ja_jp": "アジアパシフィック (ソウル)",
    "ko_kr": "아시아 태평양(서울)"
  },
  "me-south-1": {
    "en_us": "Middle East (Bahrain)",
    "ja_jp": "中東 (バーレーン)",
    "ko_kr": "중동(바레인)"
  },
  "ap-northeast-1": {
    "en_us": "Asia Pacific (Tokyo)",
    "ja_jp": "アジアパシフィック (東京)",
    "ko_kr": "아시아 태평양(도쿄)"
  },
  "sa-east-1": {
    "en_us": "South America (São Paulo)",
    "ja_jp": "南米 (サンパウロ)",
    "ko_kr": "남아메리카(상파울루)"
  },
  "ap-east-1": {
    "en_us": "Asia Pacific (Hong Kong)",
    "ja_jp": "アジアパシフィック (香港)",
    "ko_kr": "아시아 태평양(홍콩)"
  },
  "ca-west-1": {
    "en_us": "Canada West (Calgary)",
    "ja_jp": "カナダ西部 (カルガリー)",
    "ko_kr": "캐나다 서부(캘거리)"
  },
  "ap-southeast-1": {
    "en_us": "Asia Pacific (Singapore)",
    "ja_jp": "アジアパシフィック (シンガポール)",
    "ko_kr": "아시아 태평양(싱가포르)"
  },
  "ap-southeast-2": {
    "en_us": "Asia Pacific (Sydney)",
    "ja_jp": "アジアパシフィック (シドニー)",
    "ko_kr": "아시아 태평양(시드니)"
  },
  "ap-southeast-3": {
    "en_us": "Asia Pacific (Jakarta)",
    "ja_jp": "アジアパシフィック (ジャカルタ)",
    "ko_kr": "아시아 태평양(자카르타)"
  },
  "ap-southeast-4": {
    "en_us": "Asia Pacific (Melbourne)",
    "ja_jp": "アジアパシフィック (メルボルン)",
    "ko_kr": "아시아 태평양(멜버른)"
  },
  "us-east-1": {
    "en_us": "US East (Virginia)",
    "ja_jp": "米国東部 (バージニア)",
    "ko_kr": "미국 동부(버지니아)"
  },
  "us-east-2": {
    "en_us": "US East (Ohio)",
    "ja_jp": "米国東部 (オハイオ)",
    "ko_kr": "미국 동부(오하이오)"
  }
}

一覧の作り方

先ほどの一覧を手作業で作るのは死んでしまいますので、簡単なスクリプトを書きました。まず情報源ですが、このページです。

いい感じにリージョンコードとリージョン名の一覧がありますね。で、ドキュメントの言語を変えれば、その言語でのリージョン名もあります。これをかき集めれば良さそうですね?つまりWebスクレイピングですね。

手元で実行したい場合はライブラリのインストール等しておいてください。

$ pip install boto3 requests beautifulsoup4

今回作ったスクリプトはこちら。

import boto3
import requests
from bs4 import BeautifulSoup
import json


OUTPUT_LANG = ["en_us", "ja_jp", "ko_kr"]

REGION_URL = {
    lang: f"https://docs.aws.amazon.com/{lang}/AWSEC2/latest/UserGuide/using-regions-availability-zones.html"
    for lang in OUTPUT_LANG
}


ec2 = boto3.client("ec2")

# { lang: { code: region_name } }
region_name_with_lang: dict[str, dict[str, str]] = {}

for lang, url in REGION_URL.items():
    response = requests.get(url)
    response.encoding = response.apparent_encoding
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    region_name_with_lang[lang] = {
        td[0]
        .text: td[1]
        .text.replace("(", " (")
        .replace(")", ")")  # e.g. ap-northeast-1: アジアパシフィック (東京)
        for td in (
            tr.find_all("td")
            for tr in (
                soup.find(attrs={"id": "concepts-available-regions"})
                .find_next("table")
                .find_all("tr")
            )
        )
        if len(td) > 0
    }

    # Crawl-delay: 5
    sleep(5)


# { code: { lang: region_name } }
region_name_with_code: dict[str, dict[str, str]] = {}

for code in (r["RegionName"] for r in ec2.describe_regions(AllRegions=True)["Regions"]):
    region_name_with_code[code] = {
        lang: region_name_with_lang[lang][code]  # e.g. ja_jp: アジアパシフィック (東京)
        for lang in region_name_with_lang.keys()
    }


print(json.dumps(region_name_with_code, ensure_ascii=False, indent=2))

OUTPUT_LANGに含めたい言語コードを追加すれば自動的にリージョン名が追加されます。

まとめ

リージョン名一覧を作りたい!という方はどうぞ。

あとHTMLの構造が変わると動かなくなりますので、もしそういう場合はご一報ください。