原文はこちら
マイクロサービスとサーバレスは、これまでにも増して人気を得てきており、世界中のチームがこれらのパターンとアーキテクチャに非常に迅速に適応してきています。しかし、大規模にマイクロサービスとサーバレスを活用しようとする際にこうしたチームがまず直面するのが、フロントエンドとモバイルAPIのとても多くの、そして複雑なエンドポイントを管理しなければならないという課題です。そのため、多くのチームではバックエンドをシンプルにし、すべてのクライアントからの「シングルポイント・オブ・エントリー」にするために、API Gatewayを採用しています。API Gatewayはまた、アーキテクチャの中の個々のファンクションではなくゲートウェイのレベルで、レート制限やCORS、認証を簡単に実装できるようにしてくれます。
このブログポストではOracle Cloudの最新サービスのひとつであるAPI Gatewayを概覧していきます。
以下の順で進めていきます:
- "Hello World"サーバレスファンクションの作成とデプロイ
- API Gatewayに適したサブネットの作成
- ダイナミックグループの作成とAPI Gatewayに必要なポリシーの適用
- Gatewayの作成
- Gatewayへの仕様のデプロイ
- Gatewayのテスト
"Hello World"サーバレスファンクションの作成とデプロイ
ではシンプルなサーバレスアプリケーションとファンクションを作成し、そのファンクションをデプロイしてみましょう。このファンクションの内容は今回関係なくて、ただ後にGatewayのテストで使いたいだけです。なので、ファンクションはサンプルの"Hello World"のままにしておきます。ランタイムもここでは関係ないので、Oracle Functionsと
Fn Projectでサポートされているものならなんでもよいです。
| $ fn create app gw-hello-world-app --annotation oracle.com/oci/subnetIds='["ocid1.subnet.oc1.phx..."]' |
| Successfully created app: gw-hello-world-app |
| |
| $ fn init --runtime node gw-hello-world-fn |
| Creating function at: /gw-hello-world-fn |
| Function boilerplate generated. |
| func.yaml created. |
| |
| $ cd gw-hello-world-fn |
| |
| $ fn deploy --app gw-hello-world-app |
| Deploying gw-hello-world-fn to app: gw-hello-world-app |
| Bumped to version 0.0.3 |
| Building image phx.ocir.io/toddrsharp/faas/gw-hello-world-fn:0.0.3 ......... |
| Parts: [phx.ocir.io toddrsharp faas gw-hello-world-fn:0.0.3] |
| Pushing phx.ocir.io/toddrsharp/faas/gw-hello-world-fn:0.0.3 to docker registry...The push refers to repository [phx.ocir.io/toddrsharp/faas/gw-hello-world-fn] |
| 643fe44f12a4: Pushed |
| b279f8214e6b: Pushed |
| 0adc398bfc34: Pushed |
| 0b3e54ee2e85: Pushed |
| ad77849d4540: Pushed |
| 5bef08742407: Pushed |
| 0.0.3: digest: sha256:e16e74ce194d85a9658177f7637484aded9764e981e395dfcbcac2d018687cac size: 1571 |
| Updating function gw-hello-world-fn using image phx.ocir.io/toddrsharp/faas/gw-hello-world-fn:0.0.3... |
| Successfully created function: gw-hello-world-fn with phx.ocir.io/toddrsharp/faas/gw-hello-world-fn:0.0.3 |
この時点でファンクションを fn CLIで呼び出しできます:
| $ fn invoke gw-hello-world-app gw-hello-world-fn |
| {"message":"Hello World"} |
しかし、HTTP(S)経由やOCI SDKを利用してファンクションを直接呼び出しするにはリクエストへの署名が必要です。ファンクションをインスペクトして呼び出しエンドポイントを取得してみましょう:
| $ fn inspect gw-hello-world-app gw-hello-world-fn |
注! fn inspect コールから id をコピーしておきましょう。これが後で必要になるファンクションのOCIDです!
呼び出ししようすると 401 Unauthorizedで失敗します:
| $ curl -i -X GET https://[redacted].us-phoenix-1.functions.oci.oraclecloud.com/20181201/functions/ocid1.fnfunc.oc1.phx..../actions/invoke |
| HTTP/1.1 401 Unauthorized |
| Date: Fri, 22 Nov 2019 14:24:33 GMT |
| Content-Type: application/json |
| Content-Length: 57 |
| Connection: keep-alive |
| Opc-Request-Id: /01DT9R03K21BT1A2RZJ0005QSH/01DT9R03K21BT1A2RZJ0005QSJ |
| Www-Authenticate: Signature headers="date (request-target) host" |
| |
| {"code":"NotAuthenticated","message":"Not authenticated"} |
But once we put our serverless function behind our gateway we can invoke it via HTTPS. Let's move on!
しかし、Gatewayのうしろにサーバレスファンクションを配置することによって、HTTPS経由で呼び出しができるようになります!やってみましょう!
API Gatewayに適したサブネットの作成
API Gateway用にHTTPSトラフィックのためのイングレスルールを設定したリージョナルサブネットが必要になります。ここでゃ既存のVCNの中にこのサブネットを作成していきましょう。
選んだセキュリティリストにポート443へのイングレスルールを追加します:
完了です。続いてもセキュリティについて…
ダイナミックグループの作成とAPI Gatewayに必要なポリシーの適用
API Gatewayではテナンシー内でのアクセス制御にダイナミックグループを使用します。なので、新しくダイナミックグループを作成していくつかのポリシーを設定する必要があります。Gatewayを作成するコンパートメントのOCIDが必要になるので、Identity -> Compartmentsから使うコンパートメントのOCIDをコピーしてください。次に、新規ダイナミックグループを以下の定義(コンパートメントOCIDは適切なものに置き換えて)で作成しましょう:
さて、あなたのテナンシーと新しく作成したダイナミックグループに対応するポリシーを作成します。グループ名とコンパートメント名はご自身のものに置き換えてください:
| allow dynamic-group [your dynamic group] to use virtual-network-family in compartment [your compartment name] |
| allow dynamic-group [your dynamic group] to manage public-ips in compartment [your compartment name] |
| allow dynamic-group [your dynamic group] to use functions-family in compartment [your compartment name] |
ご参考まで、わたしのテナンシーでのステートメントは以下のようになりました:
| allow dynamic-group api-gw-group to use virtual-network-family in compartment faas-compartment |
| allow dynamic-group api-gw-group to manage public-ips in compartment faas-compartment |
| allow dynamic-group api-gw-group to use functions-family in compartment faas-compartment |
それではGatewayを作成しましょう!
Gatewayの作成
Gatewayを作成するには、まずサイドバーメニューから'Developer Services'の配下の'API Gateway'を選択します。
'Create Gateway'をクリックしてダイアログを埋めていきます。先程作成したリージョナルサブネットを選択することを忘れないでください。
Gatewayはまず'Creating'のステータスになるでしょう。
数分くらいで、Gatewayは'Active'になります。
Gatewayへの仕様のデプロイ
デプロイメントを作成する前に、エンドポイントを定義するためデプロイメント仕様ファイルをJSONフォーマットで記述する必要があります。前述のファンクションOCIDが手元にあることを確認してください。では、 spec.json というファイルをファンクションのルートに以下の内容で作成しましょう(ファンクションOCIDはご自身のものに置換してください):
| { |
| "routes": [ |
| { |
| "path": "/hello", |
| "methods": [ |
| "GET" |
| ], |
| "backend": { |
| "type": "ORACLE_FUNCTIONS_BACKEND", |
| "functionId": "ocid1.fnfunc.oc1.phx..." |
| } |
| } |
| ] |
| } |
このブログポストはLimited Availability期間のやり方で説明しているので手で作成したJSONでエンドポイントを定義する必要がありますが、GA後にはコンソールUIからかんたんに定義することができるようになります。
次に、Gateway詳細ページのサイドバーから'Deployments'をクリック。
そして'Deploy API'をクリック。
デプロイメントに名前をつけて、作成した spec.json を選択してパスのプレフィックスを入力します。
'Deploy'をクリックしてちょっと待てばデプロイメントは完了です。
Gatewayのテスト
Gateway詳細のページで、エンドポイントを見てみましょう。
ファンクションをテストするため、このエンドポイントをコピーしたものに spec.json で定義したパスを追加して、実行してみましょう!
| $ curl -i -X GET https://[redacted].apigateway.us-phoenix-1.oci.customer-oci.com/v1/hello |
| HTTP/1.1 200 OK |
| Date: Fri, 22 Nov 2019 15:04:11 GMT |
| Content-Type: application/json |
| Connection: keep-alive |
| Content-Length: 25 |
| Server: Oracle API Gateway |
| Strict-Transport-Security: max-age=31536000 |
| X-XSS-Protection: 1; mode=block |
| X-Frame-Options: sameorigin |
| X-Content-Type-Options: nosniff |
| opc-request-id: /429E9723BB6BED8DB8D237876894DDF6/3E4A5D8760D59242A98AB8A91E2B0107 |
| |
| {"message":"Hello World"} |
これはAPI Gatewayを使ってできることのほんのさわりです。デプロイメント仕様を拡張して他のファンクションや(Oracle Cloud上や外部の)HTTPエンドポイントをカバーしたり、レート制限や認証などを行うこともできます。