こんにちは。SCSKの林です!
AWS LambdaでHTTPSエンドポイントが使えるようになったようですね。
Google CloudのCloud Functionsの方は以前からHTTPトリガー機能があるのは知っていましたが、今回改めて検証してみました!
Cloud Functionsって?
出典:Cloud Functions
ふむふむ。Google Cloudのサーバーレスでコードを実行できるサービスですね。つまりはAWSでいうところのAWS Lambda。
ベータ版がリリースされたのは2017年3月でその当時からHTTPトリガー(HTTPエンドポイント)は利用できたようです。
イベントトリガー
トリガーはこれら⇩が設定できるそうです。以下二つのイベントトリガーを選択することができます。
イベントトリガー種類
|
説明
|
---|---|
HTTP関数 |
|
バックグラウンド関数 |
|
関数作ってみた
特に難しいことはなく、トリガーでHTTPを選択することでエンドポイントが作成できます。
認証の要否は作成時に指定した設定を後から変えることはできませんでした。
※ドキュメントを確認したらデプロイ後に未認証の呼び出しを許可する方法もありました。
(関数の権限設定で「allUsers」に「Cloud Functions起動元ロール」を付与)
Hello World!
関数作成時にランタイムを選択すると、選択したランタイムのサンプルが自動で入力されます。
今回はPython3.9で試しました。
def hello_world(request): """Responds to any HTTP request. Args: request (flask.Request): HTTP request object. Returns: The response text or any set of values that can be turned into a Response object using `make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`. """ request_json = request.get_json() if request.args and 'message' in request.args: return request.args.get('message') elif request_json and 'message' in request_json: return request_json['message'] else: return f'Hello World!'
サンプルのソースコードをそのままデプロイします。
HTTPSエンドポイントURLは関数の詳細画面のトリガータブから確認できます。
URLは「https://<リージョン名>-<プロジェクトID>.cloudfunctions.net/<関数名>」になるようです。
試しに叩いてみました。
$ curl https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction Hello World! $
パラメーターをつけるとこんな感じです。
<GET>
$ curl https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction?message=sendparam
sendparam
$
<POST>
$ curl -X POST -H 'Content-Type: application/json' -d '{ "message": "sendparam" }' \
> https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction
post_param
$
レスポンスヘッダーを表示するとこんな感じです。
$ curl -i https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction HTTP/2 201 access-control-allow-origin: * content-type: text/html; charset=utf-8 function-execution-id: xxxxxxxxxx x-cloud-trace-context: xxxxxxxxxxxxxxxxxxxx;o=1 date: Fri, 15 Apr 2022 09:34:48 GMT server: Google Frontend content-length: 13 Hello World!! $
ブラウザだとこんな感じ。
CORSを有効にしてみる
CORS設定前
Google Chromeの開発者ツールを使って、ブラウザ上から動的にCloud Functionsへアクセスしてみると、以下のようにCORSエラーが発生します。
CORS対応の方法については公式ドキュメントにコードサンプルが載っています。
LambdaのようにGUI上で設定することはできないようですね。
def hello_world(request): request_json = request.get_json() headers = { 'Access-Control-Allow-Origin': '*' } if request.args and 'message' in request.args: return request.args.get('message') elif request_json and 'message' in request_json: return request_json['message'] else: return ("Hello World!!", 200, headers)
CORS設定後
エラーが消えました。
IAM認証を有効にしてみる
cloudfunctions.functions.invoke
権限を付与されているアカウントのみ実行を許可します。
認証なしでアクセスするとはじかれます。
$ curl https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction-IAM <html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Your client does not have permission to get URL <code>/testFunction-IAM</code> from this server.</h2> <h2></h2> </body></html> $
コマンドラインだとわかりにくいので、ブラウザでアクセスするとこんな感じ。
認証ありでアクセス
HeaderにIDトークンを含めることで認証できます。
$ curl -H "Authorization: bearer $(gcloud auth print-identity-token)" \ https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction-IAM Hello World! $
プログラムから呼び出す場合はサンプルコードが公式ドキュメントに載っているのでそちらを参照ください。
参考:呼び出しの認証 – プログラムによるトークンの生成
その他
接続タブにこんな設定がありました。
VPC内部など、限られたトラフィックのみ許可する設定ですね。
「内部トラフィックのみ許可」を設定して実行してみたら、ちゃんとはじかれました。
$ curl -i https://asia-northeast1-xxxxxxxxxx.cloudfunctions.net/testFunction HTTP/2 403 x-appengine-city: ? x-appengine-country: TW x-appengine-citylatlong: 0.000000,0.000000 x-appengine-region: ? content-length: 235 content-type: text/html; charset=UTF-8 date: Fri, 15 Apr 2022 09:38:21 GMT <html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Access is forbidden.</h2> <h2></h2> </body></html> $
最後に
Cloud FunctionsのHTTPSエンドポイント機能を紹介しました!
個人的な感想としては、LambdaのHTTPSエンドポイントとそんなに変わらないかなーと感じました。
Cloud Functionsは今日紹介した以外にもCloud Storage、Pub/Subなど様々なサービスと簡単に統合できるので、ぜひいろいろな機能を試してみてください!!