【Tips】AWS-CLIでAWS LambdaのイベントソースにS3を設定する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

お疲れの皆さま、もう一息で週末ですよ。城内です。
今回は、Lambdaの小ネタです。先日のAWS Summit Tokyo 2015でこの夏に東京リージョンに上陸すると発表があり、皆さまも心躍らせていることかと思います。

概要

内容としては、マネージメントコンソールで操作するところの、以下のアクションをAWS-CLIで実行するだけです。

lambda_01

なんだそれだけかと思うかもしれませんが、やってみなければ分からないこともあります(笑)
気になる方はぜひ続きを読んでくださいね。

内容

Lambdaファンクションの作成

まず、サンプルのLambdaファンクションを作成します。

$ aws lambda create-function --function-name "test-function" --runtime "nodejs" --role "arn:aws:iam::123456789012:role/lambda_basic_execution" --handler "index.handler" --zip-file "fileb://test-function.zip"
{
    "FunctionName": "test-function",
    "CodeSize": 23048,
    "MemorySize": 128,
    "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:test-function",
    "Handler": "index.handler",
    "Role": "arn:aws:iam::123456789012:role/lambda_basic_execution",
    "Timeout": 3,
    "LastModified": "2015-06-05T03:00:50.664+0000",
    "Runtime": "nodejs",
    "Description": ""
}

一応、確認コマンドはこんな感じですかね。アウトプットは上記と同じなので割愛します。

$ aws lambda list-functions | jq ".Functions[] | select(.FunctionName == 'test-function')"

S3イベントソースの追加

さて、ここからが本題です。
S3イベントソースの追加は、マネージメントコンソールからであれば、設定画面1ページの1アクションで設定できますが、AWS-CLIからはそうはいきません。

実行するコマンドは2つで、aws lambdaaws s3spiになります。マネージメントコンソールからは1アクションですが、AWS-CLIからだと、Lambda側の設定だけではなく、S3側の設定も必要になります。
ちなみに、aws lambda create-event-source-mappingというコマンドがありますが、これはDynamoDBとKinesisのストリーム用になり、S3は対象に含まれていません。

では、まずLambda側から設定します。
S3のイベントに対する権限設定です。ここでは、LambdaのInvokeFunctionの実行を許可しています。

$ aws lambda add-permission --function-name "test-function" --statement-id "s3-put-event" --action "lambda:InvokeFunction" --principal "s3.amazonaws.com" --source-arn "arn:aws:s3:::cm-lambda-test-bucket"
{
    "Statement": "{"Condition":{"ArnLike":{"AWS:SourceArn":"arn:aws:s3:::cm-lambda-test-bucket"}},"Action":["lambda:InvokeFunction"],"Resource":"arn:aws:lambda:us-west-2:595120573002:function:test-function","Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Sid":"s3-put-event"}"
}

ここで注意を1つ。細かいことですが、--source-arnのオプション(※必須ではない)を指定しないと、マネージメントコンソールの表示が以下のようになり、マネージメントコンソールからの削除ができなくなります(AWS-CLIからの削除は可能)。

lambda_02

どういう仕様なのかは分かりませんが、一応--source-arnオプションをつけておくことをお薦めします。

確認コマンドは以下の通りです。

$ aws lambda get-policy --function-name "test-function"
{
    "Policy": "{"Version":"2012-10-17","Statement":[{"Condition":{"ArnLike":{"AWS:SourceArn":"arn:aws:s3:::cm-lambda-test-bucket"}},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-west-2:595120573002:function:test-function","Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Sid":"s3-put-event"}],"Id":"default"}"
}

次に、S3側の設定をします。
ここでは、イベントタイプをPutにしています。一応、ちなみに程度ですが、S3バケットはLambdaファンクションと同じリージョンに存在する必要がありますので、ご注意ください。

$ aws s3api put-bucket-notification-configuration --bucket "cm-lambda-test-bucket" --notification-configuration "{'LambdaFunctionConfigurations': [{'LambdaFunctionArn': 'arn:aws:lambda:us-west-2:123456789012:function:test-function', 'Events': ['s3:ObjectCreated:Put']}]}"

設定されたことを確認します。

$ aws s3api get-bucket-notification-configuration --bucket "cm-lambda-test-bucket"
{
    "LambdaFunctionConfigurations": [
        {
            "LambdaFunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:test-function",
            "Id": "NWZmYjhkNmYtZTQwOS00ZDdlLThkODctMTZkNTY5MjEwOWNl",
            "Events": [
                "s3:ObjectCreated:Put"
            ]
        }
    ]
}

以上でおしまいです。
ちなみに、マネージメントコンソールで確認すると以下のようになっています。

Lambda:
lambda_03

S3:
s3_01

S3イベントソースの削除

最後に、削除の方法も載せておきます。
削除に関しても、Lambda側とS3側の両方の設定を削除する必要がありますので、以下のように2つのコマンドを実行してください。

$ aws lambda remove-permission --function-name "test-function" --statement-id "s3-put-event"
$ aws s3api put-bucket-notification-configuration --bucket "cm-lambda-test-bucket" --notification-configuration "{}"

まとめ

今回のTipsは、AWS-CLIやSDKからLambdaを操作をしようとするときの参考になるかと思いますので、ぜひ頭の片隅にメモっておいてください。
・・・う~ん、ちょっと手間だなと(笑)