AWS Startup ブログ

【週刊 Ask An Expert #11】AWS AppSync に対してサーバーサイドから mutation するには? AWS Loft Tokyo で受けた質問まとめ #AWSLoft

こんにちは、スタートアップ ソリューションアーキテクトの塚田 (@akitsukada) です。
最近、ときめいている技術やサービスはありますか?僕は ChaliceAmazon Pinpoint です!

今回は週刊 Ask An Expert 第 11 回目をお届けします。「参考になった!」「いい内容だ!」と思っていただけたら、ぜひハッシュタグ #AWSLoft を付けてシェアしてください。もちろん、改善点・ご要望もお待ちしております。

Ask An Expert ?

さて、皆さん AWS Loft Tokyo はご存知でしょうか?
目黒セントラルスクエア17Fにある、AWS を利用中のスタートアップとデベロッパーのためのコワーキングおよびイベントスペースです。その中に、AWS のエキスパート – Solutions Architect(SA)や Cloud Support Engineer(CSE)といった中の人に技術的な質問ができる、Ask An Expert カウンターがあります。そこでは毎月、来場者の方から100件以上にものぼるご相談をお受けしています。

ある日の Ask An Expert(Solutions Architect 市川)

この連載では、我々 AWS のエンジニアが Ask An Expert でどのような質問を受け、どんな感じで対応しているのか、 *非常にざっくりと* ご紹介していく「週刊 Ask An Expert」をお届けしていきます。他の AWS Loft 利用者がどんな質問をしているのか、自分が知らなかった新しいトピックはないか、Ask An Expert ってどんなところなのか、一緒に見ていきましょう!
※ 似たご質問をまとめたり、ざっくりまとめにくいご質問を省いたりしているため、実際のご質問件数・内容とは異なる部分があります。

週刊 Ask An Expert #11 (2019/06/24 – 06/28)

この週の対応者は SA:内田、山崎、浅野、中島、岩野、CSE:福嶋、古野、榎本 でした。

Q: Amazon S3 の書き込みイベントで AWS Lambda(Node.js) が実行されるように設定しているが、望む処理結果が確認できない。

一緒にコードを確認したところ、 Callback でなく関数途中で文字列を return していたために途中で処理が終了してしまっているようでした。それを修正後、Lambda の実行ロールの不足によるエラーも出ていたため、必要な権限を IAM Role にも追加しました。

Q: Amazon Route 53 で、 CNAME レコードと Alias レコードはどう違うの?

Alias レコードは、Route 53 独自の DNS 拡張機能です。Alias レコードを使用すると、CloudFront ディストリビューションや Amazon S3 バケットなどの AWS リソースにトラフィックをルーティングしたり、ホストゾーン内のあるレコードから別のレコードにトラフィックをルーティングしたりできます。
また、CNAME レコードと異なり、Alias レコードは Zone Apex DNS 名(www.example.com でなく example.com)を作成できたり、Alias レコードへのクエリが無料であることが違いとして上げられます。(ドキュメントFAQ を御覧ください)

Q: CI のプロセス内で Amazon Aurora PostSQL にテーブル作成・データ登録する方法を知りたい。

既に CI 環境内で AWS CLI をお使いだったため、IAM 認証によって接続を行いデータベースを操作する方法をご案内しました。

Q: Amazon Connect の CCP (問い合わせコントロールパネル – Contact Control Panel)に、 Amazon Connect Streamsで実装した JavaScript をデプロイしているが、onAcceptedメソッド、onEndメソッドが動かなくて困っている。

一緒にログやエラーを見ていったところ、独自に作成されたクラスのコンストラクタで電話番号を split() する箇所でエラーが発生していることが分かったため、修正していただいたところ onAccepted, onEnd が問題なく動きました。

Q: Amazon ElastiCache で、適切なインスタンスタイプを知る術を知りたい。

ヒアリング結果から、まず最小のインスタンスタイプで動かしていただき、CloudWatchの各種メトリクス(CPU、メモリ、クライアントのコネクション数等)を確認していただきインスタンスタイプを変更していただくようにご案内いたしました。あわせて、公式ドキュメントの「モニタリングすべきメトリクス」のページをご案内いたしました。

※ 場合によっては、逆に大きめのインスタンスを立ててから徐々に小さくしていくことが適切であることもあります。ケースバイケースでご対応ください。

Q: Amazon S3 にファイルをアップロードしたイベントで AWS Lambda をトリガーしたいと考えているが、万が一 Lambda が起動しなかった場合などを想定したケアはどうすればよいか?

