IBM Cloud: VPCのVSIをIPアドレス指定でプロビジョニングする方法

# 1. はじめに
本記事執筆時点（2020年8月）では、IBM Cloud PortalからVPC版のVSIをプロビジョニングする際に、subnetの指定はできるがIPアドレスの指定をGUI画面で行うことはできない。
しかし、CLIやAPIで、`primary_ipv4_address`フィールドを指定すれば、IPアドレスの指定はできる。参考API資料は[こちら](https://cloud.ibm.com/apidocs/vpc#create-an-instance)。
CLIでも`ibmcloud is instance-create`コマンドなどで実行できるのだが、その際にいちいち各種ID情報を取得してくるのが面倒である。そこで、今回は（多分一番簡単な方法だと思われる）APIを使ったやり方を紹介する。

(2020/09/18追記)
VSI注文後に、2つ目以降のvNICにIPアドレスを明示的に指定する方法は、[こちら](https://qiita.com/testnin2/items/dbf5b509fb725380dcbf)をご参照ください。

(2022/03/31追記）
今後はこちらを使う方が良さそうです。
[IBM Cloud: VPCのVSIをIPアドレス指定(reserved IPを利用)でプロビジョニングする方法](https://qiita.com/testnin2/items/1a15a793aa73d7b61578)


# 2. 構成の作成とSample API callの生成
. IBM Cloud PortalからVPC版のVSIの注文画面で最終的にプロビジョニングしたい構成をいったんGUIベースで作った後、`Get sample API call`を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/99a8abe9-cea5-5f85-6d54-160a3e4d2fe1.png)

すると、以下のようなsample API callが出力されるので、このコードをコピーし、スクリプト（例えばvsi.sh）として保管する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d5006a53-6920-f0c3-d80d-5397c07a2908.png)

# 3. sample API callの修正

```json:vsi.sh（修正前）
（省略）
  "primary_network_interface": {
    "name": "eth0",
    "allow_ip_spoofing": false,
    "subnet": {
      "id": "02e7-ff96ff2a-fa27-4d88-b855-98fb85112636"
    },
    "security_groups": [
      {
        "id": "r022-1a2bb9f2-7647-4332-8a1b-eb925fb6e160"
      }
    ]
  },
（省略）
```

みたいになっている箇所を修正し、`"primary_ipv4_address": "10.0.0.5",`みたいにIPアドレスを明示的に追加指定する。

```json:vsi.sh（修正後）
（省略）
  "primary_network_interface": {
    "name": "eth0",
    "primary_ipv4_address": "10.0.0.5",
    "allow_ip_spoofing": false,
    "subnet": {
      "id": "02e7-ff96ff2a-fa27-4d88-b855-98fb85112636"
    },
    "security_groups": [
      {
        "id": "r022-1a2bb9f2-7647-4332-8a1b-eb925fb6e160"
      }
    ]
  },
（省略）
```

なお、指定するIPアドレスは[ここ](https://cloud.ibm.com/docs/vpc?topic=vpc-about-networking-for-vpc&locale=en#reserved-ip-addresses)に記載されているとおり予約済みアドレスを避ける必要があることに注意。

例えば`10.0.0.0/24`というsubnetでは以下が予約済みでありユーザーが利用することはできない。

```
10.0.0.0: Network address
10.0.0.1: Gateway address
10.0.0.2: reserved by IBM
10.0.0.3: reserved by IBM for future use
10.0.0.254: Broadcast address
```


# 4. IAMトークンの取得とスクリプトの実行
上記スクリプトを実行するためには、`$iam_token`という変数名でIAMのトークンが設定されている必要があるので、以下でiam_token取得した後、シェルを実行してVSIをプロビジョニングする。（なお、IAM_TOKENの取得方法については、[こちら](https://qiita.com/testnin2/items/3a4ca8a1a2b79b713c48)も参考）

```
$ export iam_token=`ibmcloud iam oauth-tokens | awk '{printf $4}'`
$ sh vsi.sh
```

# 5. 結果の確認
指定した構成で作成された（今回の例では`10.0.0.5`を指定したが、確かにそのとおりの構成になっている！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/9f38d918-c84a-b910-0398-3961cb00eaa1.png)



#（参考）2つ目以降のInterfaceでのIPアドレスを指定する時。

1つ目のInterfaceでの指定と同様に`"primary_ipv4_address"`を利用すれば良い。

```json:設定例（抜粋）
  "primary_network_interface": {
    "name": "eth0",
    "primary_ipv4_address": "10.0.0.100",
    "allow_ip_spoofing": false,
    "subnet": {
      "id": "02e7-ff96ff2a-fa27-4d88-b855-98fb85112636"
    },
    "security_groups": [
      {
        "id": "r022-1a2bb9f2-7647-4332-8a1b-eb925fb6e160"
      }
    ]
  },
  "network_interfaces": [
    {
      "name": "eth1",
      "primary_ipv4_address": "10.4.0.100",
      "allow_ip_spoofing": false,
      "subnet": {
        "id": "02e7-b50228c7-2431-4854-ad4c-b68f6c7382a7"
      },
      "security_groups": [
        {
          "id": "r022-1a2bb9f2-7647-4332-8a1b-eb925fb6e160"
        }
      ]
    }
  ],
```


プロビジョニング後の状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/b9e8ff15-dfa6-3004-1b68-10ef8ac52694.png)