{Lambda}チュートリアル: Amazon S3 トリガーを使用して Lambda 関数を呼び出す

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html
https://dev.classmethod.jp/articles/tsnote-lambda-s3-event-trigger/

-- 1. コマンド等のインストール

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

aws --version

-- 1.2 jqインストール
sudo yum -y install jq


-- 2. S3 バケットを作成する

aws s3 mb s3://bucket123

aws s3 ls

-- 3. テストファイルアップロード

echo test01 > test01.txt

aws s3api put-object --bucket bucket123 --key test01.txt --body test01.txt --content-type text/plain

aws s3 ls s3://bucket123 --recursive


-- 4. IAMロール作成
vim role01.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

aws iam create-role \
--role-name role01 \
--assume-role-policy-document file://role01.json


-- 5. ポリシーをロールにアタッチ
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AWSLambdaExecute \
--role-name role01

 

-- 6. Lambda関数作成

vim test.py

import json
import urllib.parse
import boto3

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e


chmod 755 test.py
zip test.zip test.py

aws lambda create-function \
--function-name func01 \
--zip-file fileb://test.zip \
--handler test.lambda_handler \
--runtime python3.7 \
--role arn:aws:iam::999999999999:role/role01

 


aws lambda list-functions | grep func01

aws lambda get-function --function-name func01

-- 7. Lambda関数に権限を追加する

aws lambda add-permission \
--function-name func01 \
--statement-id s3 \
--action lambda:InvokeFunction \
--principal s3.amazonaws.com \
--source-arn arn:aws:s3:::bucket123 \
--source-account 999999999999


aws lambda get-policy \
--function-name func01 | jq -r .Policy  | jq .


-- 8. イベント通知を作成

aws s3api get-bucket-notification-configuration \
--bucket bucket123

vim a.json
{
"LambdaFunctionConfigurations": [
    {
        "Id": "en01",
        "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:func01",
        "Events": [
            "s3:ObjectCreated:Put"
        ],
        "Filter": {
            "Key": {
                "FilterRules": [
                    {
                        "Name": "Prefix",
                        "Value": ""
                    },
                    {
                        "Name": "Suffix",
                        "Value": ""
                    }
                ]
            }
        }
    }
  ]
}


aws s3api put-bucket-notification-configuration \
--bucket bucket123 \
--notification-configuration file://a.json


※S3イベント通知の設定前にリソースベースポリシーを設定しないと下記エラーがでる

An error occurred (InvalidArgument) when calling the PutBucketNotificationConfiguration operation: 
Unable to validate the following destination configurations

 


-- 9. Lambda 関数をテストする

aws lambda invoke \
--function-name func01 \
--payload '{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-west-2",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "bucket123",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "test01.txt",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}' \
response.txt \
--cli-binary-format raw-in-base64-out

cat response.txt


-- 10. S3 トリガーでテストする


echo test02 > test02.jpg

aws s3api put-object --bucket bucket123 --key test02.jpg --body test02.jpg --content-type image/jpeg

aws s3 ls s3://bucket123 --recursive


-- 11. クリーンアップ

 


-- Lambda関数の削除
aws lambda get-function --function-name func01
aws lambda delete-function --function-name func01


-- ロールの削除
aws iam list-roles | grep role01

aws iam detach-role-policy \
--role-name role01 \
--policy-arn arn:aws:iam::aws:policy/AWSLambdaExecute \

aws iam delete-role --role-name role01

-- S3バケットの削除
aws s3 ls
aws s3 rb s3://bucket123 --force