ファイルがアップロードされる場所と Lambda で処理した後にファイルを移動する場所を分けて元の場所に古いファイルが残っていないか見張る方法などをご提案しました。

Q: Amazon S3 に保存したデータを SQL で検索したり、グラフ表示で可視化したりしたい。何を使えばよいか?

Amazon Athena を使い S3 上のデータを検索したり、 Amazon QuickSight で Athena を通じ S3 上のデータを可視化する方法をご案内しました。

QuickSight についてはこちらのマンガも分かりやすいのでご覧ください。

Q: Amazon Cognito User Pools と Cognito Identity Pools の違いはなんですか?

User Pools は、新規登録、サインイン、サインアウトといったユーザー管理および認証機能をアプリケーションに追加できます。ソーシャルアカウントや SAML、OpenID Connect といったサードパーティの ID プロバイダ (IdP) に対してフェデレーションを行うこともでき、これによって、例えば Facebook ログイン機能をアプリケーションに追加することができます。User Pools で認証に成功したクライアントには、ID トークン、アクセストークン、リフレッシュトークンが JWT (JSON Web Token) 形式で払い出されます。

Identity Pools は、User Pools 含む対応 IdP で認証されたクライアント、または未認証のゲストクライアントに対して、 AWS IAM Role に基づいた AWS 認証情報を発行します。クライアントには、Access Key、Secret Access Key、Session Token といった AWS リソースにアクセスするための認証情報が払いだされます。これによって、未認証ユーザーと認証済ユーザーで例えばアクセス可能な Amazon S3 バケットを分けるなどの権限制御を行うことができます。

参考: Amazon Cognito のユーザープールと ID プールの違いは何ですか?

Q: SPA (Single Page Application) でなく画面遷移するアプリケーションで Amazon Cognito User Pools を使う場合、 Cognito から発行されるトークンは各画面でどう扱えばよいですか?

アプリケーションの要件次第ですが、例えばリクエストのたびにサーバーサイドでトークンを検証し、クライアントが正しくサインイン済であることを確認することが考えられます。

Q: Amazon SNS でモバイルプッシュ通知を配信している。「xx日間ログインしていない人」といった条件に対して通知を配信したい。その際、AWS マネージメントコンソールではなく、API 経由で操作したい。

機能的に Amazon Pinpoint が適していると思われるため、ご紹介しました。

Amazon Pinpoint × グロースハック活用事例集

Q: 現在あるシステムを、アプリケーションとデータベース全て込みで Amazon EC2 インスタンス 1 台で運用している。ベンダーに次の一年間の見積もりを取ったら Amazon RDS が追加されていたが、これは必要なのか?

Amazon RDS は、データベースの管理、運用、拡張などを簡単にしてくれます。EC2 一台であれば安価で済むかも知れませんが、それは運用コストや可用性、障害発生時のビジネスリスクなどとトレードオフになることを認識した上で、ビジネス要件と併せてご検討ください。

Q: Amazon EC2 1台で WordPress を運用しているが、サービスがダウンしてしまった。インスタンスタイプを変更したところ復旧したが、今後どうすればよいか。

アクセス過多による負荷が原因なのであれば、WordPress でホストされた読み込みアクセスがメインのサイトには Amazon CloudFront によるコンテンツのキャッシュが有効と思われます。また、通常 Web サイトの負荷対策には ELB を利用した EC2 複数台での負荷分散などが考えられますが、WordPress におけるベストプラクティス、リファレンスアーキテクチャを公開しているのでそちらも御覧ください。
> AWS Architecture Blog – WordPress: Best Practices on AWS

Q: AWS AppSync のデータソースに指定している Amazon DynamoDB から読み込みはできるが、書き込みができない。以前はできていた。

AWS IAM の権限設定に問題ないように思われ、Amazon CloudWatch Logs でエラーログ等も確認できませんでした。AppSync のデバッグ方法、ブラウザの Developer Tools を使った HTTP レスポンスの確認方法などをお伝えし、調査しても解決できないようなら AWS サポートにお問い合わせいただくようご案内しました。

※ 現在、AWS Summit 限定ビジネスサポート 60 日間無料トライアルキャンペーンを実施中です。お申し込み受け付けは 7/11(木) までです。この機会にぜひお試しください!

Q: Amazon QuickSight で Amazon S3 をデータソースにしたい。どういった制約があるか?

