Windows で python boto3 を使って AWS の REST API を叩くまで

例として公式ドキュメントの下記サンプルコード、

リージョン名と AZ 名を列挙するところを目標にする。特に Python コードを書く部分でハマリポイントがちらちらある。

前提

  • AWS の基礎知識がある(管理コンソールをいじってアクセスキーを発行できる)
  • Windows で Python を使う基礎知識がある(Python や pip のインストールができる)
  • Python 3.6.1
  • boto3 1.7.35

コード

# coding: utf-8

import os
import boto3

# キーを生でファイル等に保存するのは危ないので
# 環境変数から読み込むようにする.
# (使う度に環境変数にキーをセットしてね)
ACCESS_KEY = os.environ['AWS_ACCESS_KEY']
SECRET_KEY = os.environ['AWS_SECRET_KEY']

# ここでは東京リージョンを指定している.
USING_REGION_NAME = 'ap-northeast-1'

# SSL 証明書ファイルのパス.
# 今回は面倒くさいので使わない. 使わない, を意味する False を.
USE_SSL = False

ec2 = boto3.client(
    'ec2',
    aws_access_key_id=ACCESS_KEY,
    aws_secret_access_key=SECRET_KEY,
    region_name=USING_REGION_NAME,
    verify=USE_SSL
)

# Retrieves all regions/endpoints that work with EC2
response = ec2.describe_regions()
print('[Regions]')
for region in response['Regions']:
    print(region)

# Retrieves availability zones only for region of the ec2 object
response = ec2.describe_availability_zones()
print('[AZs]')
for az in response['AvailabilityZones']:
    print(az)

実行結果

$ python boto3_test.py
[Regions]
{'Endpoint': 'ec2.ap-south-1.amazonaws.com', 'RegionName': 'ap-south-1'}
...

[AZs]
{'State': 'available', 'Messages': [], 'RegionName': 'ap-northeast-1', 'ZoneName': 'ap-northeast-1a'}
...

必要な作業

(1) Python3 のインストール

割愛。

(2) boto3 のインストール

pip コマンドで一発。

$ pip install boto3

気になる人は venv 等を使って仮想環境で作業すること(仮想環境自体の解説は割愛)。

Q: (2) で応答が返ってきません

Ans: プロキシサーバ環境下の場合はその設定も行う。

$ set HTTPS_PROXY=https://(PROXY_SERVER_IP):(PORT)
$ set HTTP_PROXY=http://(PROXY_SERVER_IP):(PORT)
$ pip install boto3

Q: (2) で SSLError が出ます

Ans: てっとり早くやりたいなら以下のおまじないを使う。

$ pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org boto3

やってることは、SSL 通信において信頼済ホストに「pip パッケージの配布元」を追加する、というもの。

参考: python - pip install fails with "connection error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)" - Stack Overflow

(3) AWS 管理コンソールでアクセスキーを取得

ポリシーやら何やら細かい話は割愛。

必要なのは「アクセスキー(Access Key)」と「シークレットキー(Secret Key)」の二つ。なおシークレットキーはアクセスキー新規時に一度のみ表示されるので、それをコピペして安全に保存しておく。

(4) 上記スクリプトを書く

たとえば boto3_test.py で保存する。

(5) 上記スクリプトをキーを設定した後、実行する

以下を実行する。

$ set AWS_ACCESS_KEY=(取得したアクセスキー)
$ set AWS_SECRET_KEY=(取得したシークレットキー)
$ python boto3_test.py

すると上記実行結果が得られるはず。

(余談) なぜキーを環境変数経由で設定させているかというと、セキュリティのため。キー情報をうっかり放置したままにしたり、どっかにアップ(特に GitHub 等に Push しちゃうケース)しちゃったりすると、悪用されて大変なことになる。このやり方ならキー情報を保存しない(ターミナルを閉じたら消える)ので安心。

Q: (5) で InsecureRequestWarning 警告が出ます

Ans: 無視すれば OK

上記スクリプトでは SSL 認証をしていない(verify=False)ので、その旨が傾向として表示されている。

D:\bin1\Python361\lib\site-packages\botocore\vendored\requests\packages\urllib3\connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)

(メモ) アクセスキーがおかしい場合

参考までにメモしておく。以下のようなエラーが出る。

$ python boto3_test.py
Traceback (most recent call last):
  File "boto3_test.py", line 28, in <module>
    response = ec2.describe_regions()
  File "D:\bin1\Python361\lib\site-packages\botocore\client.py", line 314, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "D:\bin1\Python361\lib\site-packages\botocore\client.py", line 612, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AuthFailure) when calling the DescribeRegions operation: AWS was not able to validate the provided access credentials

参考

おわりに

最低限動かすところはできた。

課題は SSL 部分で手抜きしていることか。本当はちゃんと証明書ファイルのパスを指定して認証するべき。