初心者向け『チュートリアル: Amazon S3 で AWS Lambda を使用する』をやってみた

概要

大阪オフィスのちゃだいんです。

手を動かして学ぶために、公式ドキュメントのチュートリアルをやってみました。

今回は、Lambdaチュートリアル第2弾です。内容は以下のものです。

チュートリアル: Amazon Simple Queue Service で AWS Lambda を使用する

バケットにアップロードされる各画像ファイルのサムネイルを作成するとします。オブジェクトの作成時に Amazon S3 が呼び出すことができる Lambda 関数 (CreateThumbnail) を作成できます。その後、Lambda 関数はソースバケットから画像オブジェクトを読み取り、ターゲットバケットにサムネイル画像を作成できます。

前提条件

AWS CLIが使用できる環境で行ってます。

早速やってみた

1.実行ロールを作成する

  • lambda関数にAWSリソースに対して実行権限を付与するIAMロールを作成します。

  • マネジメントコンソールを開き、IAMの画面へ移動します。

  • Roleページにて、ロールの作成を選択します。

  • Lambdaの中からAWSLambdaExecute.を選び、以下のように作成しました。

2.バケットを作成しサンプルオブジェクトをアップロードする

  • バケットを作成し、オブジェクトをアップロードするための手順を行います。

  • S3のコンソール画面を開き、新しくバケットを作成します。

  • ソースバケットとターゲットバケットは以下の名前で作成しました。

  • ソースバケットには以下のSpiceCurry.jpg画像をアップロードします。

  • ちなみにこんな画像です。(とても美味しかったです)

3.関数を作成する

  • ここではデプロイパッケージを作成し、アップロードして、Lambda関数を作成します。

  • 言語はPythonでやりたいので、下記ページのPython 3の項目を参考にします。

サンプル Amazon Simple Storage Service 関数コード - AWS Lambda

以下のコード例では、Amazon S3 イベント入力を受け取り、含まれるメッセージを処理します。ソースバケットのイメージのサイズを変更し、ターゲットバケットに出力を保存します。

  • どうやら仮想環境で作成した方が良さそうなので、下記エントリを参考にデプロイパッケージ作成するための環境として、まずEC2を立ち上げます。

Amazon Linux2にvenv/Anacondaで隔離されたPython3環境を構築

  • 立ち上げたEC2にSSHで接続します。

  • メインのコードはドキュメントにあるものをそのままCreateThumbnail.pyというファイル名で作成します。

  • このAMI``ではPythonのバージョンは以下の通りでした。

$ python --version
Python 2.7.16
  • 今回のサンプルコードはPython 3と書いてあったので、Python 3を入れてみます。
sudo yum install -y python3
  • そして仮想環境とやらを作成します。ドキュメントではVirtualenvとなってますが、Python3の標準ライブラリであるvenvを使います。
$ python3 -m venv test-venv
$ source test-venv/bin/activate
  • そうすると頭に(test-env)が付いたので、仮想環境に入ることができました。
(test-venv) [ec2-user@ip-*********** ~]$
  • 仮想環境にライブラリをインストールします。(ドキュメントと同じ)
$ pip install pillow
$ pip install boto3
  • lib および lib64 サイトパッケージの内容を .zip ファイルに追加します。(ドキュメントと同じ)
$ cd $VIRTUAL_ENV/lib/python3.7/site-packages
$ zip -r ~/CreateThumbnail.zip .
  • .zip ファイルに Python コードを追加します。(ドキュメントと同じ)
$ cd ~
$ zip -g CreateThumbnail.zip CreateThumbnail.py
  • 作成した.zipファイルをローカルにコピーします。
$ scp -i .ssh/testkey.pem ec2-user@**********:~/CreateThumbnail.zip ~/desktop
  • create-functionコマンドを使用してLambda関数を作成します。
$ aws lambda create-function --function-name CreateThumbnail \
--zip-file  fileb://~/desktop/CreateThumbnail.zip 
--handler CreateThumbnail.handler \
--runtime python3.7 --timeout 30 --memory-size 1024 \
--role arn:aws:iam::123456789012:role/lambda-s3-role \
--region ap-northeast-1

4.関数をテストする

  • サンプルのS3イベントデータを使用して、手動でLambda関数を呼び出してみます。

  • ドキュメントに記載のInputFile.txtsourebucketHappyFace.jpgのみを変更して作成します。

{
  "Records":[  
    {  
      "eventVersion":"2.0",
      "eventSource":"aws:s3",
      "awsRegion":"us-west-2",
      "eventTime":"1970-01-01T00:00:00.000Z",
      "eventName":"ObjectCreated:Put",
      "userIdentity":{  
        "principalId":"AIDAJDPLRKLG7UEXAMPLE"
      },
      "requestParameters":{  
        "sourceIPAddress":"127.0.0.1"
      },
      "responseElements":{  
        "x-amz-request-id":"C3D13FE58DE4C810",
        "x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
      },
      "s3":{  
        "s3SchemaVersion":"1.0",
        "configurationId":"testConfigRule",
        "bucket":{  
          "name":"190711lambdatest",
          "ownerIdentity":{  
            "principalId":"A3NL1KOZZKExample"
          },
          "arn":"arn:aws:s3:::190711lambdatest"
        },
        "object":{  
          "key":"SpiceCurry.jpg",
          "size":1024,
          "eTag":"d41d8cd98f00b204e9800998ecf8427e",
          "versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko"
        }
      }
    }
  ]
}
  • 実際にやってみました。
$ aws lambda invoke --function-name CreateThumbnail --invocation-type Event \
--payload file://inputfile.txt outputfile.txt --region ap-northeast-1

{
    "StatusCode": 202
}
  • 一応成功したっぽいです。CloudWatchのログを見てみましょう。

  • Errorが出てないのでいけたっぽいです。実際にバケットを見てみましょう。

  • ファイルサイズが小さくなったサムネイル画像がターゲットバケットにちゃんと入ってました。

5.S3の設定とイベントの発行

  • Lambda 関数のアクセスポリシーに、この関数の呼び出しを Amazon S3 に許可するアクセス権限を追加します。追加前は下図のように何も入ってません。

  • Lambda CLI add-permission コマンドを実行します。ドキュメントで赤文字の部分を変更してます。
aws lambda add-permission --function-name CreateThumbnail --principal s3.amazonaws.com \
--statement-id 190711lambdatest-spicecurry --action "lambda:InvokeFunction" \
--source-arn arn:aws:s3:::190711lambdatest \
--source-account 123456789012 \
--region ap-northeast-1
  • すると、Lambdaコンソールにて関数ポリシーが追加されました。

  • オブジェクト作成イベントをLambdaに発行するように、S3のソースバケットで通知設定を追加します。(わかりづらかったので日本語から英語に切り替えてます)

  • 設定が完了すると、Lambdaコンソールにもトリガー側にS3が追加されてました。

6.セットアップをテストする

  • いよいよ本番です。これでS3のリソースバケットに画像をアップロードしたら、サムネイル画像がターゲットバケットに作成されるはず。

  • ではVeryHotCurry.jpgをアップロードしてみます。

  • ちなみにまたしてもカレーの写真です。(※見た目によらず相当辛いので注意!!)

  • 結果、ちゃんとターゲットバケットにサムネイル画像が作成されてました!めでたしめでたし。

感想

前回よりももう少しわかりやすいサービスっぽい機能が実現できたので、ちょっとテンション上がりました。

誰かのお役に立てば幸いです。それではまた、大阪オフィスのちゃだいんでした。