Amplifyで作成したLambdaにトリガーを指定する
March 20, 2020
Amplifyで作成したLambdaにトリガーを指定することが可能だが、やり方がバラバラなのでまとめてみた。
amplify version: 4.13.4
DynamoDBトリガー
AppSyncIdがテーブル名に使われているため、AppSyncIdを取得する必要がある。
(追記1) Lambdaを新規追加する場合は amplify add function
時にDynamoDBトリガーを指定できるっぽい
(追記2) amplify version 4.16.1
では、 amplify function update
時に storage
を選択するとDynamoDBを選択できるようになるので 手動でCloudFormationをいじらなくて良さそう 結局手動でCloudFormationの追加が必要
手順
amplify function update
を実行し、APIを紐付ける
? Please select the Lambda Function you would want to update
-> 対象のfunction選択
? Do you want to update permissions granted to this Lambda function to perform o
n other resources in your project?
-> Y
? Select the category (Press <space> to select, <a> to toggle all, <i> to invert
selection)
-> api
をspaceで選択
? Api has x resources in this project. Select the one you would like your Lambda
to access (Press <space> to select, <a> to toggle all, <i> to invert selection)
-> 対象のapiを選択
? Select the operations you want to permit for vacaite (Press <space> to select,
<a> to toggle all, <i> to invert selection)
-> read
をspaceで選択
? Do you want to edit the local lambda function now?
-> lambdaを編集したければY
- 以下を
amplify/backend/function/FUNCTION_NAME/FUNCTION_NAME-cloudformation-template.json
のResouces
以下に 追加し、XXXXXX
を api名に変更、YYYYYY
をトリガーにするテーブル名に変更する
"EventSourceMapping": {
"Type": "AWS::Lambda::EventSourceMapping",
"DependsOn": [
"LambdaExecutionRole",
"CustomPolicyForTableStreamSubscription"
],
"Properties": {
"EventSourceArn": {
"Fn::ImportValue": {
"Fn::Sub": "${apiXXXXXXGraphQLAPIIdOutput}:GetAtt:YYYYYYTable:StreamArn"
}
},
"FunctionName": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
},
"StartingPosition": "TRIM_HORIZON"
}
},
"CustomPolicyForTableStreamSubscription": {
"Type": "AWS::IAM::Policy",
"DependsOn": [
"LambdaExecutionRole"
],
"Properties": {
"PolicyName": "dynamodb-stream-permission",
"Roles": [
{
"Ref": "LambdaExecutionRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:DescribeStream",
"dynamodb:ListStreams"
],
"Resource": [
{
"Fn::ImportValue": {
"Fn::Sub": "${apiXXXXXXGraphQLAPIIdOutput}:GetAtt:YYYYYYTable:StreamArn"
}
}
]
}
]
}
}
}
複数のDynamoDBテーブルをトリガーにする場合
以下のように AWS::Lambda::EventSourceMapping
リソースを複数作成し、 CustomPolicyForTableStreamSubscription
の Resource
にテーブルを追加する
"YYYYYYEventSourceMapping": {
"Type": "AWS::Lambda::EventSourceMapping",
"DependsOn": [
"LambdaExecutionRole",
"CustomPolicyForTableStreamSubscription"
],
"Properties": {
"EventSourceArn": {
"Fn::ImportValue": {
"Fn::Sub": "${apiXXXXXXGraphQLAPIIdOutput}:GetAtt:YYYYYYTable:StreamArn"
}
},
"FunctionName": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
},
"StartingPosition": "TRIM_HORIZON"
}
},
"ZZZZZZEventSourceMapping": {
"Type": "AWS::Lambda::EventSourceMapping",
"DependsOn": [
"LambdaExecutionRole",
"CustomPolicyForTableStreamSubscription"
],
"Properties": {
"EventSourceArn": {
"Fn::ImportValue": {
"Fn::Sub": "${apiXXXXXXGraphQLAPIIdOutput}:GetAtt:ZZZZZZTable:StreamArn"
}
},
"FunctionName": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
},
"StartingPosition": "TRIM_HORIZON"
}
},
"CustomPolicyForTableStreamSubscription": {
"Type": "AWS::IAM::Policy",
"DependsOn": [
"LambdaExecutionRole"
],
"Properties": {
"PolicyName": "dynamodb-stream-permission",
"Roles": [
{
"Ref": "LambdaExecutionRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:DescribeStream",
"dynamodb:ListStreams"
],
"Resource": [
{
"Fn::ImportValue": {
"Fn::Sub": "${apiXXXXXXGraphQLAPIIdOutput}:GetAtt:YYYYYYTable:StreamArn"
}
},
{
"Fn::ImportValue": {
"Fn::Sub": "${apiXXXXXXGraphQLAPIIdOutput}:GetAtt:ZZZZZZTable:StreamArn"
}
}
]
}
]
}
}
}
参考URL
- https://github.com/aws-amplify/amplify-cli/issues/987
- https://github.com/matwerber1/aws-amplify-subscribe-lambda-to-dynamodb-api-table-stream/
CloudWatchEvents
CloudFormationのテンプレートにリソースを追記する
手順
- 以下を
amplify/backend/function/FUNCTION_NAME/FUNCTION_NAME-cloudformation-template.json
のResouces
以下に 追加し、ScheduleExpression
にスケジュールを指定
"ScheduledRule": {
"Type": "AWS::Events::Rule",
"Properties": {
"Description": "lambda schedule",
"ScheduleExpression": "rate(1 day)",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
},
"Id": "lambdaschedule"
}
]
}
},
"PermissionForEventsToInvokeLambda": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Ref": "LambdaFunction"
},
"Action": "lambda:InvokeFunction",
"Principal": "events.amazonaws.com",
"SourceArn": {
"Fn::GetAtt": [
"ScheduledRule",
"Arn"
]
}
}
}
S3トリガー
コマンドだけで対応可能。LambdaじゃなくてStorageの方を更新する。
手順
amplify storage update
を実行し、S3にLambdaを紐付ける
? Please select from one of the below mentioned services: (Use arrow keys)
-> 変更せずにEnter
? Who should have access: (Use arrow keys)
->変更せずにEnter
? What kind of access do you want for Authenticated users? (Press <space> to sel
ect, <a> to toggle all, <i> to invert selection)
-> 変更せずにEnter
? What kind of access do you want for Guest users? (Press <space> to select, <a>
to toggle all, <i> to invert selection)
-> 変更せずにEnter
? Do you want to add a Lambda Trigger for your S3 Bucket? (y/N)
-> y
? Select from the following options (Use arrow keys)
-> Choose an existing function from the project
を選択し、対象のLambdaを選択
注意事項
- 細かいトリガーイベントは設定できない(作成系または削除系のイベントでトリガーされる)のでLambda内で振り分けが必要
- Lambda内で同一S3に対して操作をする場合、循環参照になってしまいエラーとなる