こんにちは、上野です。
Lambda関数をワンクリックでURL公開できる機能が出ました!
今までのLambda
Lambda関数を(AWS認証無しの)HTTPS経由で実行するには、Lambdaの前段にAmazon API Gatewayを設置する必要がありました。 API Gatewayは便利で高機能なのですが、設定項目も多く、初めて触る方には難しい部分もあるかと思います。
今回の機能で、Lambdaのメニューから機能をONにするだけHTTPS公開できるようになりました。
やってみる
Lambdaの作成画面に、「関数URLを有効化」のメニューが追加されているので、これをONにします。
初期状態では認証が必要なAWS_IAMが選択されていますが、今回はまずどれだけ簡単に公開できるかを試すため、NONEを選択します。
※画面のとおり、URLを使用して全世界からLambdaをURL経由で実行できるようになるため、設定時は注意が必要です。
コードは以下のとおり初期状態からテキスト文言を変えただけです。
import json def lambda_handler(event, context): return { 'statusCode': 200, 'body': json.dumps('This is Public URL Lambda!') }
この状態で関数URLにアクセスすると、
以下のようにコードに書いた内容がブラウザで返ってきます。爆速でLambdaをURLとして公開できましたね。
他の機能も試していきます。
IAM認証
IAM認証をONにして、認証を使用したアクセスを試してみます。
ONの状態でURLにアクセスすると、以下のようにエラーとなります。
ドキュメントには、AWS Signature Version 4 (SigV4)を使用してアクセスしましょうと説明があります。今回はPostmanを使用して試してみます。
Authorizationの設定で、TypeにAWS Signatureを選択すると、AWSの認証情報入力欄が表示されます。IAMユーザーのアクセスキー、AWS SSOの一時認証情報、IAMロールを使用した一時キー(参考)いずれかを取得してその内容を入力します。
この状態でLambdaのURLへアクセスすると、いかのように結果が表示されます。認証できていることがわかりますね。
どんな情報がLambdaに渡るの?
以下のようにLambdaのコードを修正して、実際にLambdaに渡されるデータevent
を表示してみます。
import json def lambda_handler(event, context): return { 'statusCode': 200, 'body': json.dumps(event, indent=2) }
まずは以下のようにURLのクエリストリングにパラメータを渡してみます。(hogehogeの部分にURLのIDが入ります)
curl https://hogehoge.lambda-url.ap-northeast-1.on.aws/?param1=hoge
{ "version": "2.0", "routeKey": "$default", "rawPath": "/", "rawQueryString": "param1=hoge", "headers": { "x-amzn-trace-id": "Root=1-624efbbc-13cb25d619ceadfe0cb469bc", "x-forwarded-proto": "https", "host": "hogehoge.lambda-url.ap-northeast-1.on.aws", "x-forwarded-port": "443", "x-forwarded-for": "1.2.3.4", "accept": "*/*", "user-agent": "curl/7.68.0" }, "queryStringParameters": { "param1": "hoge" }, "requestContext": { "accountId": "anonymous", "apiId": "hogehoge", "domainName": "hogehoge.lambda-url.ap-northeast-1.on.aws", "domainPrefix": "hogehoge", "http": { "method": "GET", "path": "/", "protocol": "HTTP/1.1", "sourceIp": "1.2.3.4", "userAgent": "curl/7.68.0" }, "requestId": "21e5f8ee-bf99-4643-8f19-386978967955", "routeKey": "$default", "stage": "$default", "time": "07/Apr/2022:14:57:00 +0000", "timeEpoch": 1649343420924 }, "isBase64Encoded": false }
headers情報等、リクエスト関連の情報とともに、クエリストリングのデータはqueryStringParameters
に入っていました。
続いてPOSTでJSONのデータを送信。
curl -X POST \ 'https://hogehoge.lambda-url.ap-northeast-1.on.aws/' \ -H 'content-type: application/json' \ -d '{ "example": "test" }'
{ "version": "2.0", "routeKey": "$default", "rawPath": "/", "rawQueryString": "", "headers": { "x-amzn-trace-id": "Root=1-624efdf3-13cc447566739b4c555c2b54", "x-forwarded-proto": "https", "host": "hogehoge.lambda-url.ap-northeast-1.on.aws", "x-forwarded-port": "443", "content-type": "application/json", "x-forwarded-for": "1.2.3.4", "accept": "*/*", "user-agent": "curl/7.68.0" }, "requestContext": { "accountId": "anonymous", "apiId": "hogehoge", "domainName": "hogehoge.lambda-url.ap-northeast-1.on.aws", "domainPrefix": "hogehoge", "http": { "method": "POST", "path": "/", "protocol": "HTTP/1.1", "sourceIp": "1.2.3.4", "userAgent": "curl/7.68.0" }, "requestId": "ee55df23-4c65-4bcf-b161-7a6b7f78d291", "routeKey": "$default", "stage": "$default", "time": "07/Apr/2022:15:06:27 +0000", "timeEpoch": 1649343987925 }, "body": "{ \"example\": \"test\" }", "isBase64Encoded": false }
POSTしたデータはbody
に入っていました。
送られてきたデータをLambdaで処理、という実装も簡単にできそうです。
CORS
デフォルト状態ではCORSが無効のため、S3WEBホスティング等に格納したJavascriptコンテンツから、Lambda URLを呼び出すとエラーになります。ここもLambda URLの設定で簡単に解決できるので、試してみます。
以下のようにhtml上のボタンを押下すると、Lambda URLを呼び出すHTML(+Javascript)をS3のWEBホスティング上に格納します。
<head> <title></title> <script language="javascript" type="text/javascript"> function execLambda() { const xhr = new XMLHttpRequest(); const url = 'https://hogehoge.lambda-url.ap-northeast-1.on.aws/'; xhr.open('GET', url); xhr.send(); } </script> </head> <body> <input type="button" value="Exec" onclick="execLambda();"/><br /> <br /> <div id="output"></div> </body> </html>
ボタンを押下すると、以下のようにCORSエラーとなります。
これをCORSを有効にすると・・(今回はONにするだけで各設定は変更しません)
以下のようにLambdaから正常に応答が返ってきます。
API Gatewayとの比較
公式アナウンスブログにも書かれていますが、API Gatewayには以下のような機能があるのでこれを使いたい場合はAPI Gateway+Lambdaで実装したほうが良さそうです。
- リクエスト検証機能
- API Keyによる認証
- 使用量プランによる流量制御
- AWS WAFの使用
- カスタムドメイン
料金について
Lambda function URLsの料金はかからず、Lambdaの実行料金に含まれます。つまり(URLの追加設定分は)無料。嬉しいですね。
まとめ
かなり嬉しい&大きなアップデートだと思います。自分は最近Slack APIのEvent Subscriptionsを使用してAPI Gateway経由でLambdaを使用していたのですが、そういったレベルであればLambda function URLsで充分かと思います。 AWS SAMやCDK等のIaCツールを使用すればそれなりに簡単にAPI Gatewayも設定できるのですが、設定項目も多く、やりたいことに対して少しtoo muchな感じがあったので、サクッと処理を作りたいときにこの機能が役立ちそうです。
私はLambdaの紹介記事も書いたことがあり、そこでは「Lambdaは基本他のサービスと組み合わせて使います」と紹介していましたが、Lambda単体で使えるアップデートが来ちゃいました。
それではまた!