Amplify CLI でカスタムリソースとして Lambda をトリガーする SQS キューを作成する
Amplify CLI でカスタムリソースとして Lambda をトリガーする SQS キューを作成する
Amplify CLI では amplify add function
のような SQS を追加するコマンドは存在しません。
また、 amplify add function
実行時に、Lambda 関数のトリガー設定に関する以下のような質問が出ますが選択肢として SQS はありません。
$ amplify add function
? Choose the function template that you want to use: Lambda trigger
? What event source do you want to associate with Lambda trigger? (Use arrow keys)
❯ Amazon DynamoDB Stream
Amazon Kinesis Stream
SQS のような Amplify CLI ではサポートされていない他のリソースを作成する場合は、「カスタム」機能を利用する必要があります。1
この「カスタム」機能では、カスタムリソースの定義方法として AWS CDK2 と CloudFormation3 の 2 種類がありますがそれぞれの方法で Lambda 関数をトリガーする SQS キューの作成と設定をしてみます。
Amplify CLI でカスタムリソースとして Lambda をトリガーする SQS キューを作成する手順
開発環境
- Amplify CLI: 7.6.22
作業ディレクトリの作成と初期化
まず、作業ディレクトリを作成し、Amplify プロジェクトを初期化します。
mkdir ~/sqs-lambda
cd ~/sqs-lambda
amplify init -y
Lambda 関数の作成と SQS へのアクセス許可の付与
amplify add function
コマンドで Lambda 関数を作成します。
取り敢えずここでは実行できればいいの、Hello World テンプレートを使用します。
$ cd ~/sqs-lambda
$ amplify add function
? Select which capability you want to add: Lambda function (serverless function)
? Provide an AWS Lambda function name: handleNotifySQS
? Choose the runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello World
Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration
- Environment variables configuration
- Secret values configuration
? Do you want to configure advanced settings? No
? Do you want to edit the local lambda function now? No
amplify/backend
ディレクトリに Lambda 関数(handleNotifySQS
)が追加されます。
.
└── amplify
└── backend
└── function
└── handleNotifySQS
├── amplify.state
├── custom-policies.json
├── dist
│ └── latest-build.zip
├── function-parameters.json
├── handleNotifySQS-cloudformation-template.json
└── src
├── event.json
├── index.js
├── node_modules
├── package.json
└── yarn.lock
Lambda 関数には SQS キューからメッセージを読み取るためのアクセス許可が必要です。
付与するアクセス許可は AWS マネージドポリシーの AWSLambdasqsqueueExecutionRole4 を参考にします。
CloudWatch Logs に関するアクセス許可はすでに定義済みなので、残りの以下の 3 つのアクションのアクセス許可を追加します。
sqs:ReceiveMessage
sqs:DeleteMessage
sqs:GetQueueAttributes
'lambdaexecutionpolicy':
{
'DependsOn': ['LambdaExecutionRole'],
'Type': 'AWS::IAM::Policy',
'Properties':
{
'PolicyName': 'lambda-execution-policy',
'Roles': [{ 'Ref': 'LambdaExecutionRole' }],
'PolicyDocument':
{
'Version': '2012-10-17',
'Statement':
[
{
'Effect': 'Allow',
'Action':
[
'logs:CreateLogGroup',
'logs:CreateLogStream',
'logs:PutLogEvents',
],
'Resource':
{
'Fn::Sub':
[
'arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*',
{
'region': { 'Ref': 'AWS::Region' },
'account': { 'Ref': 'AWS::AccountId' },
'lambda': { 'Ref': 'LambdaFunction' },
},
],
},
},
{
'Effect': 'Allow',
'Action':
[
'sqs:ReceiveMessage',
'sqs:DeleteMessage',
'sqs:GetQueueAttributes',
],
'Resource': '*',
},
],
},
},
}
CloudFormation で SQS をカスタムリソースとして作成する方法
amplify add custom
コマンドでカスタムリソースを作成します。
カスタムリソースの定義方法として AWS CloudFormation を選択してください。
$ cd ~/sqs-lambda
$ amplify add custom
✔ How do you want to define this custom resource? · AWS CloudFormation
✔ Provide a name for your custom resource · notifySQSByCfn
✔ Do you want to access Amplify generated resources in your custom CloudFormation file? (y/N) · yes
? Select the categories you want this custom resource to have access to. function
✅ Created skeleton CloudFormation stack in amplify/backend/custom/notifySQSByCfn directory
✔ Do you want to edit the CloudFormation stack now? (Y/n) · no
amplify/backend/custorm
ディレクトリにカスタムリソース(notifySQSByCfn
)が追加されます。
.
└── amplify
└── backend
└── custom
└── notifySQSByCfn
└── notifySQSByCfn-cloudformation-template.json
json 形式の CloudFormation テンプレートで SQS キューと Lambda のイベントソースマッピングを定義します。
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"env": {
"Type": "String"
},
"functionhandleNotifySQSName": {
"Type": "String",
"Description": "Input parameter describing Name attribute for function/handleNotifySQS resource"
},
"functionhandleNotifySQSArn": {
"Type": "String",
"Description": "Input parameter describing Arn attribute for function/handleNotifySQS resource"
},
"functionhandleNotifySQSRegion": {
"Type": "String",
"Description": "Input parameter describing Region attribute for function/handleNotifySQS resource"
},
"functionhandleNotifySQSLambdaExecutionRole": {
"Type": "String",
"Description": "Input parameter describing LambdaExecutionRole attribute for function/handleNotifySQS resource"
}
},
"Resources": {
"NotifySQSByCfn": {
"Type": "AWS::SQS::Queue"
},
"LambdaFunctionEventSourceMapping": {
"Type": "AWS::Lambda::EventSourceMapping",
"Properties": {
"BatchSize": 10,
"Enabled": true,
"EventSourceArn": {
"Fn::GetAtt": ["NotifySQSByCfn", "Arn"]
},
"FunctionName": {
"Ref": "functionhandleNotifySQSArn"
}
}
}
},
"Outputs": {}
}
AWS SDK で SQS をカスタムリソースとして作成する方法
amplify add custom
コマンドでカスタムリソースを作成します。
カスタムリソースの定義方法として AWS CDK を選択してください。
$ cd ~/sqs-lambda
$ amplify add custom
✔ How do you want to define this custom resource? · AWS CDK
✔ Provide a name for your custom resource · notifySQSByCDK
✅ Created skeleton CDK stack in amplify/backend/custom/notifySQSByCDK directory
✔ Do you want to edit the CDK stack now? (Y/n) · no
amplify/backend/custorm
ディレクトリにカスタムリソース(notifySQSByCDK
)が追加されます。
.
└── amplify
└── backend
└── custom
└── notifySQSByCDK
├── build
│ ├── cdk-stack.js
│ └── notifySQSByCDK-cloudformation-template.json
├── cdk-stack.ts
├── node_modules
├── package.json
├── tsconfig.json
└── yarn.lock
package.json
を編集して、必要なパッケージを追加してついでに使わないパッケージを削除します。
aws-sdk
のバージョンが 1.124
と古いですが、今回やることには支障がないのでそのままで行きます。
{
"name": "custom-resource",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@aws-amplify/cli-extensibility-helper": "^2.0.0",
"@aws-cdk/core": "~1.124.0",
"@aws-cdk/aws-sqs": "~1.124.0",
"@aws-cdk/aws-lambda": "~1.124.0"
},
"devDependencies": {
"typescript": "^4.2.4"
}
}
package.json
を編集したら、パッケージを再インストールします。
cd ~/sqs-lambda/amplify/custom/notifySQSByCDK
yarn install --check-files
スタックファイル(cdk-stack.ts
)に SQS キューと Lambda のイベントソースマッピングを定義します。
import * as cdk from '@aws-cdk/core'
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper'
import { AmplifyDependentResourcesAttributes } from '../../types/amplify-dependent-resources-ref'
import { Queue } from '@aws-cdk/aws-sqs'
import { Function, EventSourceMapping } from '@aws-cdk/aws-lambda'
export class cdkStack extends cdk.Stack {
constructor(
scope: cdk.Construct,
id: string,
props?: cdk.StackProps,
amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps
) {
super(scope, id, props)
/* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
new cdk.CfnParameter(this, 'env', {
type: 'String',
description: 'Current Amplify CLI env name',
})
const queue = new Queue(this, 'notifySQSByCDK', {})
const dependencies: AmplifyDependentResourcesAttributes =
AmplifyHelpers.addResourceDependency(
this,
amplifyResourceProps.category,
amplifyResourceProps.resourceName,
[{ category: 'function', resourceName: 'handleNotifySQS' }]
)
const lambdaArn = cdk.Fn.ref(dependencies.function.handleNotifySQS.Arn)
const target = Function.fromFunctionArn(this, 'handleNotifySQS', lambdaArn)
const eventSourceMapping = new EventSourceMapping(
this,
'NotifySQSByCDKEventSourceMapping',
{
target,
// the properties below are optional
batchSize: 10,
enabled: true,
eventSourceArn: queue.queueArn,
}
)
}
}
スタックファイル(cdk-stack.ts
) を編集したら、amplify build
コマンドでビルドを実行します。
cd ~/sqs-lambda
amplify build
Lambda 関数と SQS のデプロイ
amplify push
コマンドでデプロイを実行します。
cd ~/sqs-lambda
amplify push
AWS マネジメントコンソールで Lambda 関数と SQS キューが作成されていることを確認します。
動作確認
動作確認してみます。
まず、各 SQS キューからテストメッセージを送信します。
テストメッセージ送信後、Lambda 関数の CloudWatch Logs で送信したメッセージが確認できれば動作確認完了です。
Footnotes
個人開発したサービス
個人開発したサービス