boto3 (AWS SDK for Python) メモ


新しい boto3 を使ってみる。参考 → http://boto3.readthedocs.org/en/latest/

インストール

pipで。Verは0.0.6。

$ sudo pip install boto3
$ sudo pip list | grep boto3
boto3 (0.0.6)

EC2インスタンス情報取得

$ aws ec2 describe-instances 的なのを再現。

>>> import boto3
>>> client = boto3.client('ec2')
>>> response = client.describe_instances()
>>> type(response)
<type 'dict'>

dict型で返ってくる。そのままでも良いけど、JSON化してみるとエラーとなる。

>>> import json
>>> res_json = json.dumps(response)

TypeError: datetime.datetime(2014, 4, 4, 11, 34, 13, tzinfo=tzutc()) is not JSON serializable

ちょっと調べると、datetime型に対応してないらしく、bson(Binary JSON)とやらを使えばいけるっぽい。

ただ、Macだとbsonのみ入れるとダメっぽいので、pymongoとやらを入れる。

$ sudo pip install pymongo
>>> from bson import json_util
>>> res_json = json.dumps(response, default=json_util.default)
>>> type(res_json)
<type 'str'>

そのままだと全インスタンスの情報なので、Filtersで絞る。
InstanceIDで絞った場合。

>>> response = client.describe_instances(Filters=[{'Name':'instance-id','Values':['i-XXXXXXXX']}])

Filterを変数化して、Tag名で絞った場合。

>>> f = [{'Name':'tag-value', 'Values':['XXXXXXXX']}]
>>> response = client.describe_instances(Filters=f)

EC2インスタンス操作

instanceオブジェクトに対して起動停止等を実施する。
まずは、instanceオブジェクトをInstanceID指定で取得してみる。

>>> import boto3
>>> ec2 = boto3.resource('ec2')
>>> instance = ec2.Instance('i-XXXXXXXX')
>>> instance.private_ip_address
"10.X.X.X"

もう一つはInstancesCollectionから取得してみる。例えばタグ名から。
ただ、全instanceをループするので多いほど時間が掛かる。

>>> import boto3
>>> ec2 = boto3.resource('ec2')
>>> tag_name = "TAG_NAME"
>>> instance = [i for i in ec2.instances.all() for t in i.tags if t["Value"] == tag_name][0]
>>> instance.private_ip_address
"10.X.X.X"

いずれかの方法で取得されたinstanceオブジェクトに対して操作する。
インスタンス停止。Waitが可能。自前ループが不要となった。

>>> instance.stop()
{u'StoppingInstances': [{u'InstanceId': 'i-XXXXXXXX', u'CurrentState': {u'Code': 64, u'Name': 'stopping'}, u'PreviousState': {u'Code': 16, u'Name': 'running'}}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA'}}
>>> instance.wait_until_stopped()
>>> instance.state
{u'Code': 80, u'Name': 'stopped'}

インスタンス起動。こちらもWait可能。

>>> instance.start()
{u'StartingInstances': [{u'InstanceId': 'i-XXXXXXXX', u'CurrentState': {u'Code': 0, u'Name': 'pending'}, u'PreviousState': {u'Code': 80, u'Name': 'stopped'}}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA'}}
>>> instance.wait_until_running()
>>> instance.state
{u'Code': 16, u'Name': 'running'}