ニフクラ用の Terraformカスタムプロバイダを書いてみる

## 概要

AWS に触れるようになってから、なるべくインフラ構築はコードで管理したい、と思うようになりました。
業務では主に Terraform を利用しています。
AWS や vSphere はプロバイダがあるため、それを利用させていただくだけだったのですが、ニフクラも同じように構築したい、と思ったところ、プロバイダが見当たりませんでした。
諦めきれずにいろいろと調べていたら、いつのまにかカスタムプロバイダを書いていたので、その記録を残しておこうと思います。
なお、セールスエンジニアが見様見真似でこういうことをやった、という記録のため、あまり技術的なものではありませんので、ご了承ください。

## 結果

完成してはいませんが、[ここ](https://github.com/shztki/terraform-provider-nifcloud)までできました。
中途半端ですが、本日現在の状態でいったん `v0.0.1` のタグをつけています。
Goの環境が必要ですが、以下の流れで利用することができます。

```
$ mkdir -p $GOPATH/src/github.com/shztki; cd $GOPATH/src/github.com/shztki
$ git clone https://github.com/shztki/terraform-provider-nifcloud.git; cd terraform-provider-nifcloud
$ go build
$ mkdir -p ~/.terraform.d/plugins/
$ mv terraform-provider-nifcloud ~/.terraform.d/plugins/
$ cd examples
$ terraform init
$ terraform plan
$ terraform apply
```

## サンプルイメージ

examplesのコードを実行すると、とりあえず以下のような環境ができあがる状態になっています。
disableにしていますが、RDBも作成可能です。
<img width="1896" alt="nifcloud_examples_001.png" src="https://raw.githubusercontent.com/shztki/terraform-provider-nifcloud/images/nifcloud_examples_001.png">

## 今後

ロードバランサー、付替IPアドレスくらいまではなんとか追加したいと思っていますが、残念ながらニフクラを利用する職場から離れることになったため、今後の更新はできないと思います。
もしもニフクラ用カスタムプロバイダを作りたい、と思った方がいらっしゃった場合に、このコードや記事が多少でもお役に立てれば幸いです。

## 記録

以降はチラシの裏的なレベルですが、どうやって上記の成果物ができあがったか、を書いていきたいと思います。
繰り返しますが、技術的な内容ではありません。。。

### 検索

すべてのはじまりは検索からということで、「ニフクラ Terraform 構築」とか、「ニフクラ Terraform プロバイダ」とか、「Terraform provider nifcloud」とか、とにかく検索しました。
なかなか情報がでてこないなか、唯一見つけられたのが以下になります。

[https://github.com/kzmake/terraform-provider-nifcloud](https://github.com/kzmake/terraform-provider-nifcloud)

最初は「ダウンロードして置いたら終わり、とかじゃないのか・・・」と見て見ぬフリをしていたのですが、他にはまったく見つからなかったので、諦めて Go の環境を用意しました。
build自体は問題なかったのですが、 Terraform v0.12 だと動かないとか、ニフクラAPI のエンドポイントURL が変わってしまっていたりとか、いろいろありました。
がんばって修正したり、 Terraform v0.11 を使ったりして、なんとか動いたときはうれしかったですね。
ただ、作成できるリソースがほとんどなかったり、Terraform v0.12 に対応していないのは困るなぁ、と考えて、自分で手を加えてみよう！ と決めました。

### SDK

最初は nifcloudディレクトリ配下に、追加したいリソース用のコードを追加していけばいいんだ、と考えました。
しかしやってみると、ときどき関数の戻り値で意図した結果が得られなかったりしました。
どこを修正すればいいのかとたどっていって、気づいたのが nifcloud-sdk-go です。
重要なのは、ニフクラ用の API を Go で書いた SDK だったんですね！
最初は vendorディレクトリ配下をちまちま修正していたのですが、あるときこれもどこかからクローンしたものだ、と気づきました。
それが以下になります。

[nifcloud-sdk-go](https://github.com/aokumasan/nifcloud-sdk-go)
(以前は alice02 でしたけど、今は aokumasan に変わっていらっしゃいますね)

kzmake様のコードでも、上記をクローンしてきて、自身の環境の方を見るようにしている、ということのようでした。
しかも、aokumasan様の nifcloud-sdk-go はその後更新があったようで、エンドポイントURL とかちゃんと修正されています。
なるほど・・・となり、自分も改めて一から同じ流れで作成するようにしてみよう、と考えて、作り直すことにしました。
nifcloud-sdk-go を自分の[環境](https://github.com/shztki/nifcloud-sdk-go)にクローンし、ここを修正していくことにします。
また、terraform-provider-nifcloud もモジュール管理を dep から GoModules に変えて、SDK参照先を自分の環境にしました。
これで、ようやく環境が整った感じなりました。
SDK側に問題がある場合は [nifcloud-sdk-go](https://github.com/shztki/nifcloud-sdk-go)を修正し、プロバイダの作成は [terraform-provider-nifcloud](https://github.com/shztki/terraform-provider-nifcloud)側で行います。

### SDKの修正

最初はわけもわからず、serviceディレクトリ配下のファイルを直接修正していました・・・。
途中で気づいたのですが、どうやら重要なのは models/apisディレクトリ配下の json で書かれた定義ファイルのようで、そこを修正して以下のコマンドを実行すると、定義にあわせて serviceディレクトリ配下が生成されるようでした。

```
go generate ./service
```

この仕組に気づいた結果、それなら最新の定義ファイルが手に入ったら、~~より楽ができる~~最新のAPIが利用できるのでは・・・と考えました。
そして見つけたのが以下になります。

[nifcloud-sdk-python](https://github.com/nifcloud/nifcloud-sdk-python/tree/master/nifcloud/data)

ニフクラ公式で作成されているらしい、nifcloud-sdk-python になります。
こちらの更新の方が新しかったので、きっと API も新しいはず・・・。
こちらでは service-2.json という名前でしたが、nifcloud-sdk-go側の api-2.json と中身を比較し、書式とか中身は同じだ、とわかったので、computing/nas/rdb/script それぞれコピーさせていただきました。

他には、[aws-sdk-go](https://github.com/aws/aws-sdk-go)も参考になります。
特に DBパラメーターのところで使うことになりましたが、paginate処理をどうしていいか途方にくれたときは、paginators-1.json を利用すればいい、とわかって解決できました。

あとは、なんといっても API の詳細が重要なので、常に利用するものは以下ページを見るようにしていました。

[ニフクラREST API](https://pfs.nifcloud.com/api/rest/)

型がちがう場合や、必要なパラメータが抜けていることもあったりしたので、都度 jsonファイルを修正しています。

### プロバイダの作成

kzmake様のコードや主に [terraform-provider-aws](https://github.com/terraform-providers/terraform-provider-aws)を参考にさせていただき、作っています。
ニフクラREST API の情報や、[エラーコード](https://pfs.nifcloud.com/api/rest/errorcode.htm)あたりもあわせてチェックします。
本当はもっとコードに統一感があったり、validation やエラーハンドリングももっとできることがあるかもしれませんが、そのあたりの出来にはバラツキがあります。。。
テストとかもよくわからないままです。
とにかく、作成できるリソースを増やすことを目標に、細かいことは気にせずに追加してきた感じです。

## 最後に

なぐり書きのような文章にお付き合いいただき、ありがとうございました。
私の試行錯誤した流れが、多少でもお役に立てれば幸いです。
どうぞよいニフクラライフを！