Pythonについて vol08.Boto3


今回のテーマはAWS SDK for PythonであるBoto3です。
この連載の根幹となるテーマです。(あと数回ありますが、それらはおまけです。)

Boto3にはマニュアルというかリファレンスがありますので、詳細はそちらをご覧ください。
https://boto3.readthedocs.io/en/latest/

インストールは、pip install boto3で完了です。
使う時は、import boto3でインポートしておきます。

Boto3を使う時は認証が必要です。
通常のアクセスキーを使うのであれば、~/.aws/の下に、configかcredentialsにアクセスキー、シークレットキーを書いておけばOKです。

~/.aws/config or ~/.aws/credentials
[default]
aws_access_key_id=foo
aws_secret_access_key=bar

configとcredentialsで書き方が微妙に違うのでご注意ください。(defaultは上記の通り同じです)
ご参考:https://boto3.readthedocs.io/en/latest/guide/configuration.html

Assume RoleをBoto3で使うこともできます。が、便利な使い方はSTSが使えるIAMロールが付与されているEC2インスタンスで実行する必要があります。(Appendix1に書いておきます。)
なので、自分の場合はSTSが実行できるサーバまでSSHでSTSを実行して、認証情報を取得するクラス(get_sts_assumerole.py:Gsa)を作ってそれを使っています。

取ってきた認証情報は以下のように使います。

import boto3
from get_sts_assumerole import Gsa

# STS設定
creds=Gsa().get_sts_assumerole('mig')
session = boto3.Session(
    aws_access_key_id=creds[0],
    aws_secret_access_key=creds[1],
    aws_session_token=creds[2],
)

上記で作ったsessionを使ってコマンドを打っていきます。
先のboto3のリファレンスに各サービス毎のページがあります。例えば、
EC2:https://boto3.readthedocs.io/en/latest/reference/services/ec2.html
RDS:https://boto3.readthedocs.io/en/latest/reference/services/rds.html
などです。
目的のサービスのページを見ると、そのサービスで利用できるメソッドが確認できます。

例えば、EC2のインスタンス情報を表示するdescribe_instancesメソッドを利用して、

ec2 = session.client('ec2') # ec2クライアントを作成
response = ec2.describe_instances()

とすると、instanceの情報がresponseに入ります。

responseにはJSON形式っぽい何かで情報が入っているので、 # 前回の記事参照
目的のものだけを抜き出すために、

for res in response['Reservations']
    print(res['Instances'][0]['InstanceId'])

とやったり(標準出力に出力)

with open('result.json', 'w') as f:
    json.dump(response, f, default=json_serial, indent=4)

とやったり(ファイル書き出し)します。※json_serialについては前回の記事参照

Boto3というか、AWS CLIには一回で出せる出力量が決まっているものがあります。
そういう時はNextTokenを使って、複数回取得します。

例えば、先ほどのdescribe_instancesであれば、

response = ec2.describe_instances(
    MaxResults=100,
    NextToken=''
)

と実行します。続き(101個目以降)がある場合はresponse['NextToken']に続きを取得するためのtokenが入ります。
これを使って以下のようなwhile分でループをまわして、レスポンスを取得します。

ec2 = session.client('ec2')
token = ''

while token is not None:
    response = ec2.describe_instances(
        MaxResults=10,
        NextToken=token
    )
    for res in response['Reservations']:
        print(res['Instances'][0]['InstanceId'])

    if 'NextToken' in response:
        token = response['NextToken']
    else:
        token = None

MaxResultsとNextTokenはサービスによって呼び方が変わるみたいです。
RDSだとMaxRecordsとMarkerのようです。

Appendix

Boto3から直接STSを実行して認証情報を取得する時は、以下のようにconfig/credentialsを書いておけば良いみたいです。

~/.aws/credentials
[development]
aws_access_key_id=foo
aws_access_key_id=bar
# 原文ママ。2行目は aws_secret_access_keyだと思われる。
~/.aws/config
[profile crossaccount]
role_arn=arn:aws:iam:...
source_profile=development