DigitalOcean APIコマンドラインのtugboatでdroplet作成、破棄、スナップショット作成などを試す

この記事はViibarアドベントカレンダーのとある1日の記事でございます。

DigitalOceanはJSON REST APIを提供してくれているのでそれを利用して様々な操作をすることができます。また、各言語向けのラッパーがオフィシャル、サードパーティ問わず存在しています [[DigitalOcean API](https://developers.digitalocean.com/libraries/)]。

ここでは、APIのRubyラッパーである [blom/barge](https://github.com/blom/barge) を利用したコマンドラインクライアントである、 [pearkes/tugboat](https://github.com/pearkes/tugboat) を利用して、コマンドラインからDigitalOceanを利用してみたいと思います。

## tugboat

tugboatはdropletの操作だけでなく、リソースの一覧を参照するのにも有効です。

DigitalOcean APIはJSONで結果を返してくれるため、そのままではひとが読むにはツライので`jq`などを利用して整形してやる必要がありますが、

```
$ curl -X GET "https://api.digitalocean.com/v2/sizes" -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.sizes[].slug'
"512mb"
"1gb"
"2gb"
"4gb"
"8gb"
"16gb"
"32gb"
"48gb"
"64gb"
```

tugboatを使えば、ヒューマンリーダブルな一覧として表示してくれます。

```
$ tugboat sizes
Sizes:
Disk: 20GB, Memory: 512MB (slug: 512mb)
Disk: 30GB, Memory: 1024MB (slug: 1gb)
Disk: 40GB, Memory: 2048MB (slug: 2gb)
Disk: 60GB, Memory: 4096MB (slug: 4gb)
Disk: 80GB, Memory: 8192MB (slug: 8gb)
Disk: 160GB, Memory: 16384MB (slug: 16gb)
Disk: 320GB, Memory: 32768MB (slug: 32gb)
Disk: 480GB, Memory: 49152MB (slug: 48gb)
Disk: 640GB, Memory: 65536MB (slug: 64gb)
```

## 前提

- Ruby 1.9以上がインストールされていること
- DigitalOceanのアカウントがあること
- DigitalOceanのPersonal Access Tokenが[settings/applications](https://cloud.digitalocean.com/settings/applications)から取得されていること
- SSHの公開鍵が[settings/security](https://cloud.digitalocean.com/settings/security)で登録されていること

### DigitalOcean API Document

[DigitalOcean API](https://developers.digitalocean.com/documentation/v2/)


## インストール

```
gem install tugboat
```

## Authorize

途中でdefaultの値を聞かれますが、後ほど、実際にAPIを叩いて諸々の情報を確認しようと思いますので、とりあえずはそのままで良いと思います。SSHの秘密鍵は、tugboat経由でssh接続する際に使われますので、あらかじめ登録している公開鍵に対応した秘密鍵を指定しましょう。

```
$ tugboat authorize
Note: You can get your Access Token from https://cloud.digitalocean.com/settings/tokens/new

Enter your access token: ${ACCESS_TOKEN}
Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa):
Enter your SSH user (optional, defaults to root):
Enter your SSH port number (optional, defaults to 22):

To retrieve region, image, size and key ID's, you can use the corresponding tugboat command, such as `tugboat images`.
Defaults can be changed at any time in your ~/.tugboat configuration file.

Enter your default region (optional, defaults to nyc1):
Enter your default image ID or image slug (optional, defaults to ubuntu-14-04-x64):
Enter your default size (optional, defaults to 512mb)):
Enter your default ssh key IDs (optional, defaults to none, comma separated string):
Enter your default for private networking (optional, defaults to false):
Enter your default for enabling backups (optional, defaults to false):
Authentication with DigitalOcean was successful.
```

これで`tugboat`コマンドが実行できるようになりました。ここで入力した値は`~/.tugboat`に保存されます。では、`tugboat sizes`、`tugboat regions`、`tugboat keys`あたりを確認して、実際の希望の値に変更しておきましょう。


## Create & SSH

```
$ tugboat create first-droplet-via-api
Queueing creation of droplet 'first-droplet-via-api'...Droplet created!
```

作成できたようです。
確認してみます。

```
$ tugboat droplet
first-droplet-via-api (ip: 188.xxx.xxx.xxx, status: active, region: sgp1, id: 9385141)
```

OKのようです。
SSHでつないでみます。

```
$ tugboat ssh first-droplet-via-api
Droplet fuzzy name provided. Finding droplet ID...done, 9385141 (first-droplet-via-api)
Executing SSH on Droplet (first-droplet-via-api)...
Attempting SSH: root@188.xxx.xxx.xxx
SShing with options: -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -i /Users/shrkw/.ssh/id_rsa -p 22 root@188.xxx.xxx.xxx
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-71-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

  System information as of Sun Dec 13 08:00:18 EST 2015

  System load: 0.0                Memory usage: 9%   Processes:       50
  Usage of /:  10.6% of 19.56GB   Swap usage:   0%   Users logged in: 0

  Graph this data and manage this system at:
    https://landscape.canonical.com/

root@first-droplet-via-api:~#
```

つながりました。よかったです。作業の続きができることを確認するためにファイルを残しておきます。

```
root@image-from-snapshot:~# echo 'I was here.' > README
```

次の手順でスナップショットをとるのでssh接続上で`poweroff`しておくか、`tugboat halt first-droplet-via-api`します。

## Take a Snapshot & Destroy

スナップショットもとってみましょう。

```
$ tugboat snapshot first-snapshot first-droplet-via-api
Droplet fuzzy name provided. Finding droplet ID...done, 9385141 (first-droplet-via-api)
Warning: Droplet must be in a powered off state for snapshot to be successful
Queuing snapshot 'first-snapshot' for 9385141 (first-droplet-via-api)...Snapshot successful!
```

スナップショットがあれば今のdropletは用無しです。`destroy`します。

```
$ tugboat destroy first-droplet-via-api
Droplet fuzzy name provided. Finding droplet ID...done, 9385141 (first-droplet-via-api)
Warning! Potentially destructive action. Please confirm [y/n]: y
Queuing destroy for 9385141 (first-droplet-via-api)...Deletion Successful!
```

## Create from a Snapshot

スナップショットから`create`しようと思いますが、`tugboat create`コマンドの`--image`オプションは名前解決はしてくれないようです。なので、idを調べます。

```
$ tugboat images --show_just_private_images
Showing just private images
Private Images:
first-snapshot (id: 14825860, distro: Ubuntu)
```

idがわかったので`create`のオプションに渡します。

```
$ tugboat create --image=14825860 droplet-from-snapshot
Queueing creation of droplet 'droplet-from-snapshot'...Droplet created!
```

できました。sshでつないで、`README`ファイルをみてみます。

```
$ tugboat ssh droplet-from-snapshot
```

```
root@image-from-snapshot:~# cat README
I was here.
```

正しくスナップショットから作成できているようです。よかったですね。
これで、一連の作業をwebからログインすることなく全てコマンドラインで完結させることができました。

tugboatはDigitalOceanのAPIがシンプルなぶん、こちらもシンブルで、使いやすくてとても良いツールですね。`thor`や`middleware`の使い方サンプルとしてもとても勉強になりました。