echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【Serverless Framework】Serverless FrameworkでAppSync APIを作成する

はじめに

前回、および前々回の記事で、AWS AppsSync(以下「AppSync」)のOpenID Connect認証、およびLambda認証について書きました。

となれば今回はIAM認証かな...とも思ったんですが、今回はちょっと話題を変えて、自分も大好きなServerless FrameworkでAppSync APIを作成する方法について書きたいと思います。

Serverless Framework

TL;DR

  • Serverless Frameworkでは、デフォルトではAppSyncはサポートされていない
  • でも「serverless-appsync-plugin」を使えば、AppSyncを作成できる
  • そのやり方

参考サイト

serverless-appsync-pluginについて

現在(2021/9/26時点)、Serverless Frameworkの公式機能としては、AppSyncはサポートされておらず、Lambdaのトリガ元として設定することもできません。(リゾルバが必ずしもLambdaとは限らないので、当然と言えば当然ですが)

ですのでServerless Framework標準機能でAppSyncを作成する場合、resourcesセクションで、生のCloudFormation(以下「Cfn」)のテンプレートを記載する必要があります。

しかし、Serverless FrameworkのPluginとして「serverless-appsync-plugin」というものが公開されており、これを使うことで、生のCfn構文を書かなくてもServerless FrameworkでAppSyncを作成することができます。

早速使ってみる

というわけで、まずはインストールします。
以下コマンドでインストールを行います。

> npm install serverless-appsync-plugin --save-dev

そして、serverless.ymlの「plugins」セクションに「serverless-appsync-plugin」を追加します。

plugins:
  - serverless-appsync-plugin

serverless.ymlを見ながら説明

「百聞は一見に如かず」ということで、ここからは実際のserverless.ymlを元に説明します。(関係ない定義は省略)

また全部説明するとキリがないので、appSyncキーの子要素&重要ポイントだけ説明します。(各項目の詳細説明は「参考サイト」のGitHubページに全て書いてあります。)

なお今回は、

というAppSync APIを作成しています。

あとLambda関数「authL」「treasureL」の処理内容は、前回の記事のそれと全く同じです。

service: 'terraform-sample'
frameworkVersion: '2'
  
custom:
  appSync:
    name: appsync-plugin-sample-api2
    # apiId: zn2mpenctja3neujg7m2vaiw3m
    authenticationType: AWS_LAMBDA
    schema: schema.graphql
    lambdaAuthorizerConfig:
      # functionName: # The function name in your serverless.yml. Ignored if lambdaFunctionArn is provided.
      # functionAlias: # optional, used with functionName
      lambdaFunctionArn: { Fn::GetAtt: [AuthLLambdaFunction, Arn] }
      # identityValidationExpression: # optional
      authorizerResultTtlInSeconds: 300
    # openIdConnectConfig:
    #   issuer:
    #   clientId:
    #   iatTTL:
    #   authTTL:
    logConfig:
      loggingRoleArn: arn:aws:iam::659547760577:role/administratorRole
      level: ALL
      excludeVerboseContent: false
    defaultMappingTemplates:
      request: false
      response: false
    mappingTemplates:
      - type: Query
        request: false
        response: false
        dataSource: dataSourceLambda
        field: treasureL
    dataSources:
      - type: AWS_LAMBDA
        name: dataSourceLambda
        description: 'Lambda DataSource for appsync-plugin-sample-api2.'
        config: # Either of functionName or lambdaFunctionArn must tbe provided. When both are present, lambdaFunctionArn is used.
          # functionName: graphql
          lambdaFunctionArn: { Fn::GetAtt: [TreasureLLambdaFunction, Arn] }
          serviceRoleArn: arn:aws:iam::659547760577:role/administratorRole
  
plugins:
  - serverless-appsync-plugin
  
functions:
  treasureL:
    handler: ./dist/treasureL/index.handler
  
  authL:
    handler: ./dist/authL/index.handler

大前提として「custom」セクション内に「appSync」キーを設定し、その中にAppSync APIの定義を書いていきます。

また上記serverless.ymlではしていませんが、AppSync APIの定義を配列で複数個定義することにより、一度に複数個のAppSync APIを作成できます。(同一スタックで管理したい場合)

「appSync」キーには、下表のキーが設定できます。

