PythonでAWS操作(主にboto3利用)

概要

AWSでちまちま処理を実行する機会があったので、Pythonのboto3を使ってみる。

@CretedDate 2016/12/15
@Versions python3.5, boto3 1.4.2, awscli 1.11.28

前提条件

Python3が入っていて、AWSのアカウントを持っていること。

インストール

AWSをPythonから動かせるAWS Command Line InterfaceBoto3を入れる。

$ pip install boto3
$ pip install awscli

AWSに繋ぐ設定

IAM Management Consoleからaws_access_keyとaws_secret_access_keyを作る。

作り方はこのへんとかに書いてある。

ユーザを作成してキーをダウンロードしたら、先ほど入れたawscliでconfigureしてkeyの内容を設定する。

$ aws configure

AWS Access Key ID [None]: ここにAccess Key Idを入れる
AWS Secret Access Key [None]: ここにSecret Access Keyを入れる
Default region name [None]: ap-northeast-1
Default output format [None]: json

これで ~/.aws/credentials に設定情報が出力され、boto3からAWSが操作できる状態になった。

S3の操作

簡単なところで、S3の操作から行ってみる。事前にコンソールから1つbucketを作っておくこと。また、ユーザにS3の権限を与えておくこと。

import boto3
s3 = boto3.resource('s3')

# bucket名は仮に下記の名前にしておく
bucket_name = 'jp.mwsoft.example'

# regionがちゃんと設定されているか確認
boto3.DEFAULT_SESSION
  #=> Session(region_name='ap-northeast-1')

# bucketの一覧を確認
for bucket in s3.buckets.all():
    print(bucket)
      #=> jp.mwsoft.example

# 指定のbucketを取得
bucket = s3.Bucket('jp.mwsoft.example')

# 作成日
bucket.creation_date
  #=> datetime.datetime(2016, 8, 19, 4, 54, 56, tzinfo=tzutc())

# ACL
bucket.Acl().grants
  #=> [{'Grantee': {'DisplayName': 'info',
   'ID': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
   'Type': 'CanonicalUser'},
   'Permission': 'FULL_CONTROL'}

# ファイルを置く(事前にhello.txtというファイルを作っておく)
bucket.upload_file('hello.txt', Key='tmp/hello.txt')

# ファイルの一覧を見る
for key in bucket.objects.all():
    print(key)
      #=> s3.ObjectSummary(bucket_name='jp.mwsoft.example', key='tmp/hello.txt')

# S3上のファイルをダウンロードする
bucket.download_file(Key='tmp/hello.txt', Filename='local_hello.txt')

# S3上のファイルをwriteする
with open('local_hello.txt', 'wb') as data:
    bucket.download_fileobj('tmp/hello.txt', data)

ec2の起動と終了

あまりお金がかからないようにnanoインスタンスを立ち上げて、そこにsshでファイルを配置して落とすまでを実行してみる。

試しにDryRunで実際には起動しないけど、この設定で立ち上げられるかを確認してみる。

ec2 = boto3.resource('ec2')

ec2.create_instances(DryRun=True, ImageId='ami-374db956', MinCount=1, MaxCount=1)
  #=> ClientError: An error occurred (InvalidParameterCombination) when calling the RunInstances operation: Non-Windows instances with a virtualization type of 'hvm' are currently not supported for this instance type.

エラーになった。HVM Instance Store 64-bitのAMI IDを指定したのだけど、instance type的に対応してないらしい。

上記ではインスタンスタイプは指定してないけど、デフォルトだと m1.small になるそうだ。だいぶレガシーな設定だ。t2.nanoでやってみる。

ec2 = boto3.resource('ec2')

ec2.create_instances(DryRun=True, ImageId='ami-374db956', MinCount=1, MaxCount=1, InstanceType='t2.nano')
  #=> ClientError: An error occurred (DryRunOperation) when calling the RunInstances operation: Request would have succeeded, but DryRun flag is set.

こちらでは成功した。ClientErrorとなっているが、エラー内容は「Request would have succeeded, but DryRun flag is set.」(リクエスト的には成功したけどDryRunフラグ立ってるからやめといた)になっている。

大丈夫そうなので立ち上げてみる。nanoなら1時間あたり1円もかからないので気兼ねなく扱える。

ec2 = boto3.resource('ec2')
instance = ec2.create_instances(ImageId='ami-374db956', MinCount=1, MaxCount=1, InstanceType='t2.nano')

instance
  #=> [ec2.Instance(id='i-xxxxxxxxxxxxxx')]

立ち上げたところで、状態を確認してみる。

# インスタンスの一覧
for instance in ec2.instances.all():
    print(instance, instance.state)
      #=> ec2.Instance(id='i-xxxxxxxxxxxxxx') {'Name': 'running', 'Code': 16}

# volume
for volume in ec2.volumes.all():
    print(volume)

# ACL
for acl in ec2.network_acls.all():
    print(acl)

# instance type
instance.instance_type
  #=> 't2.nano'

# IPアドレス
instance.public_ip_address
  #=> 'xx.xxx.xxx.xx'

# 状態
instance.state
  #=>{'Code': 16, 'Name': 'running'}

# 起動時間
instance.launch_time

# Filterを使ったインスタンス取得(runningのみ取得してみる)
instances = ec2.instances.filter(
    Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
for instance in instances:
    print(instance)

AWSのWeb画面から見ても起動されていることが確認できる。(リージョンが違うと画面に出てこないので注意)

確認できたら一旦終了。

# 停止する
instance.stop()
instance.state
  #=> {'Code': 80, 'Name': 'stopped'}

# もう使わなくなったらterminateしてしまう(デデンデンデデン)
instance.terminate
instance.state
  #=> {'Code': 48, 'Name': 'terminated'}