要件をお伺いすると、今回は複数ファイルとのことでした。ドキュメントを交え、各ファイルには同じ数のフィールド (列) がある必要がある点などをお伝えしました。

Q: AWS Glue はどういった用途で使うのか?

以下の資料を紹介しながら、ETL 処理などで利用するサービスであることを解説しました。

AWS Black Belt – AWS Glue

Q: 現在独自の認証基盤を持っているが、Amazon Cognito に移行したい。既存の認証基盤で Facebook 認証しているユーザー情報を、 Cognito に移行してから Facebook 認証に対応させるにはどうすればよいか。

AdminLinkProviderForUser API で、 Cognito User Pool 内のユーザーをサードパーティ IdP に紐づけることが可能です。

Q: LINE アカウントから個人に通知を行うサービスの提供を検討している。Amazon API Gateway と AWS Lambda を使ったサーバーレスアプリケーション経由で LINE の API を呼び出すことを想定しているが、Lambda 単体では通常の Web アプリケーションのようにセッション維持ができない。別の場所にセッション情報を保存すべきか。

はい。仰るように、たとえば Amazon DynamoDB など、外部のデータストアにセッション情報を持つ必要がありそうです。

Q: 新規コワーキングサービスの設計をしている。利用者同士をつなげる SNS とバックオフィス用の管理サービスの2つを作ろうとしている。バックオフィスの機能は外部の ERP サービスを使う。決済も外部の決済サービスを使う予定。SNS は、エンドユーザーが AWS 上に構築する。ERP -> 決済サービス間の連携機能が Poor なので連携用の中間サービスを AWS 上に構築したい。どのようなサービスを使えば実現できるか。

Amazon API Gateway と AWS Lambda のサーバーレスでも、Amazon EC2 でも実現できると思われますが、業務フローが固まっていない様子であったため業務フローおよび要件を先に検討することをお勧めしました。
決済処理のリトライについては、多重決済を避けるためにエラー内容によってリトライの要否を判断し、場合によってはエラー原因を人間が確認した上で適切な処理を行う業務フローも用意した方がよいのでは、というお話もしました。(例えば多重決済が発生した場合の返金手続きなども必要となるため。)

Q: AWS Fargate に対する Blue/Green Deployment について教えて欲しい。

AWS CodeDeploy による AWS Fargate への Blue/Green Deployment についてご案内しました。

Q: 社内向けに作成したトレーニング済み機械学習のモデルを使って、外部ユーザー向けにサービスを提供したい。どのようなサービスを組み合わせればよいか?

Amazon SageMaker を使って API を構築する方法や、Machine Learning & AI Marketplace についてご紹介しました。

Q: AWS Amplify と Amazon Cognito を利用中。ALB で Cognito の Authorizer を有効にしているが、カスタム認証画面を作りたい。

お伺いしたところ、React アプリケーション を Amazon S3 にデプロイした SPA ではなく、ALB と Amazon EC2 を使ってコンテンツをホストしているようでした。ALB で Cognito Auth を設定するのではなく、EC2 から React の Assets を返し、Amplify の Authentication コンポーネントを使う方法をご提案しました。

Q: Amaozn EC2から Amazon Kinesis Data Streams にログを送っている。Kinesis に設定された AWS Lambda でデータを確認し、データ内に URL がある場合はその URL に GET リクエストをしている。しかし URL を GET する Lambda の Invoke 数が多く、Lambda の同時実行上限数に達してしまうことがある。
構成:EC2->Kinesis Data Streams -> Lambda(URLの抽出) -> Amazon SNS -> AWS Lambda(1URLへのGET)

SNS でなく Kinesis を使う、以下のような構成を議論しました。

EC2->Kinesis->Lambda(URLの抽出)->Kinesis->Lamdab(複数 URL に対する GET)

この構成であれば、

  • Lambda の呼び出し回数が抑えられる
  • 追いつかないような場合には以下をすることで改善も見込める
    • Kinesis シャード数の増加(Lambda の並行数を増やす)
    • Lambda のスペックを上げる(処理能力を向上することで改善する可能性がある)
    • Lambdaのバッチサイズの調整

等のメリットが期待できることをご案内しました。

Q: ELB (Amazon Certificate Manager による TLS 証明書を使い 443 Listen) -> Amazon EC2(WordPress) の構成で、ブラウザからの HTTPS リクエストの際に403エラーとなる