なお、とりあえず新規にAppSync APIを作る場合、

  • name/authenticationType/schemaを設定する
  • authenticationTypeに対応した認証設定を該当キー(lambdaAuthorizerConfigなど)で行う
  • dataSourcesでデータソースを定義する
  • mappingTemplatesでリゾルバの定義&データソースとの紐づけ(Query/Mutation)を行う

の手順を踏めばOKです。

項目名 説明 備考
name AppSync APIAPI
apiKey AppSync APIAPI KEYの値 既存のAppSync APIの更新/削除時のみ必要。(新規作成時は不要)
apiId AppSync APIAPI IDの値 指定した場合、該当のAppSync APIのみ更新する(?)(新規作成時は不要)
authenticationType APIの認証形式。API_KEY, AWS_IAM, AMAZON_COGNITO_USER_POOLS, OPENID_CONNECT, AWS_LAMBDAから選択 AWS::AppSync::GraphQLApiのそれと同じ
schema スキーマ定義ファイルのパス(globパターンでの指定可能) デフォルトは「schema.graphql」
caching キャッシュの設定
userPoolConfig 認証用Cognitoユーザープールの設定 authenticationTypeで「AMAZON_COGNITO_USER_POOLS」を選んだ場合のみ反映される
lambdaAuthorizerConfig 認証用Lambdaユーザープールの設定 authenticationTypeで「AWS_LAMBDA」を選んだ場合のみ反映される
openIdConnectConfig OIDC認証の設定 authenticationTypeで「OPENID_CONNECT」を選んだ場合のみ反映される
apiKeys 認証用API KEYの設定 authenticationTypeで「API_KEY」を選んだ場合のみ反映される
additionalAuthenticationProviders 「追加の認証プロバイダー」の設定
logConfig 「ログ記録」の設定 excludeVerboseContentは「詳細なコンテンツを含める」の設定(デフォルトはfalse)
defaultMappingTemplates 「MappingTemplates」のrequest/responseのデフォルト設定 ダイレクトLambdaリゾルバのように全部(または大部分)が同じ設定の場合、個々を設定すると個々の「mappingTemplates」で設定する必要がなくなる(あるいは省略できる)
mappingTemplates ゾルバのデータソース、およびマッピングテンプレートの設定 配列形式
functionConfigurations AppSync関数の設定 配列形式。省略可
dataSources データソースの設定 配列形式
substitutions mappingTemplatesで指定した全リゾルバに渡す変数(variables)の設定
xrayEnabled X-RAYの有効/無効の設定 デフォルトはfalse(=無効)
wafConfig WAF(AWS Web Application Firewall)の設定

※注意点

  • 上記serverless.ymlや「参考サイト」のGitHubページを見るとわかる通り、省略可能な項目もあります。(上表はとりあえず一通りappSyncキーの子要素を洗いだしてあります)
  • 「lambdaAuthorizerConfig」及び(dataSources.typeで「AWS_LAMBDA」を指定した場合の)「dataSources.config」では、Lambda関数を下記2つのキーのいずれかの方法で指定できます。
    • functionName(Lambda関数名)
    • lambdaFunctionArn(Lambda関数のARN)
  • 上記はいずれか一方のみの指定となります。(両方指定した場合、lambdaFunctionArnが優先される)

実行結果

上記「serverless.ymlを見ながら説明」のserverless.ymlをデプロイした結果が以下の画像の通りです。

AppSync APIが作成され、設定も正しく反映されているのが分かります。

f:id:Makky12:20210926161402p:plain
f:id:Makky12:20210926161421p:plain

また、Rest Clientで実際にリクエストを投げてみても、ちゃんとLambda認証やリゾルバが正しく動いているのが分かります。

f:id:Makky12:20210926161434p:plain
f:id:Makky12:20210926161445p:plain

まとめ

以上、Serverless FrameworkでAppSync APIを作成する方法について書きました。

Serverless Frameworkは、こういう便利なPluginがたくさん公開されているので便利です。こういうのをどんどん利用して、環境構築を便利にしていきたいです。

てか、自分でもなんかPluginを作成&公開できるようになりたいなあ。(マジで。てはハンズオンとかあったら、有料でも参加したい...)

告知

私が昨年登壇した「VS Code Conference」ですが、今年もオンラインで開催されるそうです。
また、登壇受付も9/30(木)まで行っているそうなので、興味のある方は応募されてみてはいかがでしょうか?

ちなみに僕は、ネタがなかなか思い浮かばないのと、予定の関係で、今年はどうするか悩んでおります。

vscode.connpass.com

では、今回はこの辺で。