はじめに
- 最近ハマっているServerlessFrameworkでテンプレートシリーズです。
- 主旨
- 整合性チェックなり、レコード登録数の結果等をSQLして日次で取得したいニーズは時として浮上します。
- バッチこさえるのもアレですし、既存アプリのデータソースと別のDBへの接続とかだと萎えてしまうので、こんな時はLambdaでサクッと対応します。
- 尚、日次でコンテナが消滅するまでの間のコネクション1本という前提であれば、Lambda+RDSの問題には当たらないでしょう。
- ソースはGithubで公開してます。
-
PrivateSubunet
やNatGateway
についても触れます。 - 別件ですが、こないだJavaプログラマのためのAWSサーバーレスハンズオン-ServerlessFrameworkで画像処理アプリケーションを構築編-といったハンズオンしたんですが、また同様のやりたいなと思ってます。
概要
事前準備
- VPC内Lambdaから、VPC外に通信(今回はSNS)する場合、NATがバイパスされているPrivateSubnetに、Lambdaを配置する必要がありますので、そこら辺の事前準備をします。
- 今回はdefault VPCに対してPrivateSubnetを追加したりします。
PrivateSubnetの作成(ある場合はスキップ)
ルートテーブルの作成
- VPC -> ルートテーブル からルートテーブルを作成します。
- VPCはdefault VPCを選択します。
サブネットの作成
- VPC -> サブネット からサブネットを作成します。
- ルートテーブルタブにて先程作成したルートテーブルに変更します。
NatGatewayの関連付け(ある場合はスキップ)
NatGatewayの作成
- VPC -> NATゲートウェイからNATゲートウェイを作成します。
- サブネットはインターネットゲートウェイが紐付いているPublicSubnetを指定します。(先程作成したPrivateSubnetじゃない)。
- Elastic IPは、新しいEIPの作成からで良いです。
NatGatewayの関連付け
- 先程作成したPrivateSubnetに、NATゲートウェイを紐付けます
Lambdaに関連付けるRDSアクセス用のSecurity Groupを設定(ある場合はスキップ)
Security Groupの作成
RDSのSecurityGroupの変更
- RDSに設定しているSecurityGroupのインバウンドに先程作成したSecurityGroupを設定します。
SNS Topicを作成(ある場合はスキップ)
SNS Topicの作成
- SNSメニューから新しいトピックを作成します。
- 作成したトピックに任意のサブスクリプションを設定します。
Serverless FrameworkでDeploy
環境のセットアップ
Github上のソースからプロジェクト作成
- 以下のGithubからソースをインポートします。
$ sls create --template-url https://github.com/ukitiyan/notification-query --path notification-query
Serverless: Generating boilerplate...
Serverless: Downloading and installing "notification-query"...
Serverless: Successfully installed "undefined"
- バージョンによっては、 template-url が対応していないので、エラーの場合は以下を実行します:
$ sls install --url https://github.com/ukitiyan/notification-query --name notification-query
serverless.yml の修正
- serverless.ymlのL44 周辺のCron設定を適宜修正します。
- functions.notify.events.schedule.rate: AWS Lambda - Scheduled EventのCron書式
を参考に
UTC
で記載
- functions.notify.events.schedule.rate: AWS Lambda - Scheduled EventのCron書式
を参考に
serverless.yml
events:
- schedule:
rate: cron(0 16 * * ? *)
- serverless.ymlのL48 周辺の設定を適宜修正します。
- functions.notify.vpc.securityGroupIds: 事前準備で作成したRDSにアクセスするためのSercurityGroupIdを設定
- functions.notify.vpc.subnetIds: 事前準備で作成したLambdaが稼働するPrivate Subnetを設定(複数設定推奨)
- functions.notify.environment.RDS_ENDPOINT: RDSのエンドポイントを設定
- functions.notify.environment.RDS_DATABESNAME: RDSの接続DB名を設定
- functions.notify.environment.RDS_USERNAME: RDSの接続ユーザ名を設定
- functions.notify.environment.RDS_PASSWORD: RDSの接続パスワードを設定
- functions.notify.environment.SNS_TOPIC: SNSトピック名を設定
- functions.notify.environment.SNS_SUBJECT: SNSトピック送信時のSubjectを設定
serverless.yml
vpc:
securityGroupIds:
- sg-xxxxxxxx
subnetIds:
- subnet-xxxxxxxx
environment:
REGION: ${opt:region}
RDS_ENDPOINT: xxxx.rds.amazonaws.com
RDS_DATABESNAME: xxxx
RDS_USERNAME: xxxx
RDS_PASSWORD: xxxx
SNS_TOPIC: notification-query-xxxx
SNS_SUBJECT: "Notification Query Results"
src/main/resources/query.sql の修正
- 実行したいSQLに変更します。
- SNSのメッセージの上限は 256 KB なので、それ以下の結果になるよう気をつけてください。
query.sql
SELECT *
FROM customer
WHERE create_date > DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY);
Build+Deploy
- まずはmvnコマンドでビルドします。
$ cd notification-query
$ mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building notification-query 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.6.1:clean (default-clean) @ notification-query ---
~~~~~~
[INFO] Attaching shaded artifact.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.371 s
[INFO] Finished at: 2018-02-01T13:56:08+09:00
[INFO] Final Memory: 43M/432M
[INFO] ------------------------------------------------------------------------
- 続いてSLSでデプロイします。対象のregionを必ず指定してください。
$sls deploy --region ap-northeast-1
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
Service Information
service: notification-query
stage: dev
region: ap-northeast-1
stack: notification-query-dev
api keys:
None
endpoints:
None
functions:
notify: notification-query-dev-notify
- SLSでinvokeしてみて、SNS経由でメッセージが配信されるか確認します。
- もしくは、Cron設定時間になるまで待って、問題ないか気にしておきましょう。
$sls invoke -f notify --region ap-northeast-1
まとめ
- インスタンスにCronとか書きたくないじゃないですか、ソースをGitで管理して簡単にデプロイしたいじゃないですか、本当SLS素敵ですわと思います。
- 内外からこの手のニーズは良く聞いていたので、本内容でサクッと対応していけたら良いなと思います。