S3バケットの内容をLambda関数で読み込んでみる(Python)

Lambda関数からS3を操作する練習です。
S3にファイルをアップロードしたタイミングでLambda関数が実行されるように設定します。
アップロードされたタイミングで、バケット名やファイルの一覧を取得する関数を書いてみます。

S3バケットを作成する

「バケットを作成する」をクリックします。
S3 Management Console 2018-01-06 09-29-55.png

バケット名とリージョンを入力します。
S3 Management Console 2018-01-06 09-31-18.png

プロパティの設定は特に何もせずに「次へ」をクリックします。
次の「アクセス許可の設定」はユーザーに対する設定のみです。とりあえずそのまま「次へ」をクリックします。

S3 Management Console 2018-01-06 09-35-11.png

Lambdaにファイルをアップロードする

適当なファイルをアップロードしてみます。
S3 Management Console 2018-01-06 09-38-15.png

ドラッグアンドドロップでファイルのアップロードができます。
S3 Management Console 2018-01-06 09-39-58.png

「アップロード」をクリックします。
S3 Management Console 2018-01-06 09-41-26.png

以下のようにアップロードしたファイルが表示されます。
S3 Management Console 2018-01-06 09-42-26.png

IAMに権限を設定する

Lambdaを操作するIAMにS3へのアクセス権限を与えます。
IAM Management Console 2018-01-06 09-57-31.png

AmazonS3FullAccessポリシーはフルアクセス権を与えてしまうので、どのS3バケットにもアクセスできてしまうことには注意が必要です。今回はサンプルなのでFullAccessを与えますが、実運用に入る際は、インラインポリシーを設定してポリシーを絞るのがいいと思います。
IAM Management Console 2018-01-06 09-58-50.png

Lambda関数を作成する

設計図s3-get-object-pythonから作成します。
Lambda Management Console 2018-01-06 10-04-43.png

Lambda Management Console 2018-01-06 10-07-20.png Lambda Management Console 2018-01-06 10-07-37.png

boto3で何ができるかは本家のドキュメントをじっくり読むのがいいと思います。
ネットの情報は古くなってしまったものも多く、単純に真似するだけでは動かないものもありました。
「Boto 3 Docs documentation」
http://boto3.readthedocs.io/en/latest/reference/services/s3.html#client

こちらのサンプルはちゃんと動いてわかりやすかったです。
https://github.com/bloomberg/chef-bcs/blob/master/cookbooks/chef-bcs/files/default/s3-example-boto3.py

以下のような関数を作ってみました。

  • S3バケット名を取得する
  • S3バケット内のファイルの一覧を取得する
  • S3バケット内のファイルの詳細情報を表示する

などを行っています。

from __future__ import print_function

import json
import urllib
import boto3

print('Loading function')

#http://boto3.readthedocs.io/en/latest/reference/services/s3.html#client
s3 = boto3.client('s3')


def lambda_handler(event, context):


    bucket_name = event['Records'][0]['s3']['bucket']['name']
    print('==== bucket information =====')
    print(bucket_name)
    print('=============================')


    #https://github.com/bloomberg/chef-bcs/blob/master/cookbooks/chef-bcs/files/default/s3-example-boto3.py
    print('==== your bucket list ====')
    buckets = s3.list_buckets()
    for bucket in buckets['Buckets']:
        print(bucket.get('Name'))

    print('==== file list in bucket ====')
    # https://github.com/boto/boto3/issues/134
    AWS_S3_BUCKET_NAME = 'example.read.000'
    s3_resource = boto3.resource('s3')
    bucket = s3_resource.Bucket(AWS_S3_BUCKET_NAME)
    result = bucket.meta.client.list_objects(Bucket=bucket.name, Delimiter='/')
    for o in result.get('Contents'):
        print(o.get('Key'))


    print('==== file details ====')
    # https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UsingObjects.html
    GET_OBJECT_KEY_NAME = 'sample.png'
    object = s3.get_object(Bucket=AWS_S3_BUCKET_NAME, Key=GET_OBJECT_KEY_NAME)
    print('ContentType ->' + str(object.get('ContentType')))
    print('ContentLength ->' + str(object.get('ContentLength')))


    print('==== uploaded file ====')
    for rec in event['Records']:
        print(rec['s3']['object']['key'])
    print('=============================')

    print("Received event: " + json.dumps(event, indent=2))

テストを実行すると以下のようなログが表示されます。

START RequestId: bdbee72e-f28b-11e7-a401-0d0509334621 Version: $LATEST
==== bucket information =====
sourcebucket
=============================
==== your bucket list ====
example.read.000
learnjs.benrady.com
==== file list in bucket ====
sample.png
sample2.png
==== file details ====
ContentType ->image/png
ContentLength ->82361
==== uploaded file ====
HappyFace.jpg
=============================

S3にオブジェクトをプットしても同じように関数が実行されます。

+ Recent posts