LoginSignup
5
2

More than 5 years have passed since last update.

Serverless Framework @ AWSでlambdaを定期起動するlambdaを作る

Last updated at Posted at 2018-12-14

何らかの理由でLambdaから別のLambdaを呼びたいことがあります。
例えば、Lambdaのコールドスタートのコストを極力払いたくない時、定期的にそのLambdaを発火させるのが一つのパターンとして紹介されることがあるようです。

コールドスタートを速くする
スライド: https://www.slideshare.net/keisuke69/tune-up-aws-lambda

というわけで、これをServerless Frameworkでやってみます。
おそらくこれをやっている人は沢山いると思います。↓のリンク先の記事がまさに今回の例そのままなのですが、Lambdaの名前をリテラルで埋め込むあたりがしっくりこなかったので、Qiitaに書き直してみました。

やること

単純です。

  • 2つLambdaを用意して、片方をscheduleイベントで発火するようにする
  • 発火したLambdaは、もう一つのLambdaを呼ぶ

Lambdaの実装

今回は、呼ぶ側と呼ばれる側の二つの関数を同じJavaScriptモジュールに詰め込むことにします。scheduleで発火するLambdaから、呼ばれるLambdaの名前を知る方法ですが、環境変数CRON_TARGET_NAMEで渡すことにします。

const AWS = require("aws-sdk");
const lambda = new AWS.Lambda();

module.exports.hello = (_event, _context) => {
  console.log("hello");
};

module.exports.cron = (_event, _context) => {
  const params = {
    FunctionName: process.env.CRON_TARGET_NAME,
    InvocationType: "Event",
  };
  lambda.invoke(params, (err, data) => {
    console.log(err, data);
  });
};

serverless.yml

あとは設定ファイルであるserverless.ymlを書きます。

service: schedule-test

provider:
  name: aws
  runtime: nodejs8.10
  region: ap-northeast-1
  memorySize: 128

  iamRoleStatements:
    - Effect: Allow
      Action:
        - lambda:InvokeFunction
      Resource:
        - "*"

functions:
  hello:
    handler: handler.hello
    name: ${self:provider.stage}-hello-function
  cron:
    handler: handler.cron
    environment:
      CRON_TARGET_NAME: ${self:functions.hello.name}
    events:
      - schedule: rate(5 minutes)

Lambdaを起動する際に必要なものは2つあります。

  • 適切な権限(functions.cronの実行ユーザがlambda:InvokeFunctionを許可されていること)
  • Lambda関数の名前

今回の起動対象であるfunction.helloのAWSでの名前はfunctions.hello.nameで指定することができます。名前をデフォルトではなく明示的に指定をしておくことで、他の箇所からは${self:functions.hello.name}で参照できるようになるため、cronの環境変数CRON_TARGET_NAMEに名前を渡せるようになっています。

IAMについてはiamRoleStatementsを書くことでLambdaを起動できるように権限を足しました。

やっていないこと

  • iamRoleStatementsResource*より絞った方がいいかも
  • 2つのLambda関数は同期している必要がなさそうなので、InvocationType: "Event"の方が適切かも
    • (2018/12/15 追記)asyncにしておいた方が都合が良いだろうというアドバイスをいただいたのでサンプルを修正しました

参考リンク

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2