Apache LibcloudでGoogle Compute Engineを使う

# Apache LibcloudでGoogle Compute Engineを使う

## 環境

```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.12.4
BuildVersion:	16E195
$ python3 --version
Python 3.6.1
```

## Google Compute Engineの認証情報を取得する

1. Google Developers Consoleを開く
2. プロジェクトを選択する
3. Compute Engine APIを有効にする
    a. サイドバーから"API Manager"を選択し、"認証情報"をクリック
    b. ダッシュボードで"APIを有効にする"をクリック
    c. API一覧から"Compute Engine API"をクリック
    d. "APIを有効にする"をクリック

4. 認証情報を作成する
    a. API Managerのサイドバーから"認証情報"をクリック
    b. "認証情報を作成"をクリックし、"OAuth クライアントID"をクリック
    c. アプリケーションの種類から"その他"を選択し、クライアントの名前を入力して、作成をクリック
    d. 表示された"クライアントID"と"クライアント シークレット"を保存しておく

## Apache Libcloudを使ったコードのサンプル

Apache LibcloudのドキュメントとGoogle Compute EngineのAPIリファレンス、Compute Engineのコンソールから"同等の REST またはコマンドライン"を参照した

Apache Libcloudをインストール

```
$ pip3 install apache-libcloud
```

Google Compute Engine を操作するドライバを作成する

```
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

# 取得した認証情報とプロジェクトIDを設定する
client_id = '<client id>'
client_secret = '<client secret>'
project = '<project name>'

# driverを作成
ComputeEngine = get_driver(Provider.GCE)
driver = ComputeEngine(client_id, client_secret, project=project)
```

一覧系のメソッド

```
# イメージの一覧
for image in driver.list_images():
    print(image.name)

# サイズの一覧
for size in driver.list_sizes():
    print(size.name)
    
# ロケーション(リージョン)の一覧
for location in driver.list_location():
    print(location.name)
# または
for zone in driver.ex_list_zones():
    print(zone.name)

# ファイアウォールの一覧
for firewall in driver.ex_list_firewalls():
    print(firewall.name)
```

ファイアウォールのルールを作成する

```
firewall = driver.ex_create_firewall(
    'allow-http',  # ルール名
    [{
        'IPProtocol': 'tcp',  # 'tcp'または'ip'
        'ports': ['80'],  # 許可するポートのリスト
    }],
    network='default',  # 'default'ネットワークにこのファイアウォールを追加する
)
```

ノード(インスタンス)を作成する

```
node = driver.create_node(
    'test-node',  # インスタンス名
    'f1-micro',  # マシンタイプ名
    'ubuntu-1610-yakkety-v20170330',  # イメージ名
    location='asia-northeast1-a',  # ゾーン名
    ex_network='default',  # 初期値が'default'なので書かなくても良い
)
```

インスタンスにSSH認証鍵を追加する
インスタンス作成時にSSH認証鍵を追加するにはfingerprintを除いたnew_metadataを`ex_metadata=new_metadata`として引数に加える
注: すでにSSH認証鍵がインスタンスに設定されている場合、上書きや削除、保持に関してやや複雑なので割愛

```
node = driver.ex_get_node('test-node')  # インスタンスを取得
metadata = node.extra.get('metadata')  # インスタンスのメタデータを取得
fingerprint = metadata['fingerprint']  # インスタンスのメタデータの固有ID
new_metadata = {
    'items': [
        {
            'key': 'sshKeys',
            'value': '[USERNAME]:ssh-rsa [KEY_VALUE] [USERNAME]',  # ':'以降は`$ cat ~/.ssh/<id_rsa>.pub`の結果を貼り付ける
        },
    ],
    'fingerprint': fingerprint,
}
driver.ex_set_node_metadata(node, metadata) 
```

複数のインスタンスを作成する

```
nodes = driver.ex_create_multiple_nodes(
    'test-node',  # インスタンス名のプレフィクス (例: test-node-1, test-node-2, test-node-3)
    'f1-micro',  # マシンタイプ名
    'ubuntu-1610-yakkety-v20170330',  # イメージ名
    3,  # 作成するインスタンスの数
    location='asia-northeast1-a',  # ゾーン名
    ex_network='default',  # 初期値が'default'なので書かなくても良い
)
```

インスタンスを削除する

```
driver.destroy_node('test-node')  # インスタンス名を渡す
# または
node.destroy()
```

複数のインスタンスを削除する

```
driver.ex_destroy_multiple_nodes(
    ['test-node-1', 'test-node-2', 'test-node-3']
)
```


## 参考

* [Google Compute Engine Driver Documentation — Apache Libcloud 0.14.0-dev documentation](http://libcloud.readthedocs.io/en/latest/compute/drivers/gce.html)
    * Apache LibcloudのGCPに関するドキュメント
* [API Reference  |  Compute Engine  |  Google Cloud Platform](https://cloud.google.com/compute/docs/reference/latest/)
    * GCPのAPI一覧、
* [インスタンスの作成と起動  |  Compute Engine ドキュメント  |  Google Cloud Platform]( https://cloud.google.com/compute/docs/instances/create-start-instance?hl=ja)
    * コンソール、GCLOUD、APIの使用方法が参照できる。APIではGoogle公式クライアントライブラリの使い方が書いてある
* [ネットワークとファイアウォールの使用  |  Compute Engine ドキュメント  |  Google Cloud Platform]( https://cloud.google.com/compute/docs/networking?hl=ja)
    * GCPではファイアウォールはインスタンス毎ではなくネットワークに対して設定する
      インスタンスはネットワークに所属し、ネットワークのファイアウォールのルールに従って通信を行う