aliyun-python-sdkを利用して、イメージからインスタンスを作成する #Python #Image #サーバ作成

## はじめに
作成したサービスを市場に公開するために、クラウドサーバを利用することが当たり前になっています。

個人的には、AWS・GCPと触れて、世界トップ3のIaaSプロバイダーであることから
「[AlibabaCloud](https://jp.alibabacloud.com/about?spm=a21mg.8121077.1209376.dcube3.36e53e13zn9vEo)」
を見ていました。

お恥ずかしながら、調査するまでは、結構軽視していましたが、
サーバ・データベース・ドメインなど、展開はされており、
AWSやGCPと遜色なく使えているので、クラウドサーバの選択肢として持っても良いです。

そこで、イメージからインスタンスを作成することをAPIから作成してみました。

ちなみに内容みたことあると思った人は、1年前ぐらいに書いたものをQiitaに転機したものになります。

- http://hirontan.hatenablog.com/entry/2018/06/23/145228

### 実行環境
- CentOS 6.8
- Python 2.7 → v3あることあとで気づきました

### 実行準備
```
$ pip install aliyun-python-sdk-core
$ pip install aliyun-python-sdk-ecs
→必要なライブラリをインストール
$ pip install logging
$ pip install retry
$ pip install argparse
```

### 実行
##### 実行内容
事前に `Image` を作成して、インスタンスを作成する。
ミニマムのサーバリソースで同じセキュリティグループで同じサーバ名で作成していきたかったため、利用しました。
もちろん、UIでインスタンス数指定してもちろん複数構築は可能です。
ただ、また増設するときに必要になるので、書きました。
あと、オートスケーリングすれば。。。との話は置いておきます。

##### ソースコード
- https://github.com/hirontan/aliyuncli


```(python)
# -*- coding: utf8 -*-
#!/usr/bin/env python

import json
import argparse
from retry import retry
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkecs.request.v20140526 import CreateInstanceRequest

def acs_client(api_key, api_access_key):
  return AcsClient(
    api_key,
    api_access_key,
    region_id
  );

@retry(tries=4, delay=5, backoff=2)
def request_cli(req):
  status, headers, body = clt.implementation_of_do_action(req)
  print('[ status: ' + str(status) + ' ] [ headers: ' + str(headers) + ' ] [ body: ' + str(body) + ' ]')
  if status != 200:
    raise('[ status: ' + str(status) + ' ] [ headers: ' + str(headers) + ' ] [ body: ' + str(body) + ' ]')
  json_body = json.loads(body)
  return status, json_body

def create_instance():
  req = CreateInstanceRequest.CreateInstanceRequest()
  req.set_accept_format('json')
  req.add_query_param('RegionId', region_id)
  req.add_query_param('ImageId', image_id)
  req.add_query_param('InstanceType', 'ecs.t5-lc2m1.nano')
  req.add_query_param('SecurityGroupId', '[security_group_id]')
  req.add_query_param('InstanceName', '[instance_name]')
  req.add_query_param('InternetMaxBandwidthIn', '50')
  req.add_query_param('InternetMaxBandwidthOut', '50')
  req.add_query_param('VSwitchId', '[vswitch_id]')
  req.add_query_param('SystemDisk.Size', '20')
  req.add_query_param('KeyPairName', '[key_pair_name]')
  status, body = request_cli(req)

def main():
  init_logger()
  create_instance()

def init_args():
  parser = argparse.ArgumentParser(
             prog='aliyun_sample',
             usage='python aliyun_sample.py --region [ap-northeast-1] --key [api key] --access [api access key] --image [image id],
             description='description',
             epilog='end',
             add_help=True
           )
  parser.add_argument("-r", "--region", help="please set region id", type=str, default='ap-northeast-1')
  parser.add_argument("-k", "--key", help="please set api key", type=str, required=True)
  parser.add_argument("-a", "--access", help="please set api access key", type=str, required=True)
  parser.add_argument("-i", "--image", help="please set image id", type=str, required=True)
  return parser.parse_args()

if __name__ == '__main__':
  args = init_args()
  region_id = args.region
  image_id = args.image
  clt = acs_client(args.key, args.access)
  main()
```

##### コマンド
```
$ python aliyun_sample.py --region [ap-northeast-1] --key [api key] --access [api access key] --image [image id]
```

### やってみたことまとめ
- [OpenAPI Explorer](https://api.aliyun.com/)があり、プログラムは相当簡単にかけます。
- APIへリクエストが叩けない時があるので、リトライ処理入れる方が良い。（お決まり？）
- [OpenAPI Explorer](https://api.aliyun.com/) に記されている `do_action ` でリクエスト送るより、`ServerException ` の処理がある`do_action_with_exception` をリクエストを送る方が良い。
- 自分でStatus拾って実行考えたい場合は、`do_action_with_exception` ではなく `get_response` か `implementation_of_do_action` で実行する。

## 採用
- [旅行×価格という未踏領域！挑戦と自由が好きなデータサイエンティスト募集！](https://www.wantedly.com/projects/221459)
- [旅行×価格×テクノロジーの根幹を担うデータ基盤エンジニア募集](https://www.wantedly.com/projects/309675)