詳細をお伺いしつつリソースを見せて頂いたところ、ELB のターゲットグループと紐づくインスタンスが unhealhy となっていた為、ヘルスチェックの確認をしました。また、ELB -> EC2 間が 443 ポートで通信されていましたが、WordPress で Listen しているのは 80 ポートであったため、ポートの変更も依頼しました。

Q: Amazon API Gateway -> AWS Lambda -> Amazon DynamoDB という構成で、認証をどうするか考えている。Cognito User Pools を使った場合、アクセスしたユーザーを特定することはできるか?

API Gateway に Cognito Authorizer を指定する場合、Cognito から取得した JWT を HTTP リクエスト時に HTTP ヘッダで送信することで、バックエンドの Lambda では$context.authorizer.claims.{property} で JWT 内クレームのプロパティが取得できるほか、sub の取得も可能です。

Q: Amazon DynamoDB のテーブル設計について知りたい。

以下の資料をご案内しつつ、説明を行いました。

【旧版・説明欄参照ください】 サーバーレスアプリケーション向きの DB 設計ベストプラクティス

Q: Amazon DynamoDB ではロック処理が可能か。

バージョン番号を使用したオプティミスティックロックが考えられる他、トランザクション機能があります。要件にあうものをご検討ください。

Q: AWS Fargateを利用してWebサービスを作っている。 Task に複数のコンテナを定義した上で Service を構成したとき、それぞれの Task に異なるロードバランサーを紐づけることは可能か。

はい。AWS CLI で言えば、aws ecs create-serviceコマンドの --load-balancers パラメーターで、それぞれのコンテナをそれぞれのターゲットグループに紐づけることが可能です。

Q: AWS AppSync に対して、AWS Lambda(Node.js) から mutation したい。どのようなSDKを利用すればよいか?

AWS AppSync SDK、Apollo クライアントなどが必要です。詳しくは公式ドキュメントに package.json などの記述があります

package.json 依存関係ファイルを編集します。次の項目が含まれることを確認します。
“dependencies”: {
“apollo-cache-inmemory”: “^1.1.0”,
“apollo-client”: “^2.0.3”,
“apollo-link”: “^1.0.3”,
“apollo-link-http”: “^1.2.0”,
“aws-sdk”: “^2.141.0”,
“aws-appsync”: “^1.0.0”,
“es6-promise”: “^4.1.1”,
“graphql”: “^0.11.7”,
“graphql-tag”: “^2.5.0”,
“isomorphic-fetch”: “^2.2.1”,
“ws”: “^3.3.1”
}

Q: AWS AppSync に対して AWS Lambda から mutation するとき、特定の mutation だけアクセスを許可するにはどうすればよいか。

Lambda ファンクションは IAM Role を割り当てられるため、@aws_iam アノテーションを利用した権限設定方法をお伝えしました。

Q: AWS Single Sign-On で、違うリージョンの Microsoft AD に接続できるか?

同じリージョンの AD である必要がある点をお伝えしました。リージョン内に AD がないと、「リージョン内に使用できるディレクトリがありません」といったエラーメッセージが表示されます。

Q: Amazon Connet から別アカウントの AWS Lambda を呼び出したいが、エラーになる。

エラー内容を確認したところ、AWS Lambda のパーミッションが足りていないようでした。リソースベースのポリシーを使い、該当 Lambda ファンクションにクロスアカウントの Connect からの呼び出しを許可するよう設定していただくようご案内しました。

Q: 認証サービスとして Amazon Cognito User Pools の設定を行なったが、具体的な使い方が分からない。

実際にCognito User Pool の管理コンソールを見ながら各設定についてご説明しました。

Q: Amazon Cognito User Pools のトークン取得までのフローとトークンの利用方法が分からない。

ホワイトボードを用いながら、主にHosted UIを利用したフローをご説明しました。
取得した authorization code からのトークン取得については、AWS Amplify を利用して簡略化できることを紹介しました。

週刊 Ask An Expert まとめ、今回はここまで

最後までお読み頂きありがとうございます!
冒頭に書いたように、似たご質問をまとめたり、端的にまとめづらいご質問を省いているためそっくりこのままやり取りが行われているわけではありませんが、様々なご相談をいただいていることが伝わっていれば嬉しいです。実際の Ask An Expert カウンターでは、より詳細なご案内・議論が行われています。
それではまた次回をお楽しみに!


このブログの著者

塚田 朗弘 (Akihiro Tsukada) @akitsukada

Serverless, Mobile, Blockchain, FinTech Security あたりをよく触っているスタートアップ ソリューションアーキテクトです。そういうネタも書かなければ。