Ansible で Droplet をあげてみる

IaaS である Digital Ocean に対して Ansible で Droplet（いわゆる仮想マシン）の起動を試みた時のログ。

# 準備と前提

* Ansible ホスト側には dopy が必要（pip install dopy or python-pip install dopy）
* Digital Ocean の Personal Access Tokens を取得しておく
* Digital Ocean と SSH 接続するために ssh-key を作って登録しとく（login -> Settings -> Security -> SSH Keys）
* Digital Ocean API は version 2 を使う

# 環境

* Ansible Host : Vine Linux 6.3 
* Ansible version 2.0.0

# Ansible 準備
## Inventory

```shell-session:hosts
127.0.0.1 ansible_connection=local
```

## role

```shell-session:role/ocean/tasks/main.yml
 - name: Create droplet in DigitalOcean
   digital_ocean:
     state=present
     command=droplet
     name=mydroplet-test
     ssh_key_ids=987654321
     api_token=aaaaaaaaaaaaa
     image_id=ubuntu-14-04-x64
     size_id=1gb
     region_id=sgp1
     wait_timeout=500
   register: my_droplet
 - debug: msg="ID is {{ my_droplet.droplet.id }}"
 - debug: msg="IP is {{ my_droplet.droplet.ip_address }}"
```

* images_id、region_id、size_id をドキュメントで確認しとく

```shell-session
$ curl -X GET -H 'Content-Type: application/json' -H 'Authorization: Bearer <your token>' "https://api.digitalocean.com/v2/images" | jq '.regions[] | .slug,'
```

```shell-session
$ curl -X GET -H 'Content-Type: application/json' -H 'Authorization: Bearer <your token>' "https://api.digitalocean.com/v2/regions" | jq '.regions[] | .name,.slug,.sizes'
```

* 登録してある ssh_key_ids は 以下のようにして確認しとく

```shell-session
$ curl -X GET -H 'Content-Type: application/json' -H 'Authorization: Bearer <your token>' "https://api.digitalocean.com/v2/account/keys" | jq '.ssh_keys[] | .id'
```
* 最後の3行のように IP Address と Droplet ID を表示しとくようにすると後々便利

## Playbook

```shell-session:ocean.yml
- hosts: all

  roles:
    - ocean
```

# Playbook 実行

```shell-session
[hoge@akira tmp]$ ansible-playbook -i local_hosts ocean.yml

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [ocean | Create droplet in DigitalOcean] ********************************
changed: [127.0.0.1]

TASK: [ocean | debug msg="ID is {{ my_droplet.droplet.id }}"] *****************
ok: [127.0.0.1] => {
    "msg": "ID is 1234567"
}

TASK: [ocean | debug msg="IP is {{ my_droplet.droplet.ip_address }}"] *********
ok: [127.0.0.1] => {
    "msg": "IP is 111.222.333.444"
}

PLAY RECAP ********************************************************************
127.0.0.1                  : ok=4    changed=1    unreachable=0    failed=0
```

![2015-05-23 9-09-35.png](https://qiita-image-store.s3.amazonaws.com/0/75458/e6100181-104b-f26c-2c85-dba062cf59ac.png)

# リモートログイン

```shell-session
[hoge@akira ~]$ ssh -i docean.key root@111.222.333.444
The authenticity of host '111.222.333.444 (111.222.333.444)' can't be established.
ECDSA key fingerprint is 80:93:98:ea:ca:f1:2a:ed:4a:77:55:7d:d4:f9:a4:71.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '111.222.333.444' (ECDSA) to the list of known hosts.
Enter passphrase for key 'docean.key':
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-52-generic x86_64)

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

  System information as of Fri May 22 20:08:46 EDT 2015

  System load: 0.0               Memory usage: 5%   Processes:       51
  Usage of /:  5.0% of 29.40GB   Swap usage:   0%   Users logged in: 0

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

root@mydroplet-test:~#
```

# 冪等性（Idempotence）

上記で作ったときに Droplet の ID がわかってるのでそれを適用する。

```shell-session:roles/ocean/tasks/main.yml
 - name: Create droplet in DigitalOcean
   digital_ocean:
     state=present
     command=droplet
     id=1234567  ★ ここ
     name=mydroplet-test
     ssh_key_ids=987654321
     api_token=aaaaaaaaaaaaa
     image_id=ubuntu-14-04-x64
     size_id=1gb
     region_id=sgp1
     wait_timeout=500
   register: my_droplet
 - debug: msg="ID is {{ my_droplet.droplet.id }}"
 - debug: msg="IP is {{ my_droplet.droplet.ip_address }}"
```

実行してみる。

```shell-session
[hoge@akira tmp]$ ansible-playbook -i local_hosts ocean.yml

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [ocean | Create droplet in DigitalOcean] ********************************
ok: [127.0.0.1]

TASK: [ocean | debug msg="ID is {{ my_droplet.droplet.id }}"] *****************
ok: [127.0.0.1] => {
    "msg": "ID is 1234567"
}

TASK: [ocean | debug msg="IP is {{ my_droplet.droplet.ip_address }}"] *********
ok: [127.0.0.1] => {
    "msg": "IP is 111.222.333.444"
}

PLAY RECAP ********************************************************************
127.0.0.1                  : ok=4    changed=0    unreachable=0    failed=0

```

新たに Droplet が作られることはない。もしマッチしない場合は新規に作られる。

# 参考

* [Ansible - DigitalOcean](http://docs.ansible.com/digital_ocean_module.html)
* [DigitalOcean API v2] (https://developers.digitalocean.com/documentation/v2/)
* [DigitalOcean dopy](http://devo.ps/blog/announcing-dopy-with-digitalocean-api-v2/)