ALBのターゲットEC2がunhealthyになっちゃうのはどうして？

#### はじめに
ALBを学習している際にALBのターゲットであるEC2インスタンスのステータスがunhealthyとなり、EC2への通信のができないという問題に直面しました。
CloudFormationで作成したALB配下のEC2インスタンスのステータスはhealthyなのに対し、自分でポチポチ作成するとunhealthyとなってしまいます。
一番unhealthyなのは私の心だったのですが、無事解決することができましたので、備忘録を残しておきたいと思います。
もしもおかしな点や間違えている点ありましたら教えていただけると大変うれしいです。

#### 構成図
今回、ALBを設置する前のAWSの構成図が下図です。
[![Image from Gyazo](https://i.gyazo.com/985133679d897f513934a92e106d8959.png)](https://gyazo.com/985133679d897f513934a92e106d8959)
今回はALBを全てのPublic subnetに設置します。料金は変わリません。
そしてEC2インスタンスをPublic subnet Cに設置することとします。
このEC2インスタンスをALBのターゲットとして設定しています。今回EC2インスタンスは１つだけです。
[![Image from Gyazo](https://i.gyazo.com/93160c9c8ed2ae69d6d276ec81ef4fd4.png)](https://gyazo.com/93160c9c8ed2ae69d6d276ec81ef4fd4)
最終的に上図のような構成としました。

#### 解決したいこと
現状の問題点です。
ALBのターゲットのEC2インスタンスへのステータスがunhealtyになってしまっていることです。
![11fb714a396620dcfc832ead70eb4036.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1431393/f02c1119-295b-136f-e065-8e60b71d82be.png)
この状態をhealthy（正常）にすることが今回のゴールです。

### ALBとEC2インスタンスを設置
ALB及びEC2を設定するまでに具体的にどういう値を設定してきたのかを書きます。
今回は特に設置自体が目的ではないので、大切だと思われる部分をかいつまんでざっと書きます。
- EC2SecurityGroupの設定(ALB用セキュリティグループ)
  - インバウンドルールとしてhttp通信の80番ポート、https通信の443番ポートを開けます。
  - アウトバウンドルールは特に設定せずdefaultのフルオープンのままです。
[![Image from Gyazo](https://i.gyazo.com/968c06ca57cca8d290e72ae5c98149bc.png)](https://gyazo.com/968c06ca57cca8d290e72ae5c98149bc)

- ELBTargetGroupの作成
  - ALBよりも先にELBTargetGroupを作成します。このリソースを先に作成していないとALBを作ることができません。最終的に作成するEC2インスタンスをターゲットとして紐づけることになります。

- LoadBalancer（ALB）の作成
  - ListenerはHTTP:80とHTTPS:443を作成します。
  [![Image from Gyazo](https://i.gyazo.com/4b250feacc5b69fa8777147d646b8b0a.png)](https://gyazo.com/4b250feacc5b69fa8777147d646b8b0a)

- ListenerRuleの作成
  - リスナールールは写真のように設定しました。
![0fabf1393ccf46dc57ac888131ff1a5d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1431393/abc952b0-add4-f331-0eb2-f5d09267f579.png)


- Route53RecordSetIPv4
  - ALB用のAレコードを追加します。
　　　![7374025928af99010f2cb2271f269e3f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1431393/9c6b622f-012a-47d9-d7a3-57458b81848e.png)

- EC2SecurityGroup(EC2インスタンス用)
  - インバウンドルールとしてhttp通信の80番ポートのみ開けます。
  - アウトバウンドルールは特に設定せずdefaultのフルオープンのままです。
[![Image from Gyazo](https://i.gyazo.com/022dea73746d8305c25a2f4fca9ebdf5.png)](https://gyazo.com/022dea73746d8305c25a2f4fca9ebdf5)

- Instance（EC2インスタンス）を作成します。作成したEC2インスタンスはALBのターゲットに設定します。

#### 仮説・考えられる原因
今回の原因はEC2回りだろうという仮説がたちました。それはALBからEC2への接続に異常があるからです。
EC2をALBが認知できないということはEC2の設定等に原因がありそうです。
![2d4fe2d5fa415f47c9a94cde1213d0bd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1431393/22b0fdd3-5fff-93d3-b981-328eb696b357.png)
２つの仮説がたちました。
 - 通信がセキュリティグループを通過できていない　→ インバウンドルールの確認 
 - EC2での設定に問題がある　→ user data（dockerコンテナ起動の記載）の確認、EC2設定の誤り確認
 
セキュリティグループとEC2インスタンスの設定値について確認していくことにしました。

#### 解決策
EC2インスタンスにPublicIPアドレスを紐づけていないことが原因でした。
[![Image from Gyazo](https://i.gyazo.com/243a63b1b12c1c9928685407e192d109.png)](https://gyazo.com/243a63b1b12c1c9928685407e192d109)
現状私の作成している環境はPublic subnetのみ存在しています。
今回の場合はEC2インスタンスをPublic subnetに設置しています。
Public subnetはVPCの外部と直接通信を行うためにPublicIPアドレスを紐づけなければなりません。
よって、ALBがEC2インスタンスを認識できなかったようです。
[![Image from Gyazo](https://i.gyazo.com/e37791b5cf1027e9c552afd26103f9bb.png)](https://gyazo.com/e37791b5cf1027e9c552afd26103f9bb)
EC2インスタンスをPublic subnetに置く場合はこの値を有効にしてPublicIPアドレスを紐づけます。
[![Image from Gyazo](https://i.gyazo.com/e2e210c9575a6505ce8ca81ab730879f.png)](https://gyazo.com/e2e210c9575a6505ce8ca81ab730879f)
PublicIPアドレスを紐づけることで無事にhealthyになりました。
私の心も無事にhealthyになりました。

#### おわりに・参考
実務経験の中では、本当にALBという言葉がよく出てくるのを実感します。
特に本番環境デプロイの時などはよく耳にします。
最初は何を話しているのかがわからないことが多かったですが、最近AWSの学習を進める中で少しずつ話の内容についていけるようになっています。
AWSについてはルビコンさん https://twitter.com/RubiconLink
から学んでいます。ルビコン塾（ルビコンさんの講座）は予習がハードですがむちゃ学べます。私も4月から学び始め。現場でのAWS関連の会話はほとんどついていけるようになりました。
これからも心のhealthyは保ちつつ、しっかりと学習を継続していきたいと思います。

#### 参考
ルビコン塾教材