ABEJA Platform(の一部)をTerraformで管理してみる

[ABEJA Platform Advent Calendar](https://qiita.com/advent-calendar/2018/abejaplatform) 2018の5日目です。

# 自己紹介
はじめまして、[KICONIA WORKS](https://www.kiconiaworks.com/)の日熊です。
今年の[ABEJA Platform Advent Calendar](https://qiita.com/advent-calendar/2018/abejaplatform)では数少ないの非ABEJA社員の投稿だと思います。(元社員ですが) 来年はもうちょっとコミュニティが育ってるといいですねと思っています。

今日の記事ではterraformについて書きますが、インフラ屋さんではありません。
よくわからない職種なのであんまり言いたくないですが、AIエンジニア的な立ち位置な人です。(趣味でWeb開発とか触ったり、ひょんなことからTerraformを触ったりしてました)

# はじめに

ABEJA Platformはいわゆるクラウド型の深層学習向け(AI向け？)Platformです。

誤解を恐れずにいうとAIの学習や実行インフラを提供してくれてるわけです。

[こちら(ABEJA Platformを使ってコード0行でresnet50のモデルをデプロイしてみる)](http://st-hakky.hatenablog.com/entry/2018/12/02/215016)の記事を読んでいただけるとわかりやすいのですが、コード0行で深層学習を実行する WebAPIを作ることができたりします。

コードレス・コマンドレスで実行環境を用意してくれるのは嬉しいですね。
しかし、あえていいましょう。
**毎回画面をポチりたくない**ですよね。
ABEJA Platformは見渡した感じでは Cloud Trail的な機能も見当たりませんので、画面をポチってると履歴とかも残らず再現性は厳しそうな感じです。(Cloud Trailは再現性の為の機能で無いのは理解の上です)

ということで、
[Terraform](https://www.terraform.io/)でABEJA PlatformにResnet50をデプロイしていきたいと思います。(内容的には[こちら](http://st-hakky.hatenablog.com/entry/2018/12/02/215016)といっしょです)

# Terraformとは

Terraform は、Vagrant などで有名な HashiCorp が作っているコードからインフラリソースを作成する・コードでインフラを管理するためのツールです。AWS, GCP, Azure, DigitalOcean といったクラウドプロバイダや DNSimple, Mailgun, Rundeck を含む多くの SaaS に幅広く対応しています。 ([参照元](https://qiita.com/dtan4/items/ab1671d657f1571e59d8#terraform-%E3%81%A8%E3%81%AF))

# 事前準備

## TerraformってABEJA Platformに対応してるの？

とりあえず、皆さんterraformで適当なクラウドサービスを管理したいときどうしますか？

**そうですねググりますね**
とりあえず、僕もググってみました
「abeja platform terraform provider」

なんと出ません。。。
なぜだ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5918/95ab8a4e-d28c-3c30-fd77-c228fa3e981e.png)

悲しいですね。
まだまだ、マイナーだ(伸びしろがある)ということなので頑張って欲しいところです。


つまり、(公式/非公式合わせて)**対応してません** (2018/12/01 現在)

## どうするのか

なければ作ります。

[こちら](https://www.terraform.io/docs/extend/writing-custom-providers.html)に作り方が書いてあるので、読みつつ。
足りない部分は[aws provider](https://github.com/terraform-providers/terraform-provider-aws/)のコードを読みつつ。

がんばります。

terraformのprovider(plugin的なの) は基本Go言語で書くのですが。
ABEJA platformには公式/非公式合わせてGoのSDKは無いみたい(Pythonのみ?)ですので、WebAPIを`net/http`で叩きながらって感じになりました。(CLIが提供されてるからそれでやればっていうのもありますが、一応勉強も踏まえてWebAPIで作りました)

## ミニマムなproviderができました 

https://github.com/higumachan/terraform-abeja-platform

ここにコードは全部おいてあります。
Go言語は初めて書いたので普通にいろいろしくったなと思う部分が多かったりします。



# (本題) abeja platform を terraformで管理する方法

## providerのビルド
上のリポジトリで

```
go build -o /path/to/{terraformの作業ディレクトリ}
```

ように実行します。

これで、abeja platform用の(ミニマムな)providerがビルドされます。

## 学習ファイルのダウンロード

ABEJA Platformでは実行するための関連ファイルを`zip`または`tar.gz`で固めておいてあげる必要がある(AWS Lambdaみたいなものです)ので今回はそれをダウンロードして適当な名前をつけておきます。

```
curl https://abeja-platform-config-prod.s3.amazonaws.com/sample_code/keras/resnet50.tar.gz > upload/model.tar.gz
```

## tfファイルを書く

以下のような tfファイルを書きます

```main.tf
variable "user_id" {}
variable "personal_access_token" {}
variable "organization_id" {}

provider "abeja" {
  user_id = "${var.user_id}"
  personal_access_token = "${var.personal_access_token}"
  organization_id = "${var.organization_id}"
}

resource "abeja_model" "my-model" {
  name = "nadeko"
  description = "nadeko is cute"
}

resource "abeja_model_version" "my-modelversion" {
  model_id = "${abeja_model.my-model.id}"
  version = "0.0.1"
  image = "abeja-inc/all-cpu:18.10"
  handler = "main:handler"
  upload_file_path = "upload/model.tar.gz"
}

resource "abeja_deployment" "my-deployment" {
  model_id = "${abeja_model.my-model.id}"
  name = "rikka"
  default_environment = "{}"
}

resource "abeja_deployment_service" "my-service" {
  deployment_id = "${abeja_deployment.my-deployment.id}"
  instance_number = 1
  instance_type = "cpu-0.25"
  environment = "{}"
  version_id = "${abeja_model_version.my-modelversion.id}"
}
```

名前は適当に決めてあげてください。
`abeja_model_version.my-version.upload_file_path`に関しては先程ダウンロードしたファイルを指定するようにしてください。

## tfvarファイルを作る

```my.tfvar
user_id = "{ABEJA PlatformのUserID}"
personal_access_token = "{ABEJA PlatformのPersonal Access Token}"
organization_id = "{ABEJA PlatformのOrganization ID}"
```

こちらの認証情報は未契約の方はぜひABEJA Platformを契約して取得してください。(中の人から、興味あったら[連絡ください！](https://abejainc.com/platform/ja/contact/)ってコメントがありました)

## terraform init

```bash
terraform init
```

問題なくビルドできていれば

```
Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

こんな感じの説明が出ます。

## terraform plan

とりあえず、planしましょう。

```bash
terraform plan --var-file my.tfvars
```

* abeja_deployment.my-deployment
* abeja_deployment_service.my-service
* abeja_model.my-model
* abeja_model_version.my-modelversion

を作るよって書いてあれば、問題ありません。

## 事前確認

とりあえず、ABEJA Platformに何も無いことを確認しておきましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5918/6a7790ee-77c2-975a-3293-08f98ae3d04e.png)


## terraform apply

そして、applyです。

```bash
terraform apply --var-file my.tfvars
```

## 確認

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5918/a38ee32f-da0a-11f6-ace1-a10a6be59f3e.png)

何かが作られてますね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5918/4d4a3fbd-4f6e-bd80-51a5-f203aa4e6f32.png)

このようにWeb APIも作られています。
何度も言いますが、成果は[こちら](http://st-hakky.hatenablog.com/entry/2018/12/02/215016)といっしょです。

## 破棄

Deleteも実装されているので、`destroy`もできます。


```bash
terraform destory --var-file my.tfvars
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5918/3bc93ea2-9cbd-4f5d-6eb9-3550fc3d09d5.png)

跡形もなく消え去りました。
検証しながらやってるときは意外と便利ですね、ポチポチやってるときには無い体験かなと思います。

# まとめ

今回はABEJA PlatformのチュートリアルをTerraformで行いました。
ABEJA Platformは

- (もちろん)terraformの定義ファイルが書けて
- goが書けて
- 十分に時間があれば (今回はGoの勉強やawsのproviderを読んでる時間含めて、所要時間6時間くらい)

Terraformで管理できることがわかりました。

**これがあれば、画面ポチポチとはおさらばです。**