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に対して操作をする場合、循環参照になってしまいエラーとなる