AWSで使っていないサブネットを削除・整理していたらElastic Beanstalkの環境作成ができなくなった話

# この記事について
タイトルの通り、「このサブネットの中で1つもインスタンス起動してないから影響ないやろ」とサブネットを削除した結果、Elastic Beanstalkの`eb create`コマンドが通らなくなりました。
原因と復旧させるまでの手順をまとめます。

# やらかす前の状況
ローカルで作ったアプリを、`eb init`→`eb create`コマンドでElastic Beanstalk環境にデプロイするのが目標でした。ちなみにサブネット削除前にテスト的に`eb create`を叩いたときには正しく環境作成されてました。

削除前のVPCの状態は以下の通りでした。

- デフォルトVPCを使用
- ap-northeastの3つのAZに一つずつサブネットが存在
- ap-northeast-1aには1つEC2インスタンスがあり・他にはなし
- ap-northeast-1aはパブリックサブネット


# やらかしとその結果
EC2インスタンスがなかったap-northeast-1c, ap-northeast-1dのサブネットを削除しました。
その結果、デプロイのロードバランス作成時に

```bash
yyyy-mm-dd hh:mm:ss    ERROR   Creating load balancer failed Reason: At least two subnets in two different Availability Zones must be specified (Service: AmazonElasticLoadBalancingV2; Status Code: 400; Error Code: ValidationError; Request ID: XXXX)
```
「AZが2つ以上にまたがってサブネットが2つないとロードバランサが作れません」と怒られる。

ここでデプロイに支障が出ると、インスタンスが立てられないまま環境作成が終了するので、Elastic Beanstalkの環境ステータスとしては`NO DATA`となります。

# 検証
## 1. ap-northeast-1cと1dに新たにパブリックサブネットをコンソールで作り直す
**結果：エラーが解消されず、同じ内容でまた出ます。**

ちゃんとエラー文通りに、複数AZにサブネットを用意したのに不思議ですね。

## 2. 1で作り直したサブネットの状態で、そもそもロードバランサ単独で作れるのかテスト
Elastic Beanstalkからではなく、EC2のコンソールからロードバランサ単独で作れるかどうかをテストしました。

**結果：作れる。**

ロードバランサ自体は作れるのに、Elastic Beanstalk経由だと作れないという謎な状況ということがわかりました。

# 原因
Elastic Beanstalkでは、**環境を作るVPCを指定しない場合、デフォルトVPCとデフォルトサブネットが自動的に使われます。**
ソース：[公式ドキュメント 新しい環境の作成ウィザード](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environments-create-wizard.html)

今回の場合、「使ってないからいいか」といって消したのがデフォルトサブネットでした。

また、デフォルトサブネットは**現状 AWS CLI、AWS SDK、または Amazon EC2 APIからでしか作成できない**ので、Webコンソールの方で新しく作り直したサブネットはデフォルト設定されずElastic Beanstalkでは使われないものになってしまいました。
ソース：[公式ドキュメント デフォルト VPC とデフォルトサブネット](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/default-vpc.html#create-default-subnet)

# 復旧
ap-northeast-1cとap-northeast-1dにデフォルトサブネットを作り直します。

## AWS CLIの用意
今回はCLIを利用することにしました。以下のリンクからCLIをインストールします。
[公式ドキュメント AWS コマンドラインインターフェイス](https://aws.amazon.com/jp/cli/)

その後、CLIの設定を行います。

```bash
$ aws configure

AWS Access Key ID [********************]: 
AWS Secret Access Key [*******************]: 
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

## CLIからデフォルトサブネットを作成
以下のコマンドを実行します。

```bash
$ aws ec2 create-default-subnet --availability-zone ap-northeast-1c

{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1c",
        "AvailableIpAddressCount": 4091,
        "CidrBlock": "[your-IPv4-CIDR]",
        "DefaultForAz": true,
        "MapPublicIpOnLaunch": true,
        "State": "available",
        "SubnetId": "[your-subnet-id]",
        "VpcId": "[your-vpc-id]",
        "OwnerId": "[your-account-id]",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "Tags": []
    }
}
```
ap-northeast-1cにデフォルトサブネットが作成されました。同様に1dの方も作成します。

この状態で`eb create`コマンドを叩くことで、正常に環境作成ができるようになりました。

# 結論
現状、デフォルトであろうがなかろうが、サブネット削除はカジュアルにできてしまいます。
サブネット削除の際は、AZのデフォルトサブネット指定されていないかどうかよく確認しよう！

# 参考文献
- [【Elastic Beanstalk Error】Creating load balancer failed Reason: At least two subnets in two different Availability Zones must be specified](https://www.yuulinux.tokyo/7734/)
- [VPC上のELBにsubnet が設定できない](http://yukieen.hatenablog.com/entry/20141216/1418741179)
- [Elastic Beanstalkのeb create時にCreating load balancer failed Reason At least two subnets in two different Availability Zones must be specified で怒られた時の対処法](https://moon.ryukyu/003120/)