新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

結局 AWS Lambda と API Gateway の管理は Serverless にした話

AWS CloudFormationの記事でも書いたのですが、AWS Lambda と API Gateway の管理は Serverless でやっています。

結局 AWS Lambda と API Gateway の管理は Serverless にした話

そこに至るまでの経緯のポエムおよび、Serverlessの使い方の簡単な説明です。

きっかけ

LambdaがどういったURLで呼び出されるかは、Lambdaではなく、API Gatewayで設定します。

API Gatewayの設定は下記のようなGUIで行えるのですが、設定箇所は結構多く、LambdaとAPI Gatewayを手動で管理するのにはすぐに限界が来て、何かしらの管理ツールを使う必要があるなと調べ始めました。

結局 AWS Lambda と API Gateway の管理は Serverless にした話
API Gateway 設定画面

モチベーション低下

調べてみると、管理ツールとして「Serverless」「AWS SAM」「Swagger」などの候補が上がってきたのですが、その過程で、「GraphQL」なるキーワードを知ってしまいました。

「GraphQL」とは、Facebookが提唱する、REST APIに代わる新しいAPI手順で、今回は使うつもりは無かったのですが、そういった物が出てくるということは、REST APIも過渡期かなと、REST APIに取り組むモチベーションが一気に冷めてしまいました。

また、GCPやAzureも似たようなFunctionやAPIサービスを提供しているのですが、それぞれ仕組みはバラバラで、それらをまとめる万能ツールは難しいのかなとも感じていました。

なので、汎用性は無くてもいいので、できるだけ学習コストが低く、簡単に使えるものがいいなぁと思い始めました。

試してみる

そんな中、CloudFormationなら、その知識はAWS全般にも使えるのでいいかなぁと思い、やってみたのですが、記事に書いたとおり痛い目にあいました。

次に「Serverless」を試してみたのですが、使いやすくて結局そのまま使い続けることになりました。

Serverlessのメリット

  • 必要最小限の記述でよしなに動いてくれます。
  • Lambda・API Gatewayの機能はほぼ網羅しています。
  • Serverlessでカバー仕切れない機能は、CloudFormationで補うことができます。

未設定部分はServerlessの方でデフォルトの設定を補ってくれるので、設定は少ない記述で済み分かりやすかったです。

利用手順

Serverlessのインストールはnpm install -g serverlessとnpmを使って行います。

次に、設定ファイル「serverless.yml」を記述し、プログラムが置かれているディレクトリに置きます。

そして、serverless deployとすると、プログラムがアップされてLambdaが作成され、API Gatewayでパスが作られ、パスとLambdaの紐づけを行ってくれます。

プログラムやパスを変更した際は、再度serverless deployとすると更新されます。

例えば、パス「/test/message」をGETでアクセスすると「{'result': 'Hello World!'}」と返す Lambda+API Gatewayは下記のようになります。 更にここでは、開発と本番でAPIを分けられるようにしてみます。

helloWorld.ts(JavaScriptに変換しています)

exports.handler = async (event: any, context: any) => {
    try {
        return { result: 'Hello World!' };
    } catch (err) {
        console.error(err);
        throw err;
    }
}

serverless.yml

service: serverless-test-api  # プロジェクト名
provider:
  name: aws
  stage: ${opt:stage}  # ステージ名(パラメータ化)
  endpointType: REGIONAL
  role: arn:aws:iam::xxxx  # Lambdaのロール
  runtime: nodejs8.10
  region: ap-northeast-1
  deploymentBucket:
    name: serveless-test-bucket # Lambdaのアップ先のS3バケット名
functions:
  hello-world:  # 関数名(論理名)
    name: hello-world-dev-${self:provider.stage}  # 関数名(Lambda実名)
    handler: helloWorld.handler  # ハンドラ(<JavaScriptファイル名>.<function名>)
    events:
      - http:
          path: test/message  # パス
          method: get  # メソッド
          integration: lambda

serverless deploy --stage 'dev'と打つと、LambdaとAPI Gatewayがアップされます。

Serverlessには開発・本番等のステージを分ける仕組みが入っていて、YAMLの「stage」で設定します。そのステージ名で全体のAPIが作成されるので、ステージ名で開発・本番でAPIを分けることができるのです。

また、ステージ名はパラメータ化でき、serverless deployコマンド実行時に決めることができます。そして、ステージでLambda関数も変えたかったので、YAML内でステージ名を参照する変数「${self:provider.stage}」を使って名前の切り替えを行っています。

これで、パスの変更や、ステージの追加・切り替えがちょっと記述を変えるだけでできてしまいます。これをAWSのGUIでやることを考えるとゾッとします…。

補足説明

  • Serverlessは内部的にはCloudFormationを使ってLambda・API Gatewayのデプロイを行っているので、serverless removeでごっそりLambda・API Gatewayごと削除することもできます。
  • API Gatewayだけでなく、S3やCloudWatch等の、他のLambdaトリガーもServerlessで記述できます。

Lambdaを使っていると、関連するAWSリソースをまとめて管理したくなります。Serverlessを使えば、「resources」項目でCloudFormationの記述で、それらのリソースを作成・設定することができます。

例えば、LambdaのロールをServerlessで作成しておけば、本番にデプロイした時に権限付与を忘れていた、といったようなことが無くなります。また、Lambdaを削除した時に、合わせてロールも削除してくれるので、用途不明のゴミロールが残るといったことも無くなるのでとても便利です。

感想

最初ツールを探し始めた時は、覚えるのが大変だなぁと気が重かったのですが、シンプルなツールが見つかってよかったです。

GraphQLもServerlessで書けるみたいなので、GraphQLが流行ってくるようならいつか試してみたいですね。

LambdaのオーソラーザーまわりのServerlessの設定で、いくつかハマったので別記事に書きました。

www.kwbtblog.com

www.kwbtblog.com