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