AWSリージョン毎のAMIの動的に変更対応について

# 概要
東京リージョンで構築している環境を別リージョンでセットアップしようとした際にAMIインスタンスのタイプがそのリージョンに対応していないことでセットアップできないことが発生します。
本記事では、大阪リージョンと比較していきます。

大阪リージョンもフルリージョン対応されましたがインスタンスタイプはまだまだ東京リージョンと同程度には揃っていないです。
AWSのリージョンに対応してるインスタンスは下記を参照すると確認できます。

https://aws.amazon.com/jp/ec2/pricing/on-demand/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1985649/8531e51d-15c8-ae66-e1d1-5cfb4930af2b.png"  width=500 height=200rem ><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1985649/af0507bc-e22a-cb41-f05a-ba49cbab05cd.png"  width=500 height=200rem>

東京リージョンで構築していた環境を大阪リージョンでも利用したい場合、対応していないインスタンスタイプがあるため、構築できないことがあります。そこで、本記事では大阪リージョンで対応しているインスタンスタイプを確認する方法について説明します。これにより、異なるリージョンでも同じ環境を構築できるようになり、BCP対応等で役立てることができます。


## 各リージョンで対応しているインスタンスタイプの確認方法

以下のコマンドで、対象のリージョンに対応しているインスタンスタイプを確認できます。

- 東京リージョン

```
 aws ec2 describe-instance-type-offerings --region ap-northeast-1 --output json
```

```json
{
    "InstanceTypeOfferings": [
        {
            "InstanceType": "m5.4xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-1"
        },
        {
            "InstanceType": "r5d.4xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-1"
        },
        {
            "InstanceType": "c6a.4xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-1"
        },
        {
            "InstanceType": "m5zn.large",
            "LocationType": "region",
            "Location": "ap-northeast-1"
        },
        {
            "InstanceType": "d3.4xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-1"
        },
        :
        :

```

- 大阪リージョン
```
aws ec2 describe-instance-type-offerings --region ap-northeast-3 --output json
```

```json
{
    "InstanceTypeOfferings": [
        {
            "InstanceType": "r6g.8xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-3"
        },
        {
            "InstanceType": "r4.16xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-3"
        },
        {
            "InstanceType": "i3en.metal",
            "LocationType": "region",
            "Location": "ap-northeast-3"
        },
        {
            "InstanceType": "c4.xlarge",
            "LocationType": "region",
            "Location": "ap-northeast-3"
        },
        {
            "InstanceType": "c5.metal",
            "LocationType": "region",
            "Location": "ap-northeast-3"
        },
        {
            "InstanceType": "c6gn.medium",
            "LocationType": "region",
            "Location": "ap-northeast-3"
        },
        :
        :
```

## インスタンスタイプを変更する

```Python

OSAKA_REGION_INSTANCE_TYPE_CANDIDATE = {
    "m5a.large" : ["m5.large", "m5.xlarge"],
    "r5a.large" : ["r5.large", "r5.xlarge"]
}

```
東京リージョンで利用されるインスタンスタイプをKeyに大阪リージョンで利用するインスタンスタイプの候補をリストでvalueに指定します。
例えば、`m5a.large`が東京リージョンで利用されていた場合、`m5.large`か`m5.xlarge`を候補に指定することができます。


```Python

def get_instance_type_candidate(instance_type, region):
    if region == "ap-northeast-1":
        return instance_type
    elif region == "ap-northeast-3":
        if instance_type in OSAKA_REGION_INSTANCE_TYPE_CANDIDATE:
            return OSAKA_REGION_INSTANCE_TYPE_CANDIDATE[instance_type]
        else:
            return None

```

このような場合、get_instance_type_candidate関数を作成して、引数として渡されたインスタンスタイプとリージョンを元に、大阪リージョンで利用するインスタンスタイプの候補を返すように実装することができます。


```Python
def launch_instance(client, instance_type, region):
    if region == "ap-northeast-1":
        # 東京リージョンの場合はそのままインスタンスを作成する
        response = client.run_instances(
            ImageId='ami-0123456789',
            InstanceType=instance_type,
            MinCount=1,
            MaxCount=1
        )
    elif region == "ap-northeast-3":
        # 大阪リージョンの場合は、インスタンスタイプを変更してからインスタンスを作成する
        instance_type_candidate = get_instance_type_candidate(instance_type, region)
        if instance_type_candidate is None:
            raise Exception("Unsupported instance type")
        response = client.run_instances(
            ImageId='ami-0123456789',
            InstanceType=instance_type_candidate,
            MinCount=1,
            MaxCount=1
        )
    return response

```

## まとめ
インスタンスタイプはリージョン毎に対応しているものが異なっています。
そのため、同様の環境を別リージョンに立てたいときには注意が必要です。
特に新しいインスタンスタイプはリージョンごとに同じタイミングでリリースは実施されません。
環境に合わせて動的に対応できるようにしておくことでリージョン毎に最適化できます。

# Apendix

## AZ毎のインスタンスタイプの確認

```
aws ec2 describe-instance-type-offerings --location-type availability-zone --region ap-northeast-1 --output json
```

各リージョンのAZ毎にも対応インスタンスタイプが確認できるのでよりAZ毎の対応の確認が必要な場合にはこちらを利用ください。