EC2からELBの接続・切り離しをする

#はじめに
この記事ではEC2（今回はlinux系）のサーバからロードバランサを接続したり切り離したりする手順のお話です。
冗長構成のサーバに対して、リリースのたびにAWSコンソールからアクセスするのが面倒くさい！と思い手順を調べました。
今回紹介する方法で、簡単に接続・切り離しが出来るようになりますが、
同時に**簡単に切り離せてミスを誘発**してしまうため、コマンドミスが無いようにシェル化したりして人が打たないように注意したほうが良いと思います。

#対象の確認
これから紹介するコマンドでは**ターゲットグループのARN**と、
接続・切り離しをしたいEC2サーバの**インスタンスID**と**ポート**が必要になります。

###ターゲットグループの確認
このあたりは文章では分かりにくいので画像を交えて説明します。
AWSのコンソールから EC2> ロードバランサー から対象のELBのリスナーを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348248/3f762d0b-417f-df76-dc52-99c47281d85c.png)

するとロードバランサに紐づくターゲットグループの画面に遷移できますので
ここでターゲットグループのARNを確認できます。
名前の横のアイコンでターゲットグループのARNをコピーできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348248/8be1ca97-4b46-3ec3-8701-1b7e302b3c8a.png)

###EC2のインスタンスIDの確認
次にターゲットグループに接続されているEC2のインスタンスIDを確認します。
先ほどターゲットグループを確認しましたが、同じ画面で対象のターゲットグループにチェックをいれ、
画面下に表示されるTargetタブに移動すると、現在そのターゲットグループに紐づいているEC2サーバのインスタンスIDと、
ポートが表示されています。こちらも後で使うので覚えてメモしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348248/8405c5b6-8591-0364-8cb0-09b804312bc5.png)


# ヘルスチェック
ここからが本題となります。
まずはELBの接続状況を確認するためのヘルスチェックコマンドから。

### ヘルスチェックコマンド
必要になるのはターゲットグループだけです。
このコマンドを打つことにより、指定したターゲットグループの接続状況を知ることが出来ます。

```
aws elbv2 describe-target-health --target-group-arn [ターゲットグループ]
```

### コマンド例

```
aws elbv2 describe-target-health --target-group-arn arn:aws:hogegehoge:ap-hogertheast-1:123456789:targetgroup/HOGEHOGEELB013-TG-01/1a2b3c4d5d
​
```
### 実行結果
実行すると以下のように表示されます。
複数接続されている場合はTagetやTargetHealthが出力されます。

```
{
    "TargetHealthDescriptions": [
        {
            "HealthCheckPort": "80",
            "Target": {
                "Id": "i-123456abcd",
                "Port": 80
            },
            "TargetHealth": {
                "State": "healthy"
            }
        }
    ]
}

```

今回の例では
Id: i-123456abcd の EC2サーバが、Port:80で接続されており、状態はhealthy（接続されている状態）となります。
複数接続されている場合はTagetやTargetHealthが出力されます。

よく見るStateは

* healthy：ヘルスチェックOK。ようは接続されてる状態
* draining：切り離し中。未処理のリクエストが終わるまで待つ待機状態。デフォルト300秒
* inital：EC2サーバをロードバランサに登録中。大体すぐ終わりますが、まだ繋がってないので待ちましょう

#切り離し
ようやくメインの話の切り離しコマンドです。

### 切り離しコマンド
対象のターゲットグループと、切り離したいEC2のインスタンスIDとポートを指定します。

```
aws elbv2 deregister-targets --target-group-arn [ターゲットグループ] --targets Id=[EC2のID],Port=[ポート]
```

### コマンド例

```
aws elbv2 deregister-targets --target-group-arn arn:aws:hogegehoge:ap-hogertheast-1:123456789:targetgroup/HOGEHOGEELB013-TG-01/1a2b3c4d5d --targets Id=i-123456abcd,Port=80
```

### 実行結果
うまく行くと特に何も表示されないので、コマンド直後にヘルスチェックを実行すると以下のように表示されます。

```
aws elbv2 describe-target-health --target-group-arn arn:aws:hogegehoge:ap-hogertheast-1:123456789:targetgroup/HOGEHOGEELB013-TG-01/1a2b3c4d5d
{
    "TargetHealthDescriptions": [
        {
            "HealthCheckPort": "80",
            "Target": {
                "Id": "i-123456abcd",
                "Port": 80
            },
            "TargetHealth": {
                "State": "draining",
                "Reason": "Target.DeregistrationInProgress",
                "Description": "Target deregistration is in progress"
            }
        }
    ]
}
```

この時TargetHealthのStateがdrainingになっていることが分かります。
ヘルスチェックの所で説明した通り、リクエストを受けな付けなくなり、既定の時間まで待ってから切り離しが行われます。
このまま待つと（デフォルト300秒）ヘルスチェックを実行した際にこのEC2が出力されなくなります。


# 接続


### 接続コマンド
やることはほとんど切り離しと同じです。
コマンド後半はほぼ一緒ですね。
対象のターゲットグループと、接続したいEC2のインスタンスIDとポートを指定します。

```
aws elbv2 register-targets --target-group-arn [ターゲットグループ] --targets Id=[EC2のID],Port=[ポート]
```

### コマンド例

```
aws elbv2 register-targets --target-group-arn arn:aws:hogegehoge:ap-hogertheast-1:123456789:targetgroup/HOGEHOGEELB013-TG-01/1a2b3c4d5d --targets Id=i-123456abcd,Port=80
```

### 実行結果
切り離し同様、うまく行くと特に何も表示されないので、コマンド直後にヘルスチェックを実行すると以下のように表示されます。

```

aws elbv2 describe-target-health --target-group-arn arn:aws:hogegehoge:ap-hogertheast-1:123456789:targetgroup/HOGEHOGEELB013-TG-01/1a2b3c4d5d
{
    "TargetHealthDescriptions": [
        {
            "HealthCheckPort": "80",
            "Target": {
                "Id": "i-123456abcd",
                "Port": 80
            },
            "TargetHealth": {
                "State": "initial",
                "Reason": "Elb.RegistrationInProgress",
                "Description": "Target registration is in progress"
            }
        }
    ]
}
```

こちらも実行しても何も出力されませんが、直後にヘルスチェックをするとStateがinitialになっていることが分かります。
接続準備中の状態なので、healthyになるまで待てば接続完了です。（数秒で終わる？）

このコマンドの良いところは、**draining中でも接続が出来る**ことです！
AWSのコンソールからだとdraining中に接続の登録が出来ません。
ですがコマンドならdraining中でも接続に出来るので、待たなくていいのが地味にうれしいところです。

以上となります。
AWSコンソール触りたくない人、drainigの待機時間にイライラする人は是非使ってみてください。