idcfcloud-cliからILBを操作してみる（ILBでオートスケールできるかな）

##はじめに
idcfcloud-cliで、ILBの操作を試してみます。
最終的に、リソース監視と組み合わたオートスケールのための試行として、ILB配下のサーバ追加／削除用のシェルスクリプトを作ります。

**前提条件**
Ruby 2.2.7以降

**環境**
Amazon Linux AMI release 2017.03

※ 環境の違う方は、本家のマニュアルとブログを参考にインストールを進めてください。
[idcfcloud-cliについて｜技術ドキュメント/API](https://www.idcf.jp/help/cloud/docs/cli.html)
[idcfcloud-cliをリリース！｜IDCF テックブログ](http://blog.idcf.jp/entry/idcfcloud-cli-1)
##インストール
###Ruby
idcfcloud-cliは、前提条件としてRuby 2.2.7以降がインストールされた環境が必要です。
既存環境のRubyが2.0だったため、2.3をインストールします。
Amazon Linuxには標準でalternatives コマンドが入っているので、Rubyのバージョンを切り替えて使用します。


切替可能なバージョンのリストを表示

```
# update-alternatives --display ruby
```

rubyインストール

```
# yum install -y ruby23 ruby23-devel
```

Rubyの選択バージョンを切り替え

```
# update-alternatives --set ruby /usr/bin/ruby2.3
```

下記で対話的に切り替えることもできます。

```
# alternatives --config ruby
```

alternativesの参照先が切り替わったかどうか確認。

```
# update-alternatives --display ruby
ruby - status is manual.
 link currently points to /usr/bin/ruby2.3
```
Rubyのバージョンが2.3になっていることを確認。

```
# ruby --version
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux-gnu]
```
###Gem
idcfcloud-cliはRubyGemsからインストールするので、準備しておきます。
次のコマンドでGemパッケージのインストールからアップデートまでを行う事ができます。

```
# gem update --system
# gem --version
2.6.13
```

###idcfcloud-cli
####インストール
idcfcloud-cliをインストールしていきます。
インストールフォルダ配下に設定ファイルが出来るため、
下記コードでは明示的にユーザー領域にインストールしています。

```
$ gem install --user-install idcfcloud
Fetching: idcfcloud-0.1.4.gem (100%)
Please carry out 'init' command.
Successfully installed idcfcloud-0.1.4
Parsing documentation for idcfcloud-0.1.4
Installing ri documentation for idcfcloud-0.1.4
Done installing documentation for idcfcloud after 0 seconds
1 gem installed
```
以下のコマンドで、どこにインストールされたか確認できます。

```
$ gem contents idcfcloud  | grep bin
/home/qg/.gem/ruby/2.3/gems/idcfcloud-0.1.4/bin/idcfcloud
```

####初期設定
自分のIDCFクラウドのAPI情報を確認し初期設定として入力していきます。

```
$ idcfcloud init
default:api_key[NONE] :
【API Keyを貼りつけてください】
default:secret_key[NONE] :
【Secret Keyを貼りつけてください】
default:region[NONE] :
【デフォルト指定するリージョンを記述ください（jp-east/jp-east-2/jp-west）】
```

以下はTabキーによる入力補完を行うための設定です。便利機能ですね。

```
$ vi ~/.bash_profile
source $HOME/.gem/ruby/2.3/gems/idcfcloud-0.1.4/output/complement.bash
```
##実行

###list_loadbalancers：ILBの情報を取得する

WebコンソールからILBを作成して、idcfcloud-cli から情報を取得してみましょう。

IDCFクラウド上に、Webサーバを2台用意しておき、
そのうちの1台をILBの配下に設置します。

![Screenshot-2017-10-18 IDCFクラウド - ilb create.png](https://qiita-image-store.s3.amazonaws.com/0/105824/8ab3410d-cc52-f9d3-dd04-7fb7a25f477d.png)

このILBの情報を cli から情報を取得してみます。JSON形式でいーっぱい情報が返ってきますね。
このデータのうち、ILBのIDとconfigのIDは、
サーバ追加や削除等、他のコマンド実行時にパラメータとして使用します。

```
$ idcfcloud ilb list_loadbalancers
{
  "status": 200,
  "message": "",
  "data": [
    {
      "id": "5ea2a04b-3419-43ea-a9ee-bdbba9abad95",
      "account_id": "71000007335",
      "network_id": "34a1ea86-9ef1-485d-9a45-bd509f0e8d33",
      "network_name": "lux-network1",
      "network": {
        "id": "34a1ea86-9ef1-485d-9a45-bd509f0e8d33",
        "name": "lux-network1",
        "account_id": "71000007335",
        "networkcidr": "10.32.0.0/22",
        "domainid": "35874605-3e5a-4381-9efa-a21d1218b57b",
        "domain": "71000007335",
        "gateway": "10.32.0.1",
        "networkoffering_id": "7c1bbf37-5551-4fdb-9e7f-d799c64e3b6e",
        "networkoffering_name": "DefaultIsolatedNetworkOffering",
        "state": "Implemented",
        "traffic_type": "Guest",
        "related": "34a1ea86-9ef1-485d-9a45-bd509f0e8d33",
        "zone_id": "95c8746d-57b3-421f-9375-34bea93e2a3d",
        "zone_name": "lux"
      },
      "configs": [
        {
          "id": "17a3c43b-ba12-474e-be9d-4aa1afb314b7",
          "port": 80,
          "loadbalancer_id": "5ea2a04b-3419-43ea-a9ee-bdbba9abad95",
          "algorithm": "roundrobin",
          "healthcheck": {
            "check_interval": 30,
            "timeout": 5,
            "type": "http",
            "unhealthy_threshold": 2,
            "healthy_threshold": 10,
            "path": "/"
          },
          "frontend_protocol": "http",
          "backend_protocol": "http",
          "connection_timeout": 60,
          "created_at": "2017-10-18T16:39:28.000+09:00",
          "updated_at": "2017-10-18T16:39:50.000+09:00",
          "servers": [
            {
              "id": "20344366-d7c2-4e96-8bbc-ba2bbfcefe02",
              "loadbalancer_id": "5ea2a04b-3419-43ea-a9ee-bdbba9abad95",
              "config_id": "17a3c43b-ba12-474e-be9d-4aa1afb314b7",
              "ipaddress": "10.32.0.161",
              "port": 80,
              "created_at": "2017-10-18T16:39:28.000+09:00",
              "updated_at": "2017-10-18T16:39:50.000+09:00",
              "state": "Running"
            }
          ],
          "state": "Running"
        }
      ],
      "name": "ilbtest",
      "created_at": "2017-10-18T16:39:28.000+09:00",
      "updated_at": "2017-10-18T16:39:50.000+09:00",
      "state": "Running",
      "fqdn": "ilbtest.public.ilb.jp-east-2.idcfcloud.net",
      "zone_id": "95c8746d-57b3-421f-9375-34bea93e2a3d",
      "zone_name": "lux"
    }
  ]
}
```
###add_server：ILBにサーバを追加する

では、ILBにサーバをもう一台追加してみます。
パラメータは、上記の　`list_loadbalancers`　で返ってきた値と追加サーバの情報です。

 - ILBのID
 - configのID
 - 追加サーバのdata（IPアドレスとポート番号）


実行すると、ILBの配下のサーバがに2台になります。

```
$ idcfcloud ilb add_server \
> "5ea2a04b-3419-43ea-a9ee-bdbba9abad95" \
> "17a3c43b-ba12-474e-be9d-4aa1afb314b7" \
> '{"ipaddress":"10.32.0.15", "port":80}'
{
  "status": 200,
  "message": "",
  "data": [
    {
      "id": "20344366-d7c2-4e96-8bbc-ba2bbfcefe02",
      "ipaddress": "10.32.0.161",
      "port": 80
    },
    {
      "id": "4c3f6365-458a-4778-95b6-b337ed604598",
      "ipaddress": "10.32.0.15",
      "port": 80
    }
  ]
}
```

###delete_server：ILBからサーバを削除する

次は、追加したサーバを削除してみます。
パラメータは以下です。

 - ILBのID
 - configのID
 - 対象サーバのID
 
```
$ idcfcloud ilb delete_server \
> "5ea2a04b-3419-43ea-a9ee-bdbba9abad95" \
> "17a3c43b-ba12-474e-be9d-4aa1afb314b7" \
> "4c3f6365-458a-4778-95b6-b337ed604598"
{
  "status": 200,
  "message": "",
  "data": null
}
```

###list_servers：サーバリストの確認
サーバーリストを実行してみます。
パラメータは以下です。

 - ILBのID
 - configのID
 


```
$ idcfcloud ilb list_servers \
> "5ea2a04b-3419-43ea-a9ee-bdbba9abad95" \
> "17a3c43b-ba12-474e-be9d-4aa1afb314b7"
{
  "status": 200,
  "message": "",
  "data": [
    {
      "id": "20344366-d7c2-4e96-8bbc-ba2bbfcefe02",
      "ipaddress": "10.32.0.161",
      "port": 80
    }
  ]
}
```

###create_loadbalancer：ILBを新規作成する
`create_loadbalancer`のパラメータは、helpを見ても`<attributes> [headers]`とあるだけで、
何を指定するのかよくわかりません・・・。

```
$ idcfcloud ilb help
Commands:
...
  idcfcloud ilb create_loadbalancer <attributes> [headers]                   ...
...
```
気になるので、調べてみましょう。

```
$ idcfcloud ilb create_loadbalancer '{"name": "lbtest", "network_id": "34a1ea86-9ef1-485d-9a45-bd509f0e8d33", "configs": [{"ipaddress":"10.32.0.161", "port":80}]}'
HTTP status code: 400, Error message: Parameter Error.
frontend_protocol(#0) is invalid,backend_protocol(#0) is invalid,servers(#0) is invalid,algorithm(#0) is invalid,healthcheck(#0) is invalid, Reference: http://docs.idcf.jp/cloud/ilb/
```
パラメータが足りないみたいですね。
エラーとなっているパラメータを追記して・・・。

```
$ idcfcloud ilb create_loadbalancer '{"name": "lbtest", "network_id": "34a1ea86-9ef1-485d-9a45-bd509f0e8d33", "configs": [{"port": 80, "algorithm": "roundrobin", "healthcheck": {"check_interval": 30, "timeout": 5,"type": "http","unhealthy_threshold": 2,"healthy_threshold": 10,"path": "/"}, "frontend_protocol": "http", "backend_protocol": "http", "connection_timeout": 60, "servers": [{"ipaddress":"10.32.0.161", "port":80}]}]}'
{
  "status": 200,
  "message": "",
  "data": {
    "id": "bf82c638-adf7-4ae4-b461-b1bc5ab23a7c",
    "configs": [
      {
...
    "state": "Running"
  }
}
```

できました♪
HTTPの負荷分散の例なので、用途によってパラメータが変わると思いますが、とりあえずこんな感じ。

- name：作成するILBの名前、FQDN
- network_id：ILBを配置するネットワークのID
- configs：複数指定可能
    - port：ポート番号
    - algorithm：ロードバランシングアルゴリズム。Round Robin/Least Connection/Source IP
    - healthcheck：ヘルスチェック
        - check_interval：間隔(秒)
        - timeout：タイムアウト(秒)
        - type：HTTP/TCP
        - unhealthy_threshold：失敗回数(Down)
        - healthy_threshold：成功回数(Up)
        - path：パス
    - frontend_protocol：フロントエンドプロトコル HTTP/HTTPS/TCP/SSL
    - backend_protocol：バックエンドプロトコル HTTP/HTTPS
    - connection_timeout：コネクションタイムアウト
    - servers：ILBに追加するサーバの情報。複数指定可能
        - ipaddress：仮想マシンのIPアドレス
        - port：ポート番号

###delete_loadbalancer：ILBを削除する
ついでに、作ったILBを削除します。パラメータは以下です。

 - 削除したいILBのID

```
$ idcfcloud ilb delete_loadbalancer "bf82c638-adf7-4ae4-b461-b1bc5ab23a7c"
{
  "status": 200,
  "message": "",
  "data": null
}
```

##ILBへサーバ追加／削除するシェルスクリプト
JQコマンドを使うと、JSONデータから欲しい値だけを抽出することができます。
ILBの情報から必要なIDを抽出して、その値をパラメータに次のコマンドを実行すれば、
ILBへサーバ追加／削除するシェルスクリプトになります。

###サーバ追加

```
$ vim add_server_test.sh
#!/bin/sh

ILB_ID=`idcfcloud ilb list_loadbalancers | jq -r '.data[] | select(.network_name == "lux-network1") | .id'`
CONFIG_ID=`idcfcloud ilb list_loadbalancers | jq -r '.data[] | .configs[] | select(.port == 80) | .id'`

idcfcloud ilb add_server $ILB_ID $CONFIG_ID '{"ipaddress":"10.32.0.15", "port":80}'

$ chmod 755 add_server_test.sh
$ ./add_server_test.sh
```

場合によってselectの条件を変更してください。
`-r`は返り値からダブルクォートを外すオプションです。付けないとうまく動かないので注意です。

###サーバ削除

```
$ vim del_server_test.sh
#!/bin/sh

ILB_ID=`idcfcloud ilb list_loadbalancers | jq -r '.data[] | select(.network_name == "lux-network1") | .id'`
CONFIG_ID=`idcfcloud ilb list_loadbalancers | jq -r '.data[] | .configs[] | select(.port == 80) | .id'`
SERVER_ID=`idcfcloud ilb list_loadbalancers | jq -r '.data[] | .configs[] | select(.port == 80) | .servers[] |select(.ipaddress == "10.32.0.15") | .id'`

idcfcloud ilb delete_server $ILB_ID $CONFIG_ID $SERVER_ID

$ chmod 755 del_server_test.sh
$ ./del_server_test.sh
```


`.servers[] |select(.ipaddress == "10.32.0.15") | .id`
の部分で IPアドレス をキーに削除対象のサーバIDを取得していますが、
例えば、
`.servers[0] | .id'`
とすると1つ目のサーバのIDを取得できます。