HTTPSでLambdaを起動:AWS Lambda Function URLs を使ってみる

どうも、Lambda大好きな寺内です。

Lambdaをトリガー起動ではなく外部から起動したい時、API Gatewayへアクセスし、API GatewayがLambdaをキックする方法が一般的でした。
でも、起動するためだけにAPI Gatewayを作るのは面倒くさいと思っていた方も多いのではないでしょうか。
そんな方に朗報です。LambdaがURLを直接持つことができるようになりました。

AWS Lambda Function URLs: Lambda 関数用の組み込み HTTPS エンドポイント

早速やってみましょう。

URL付き関数の作成

Lambda関数の作成画面で、「詳細設定」を見ると「関数URLを有効化」というチェックボックスができています。

それをONにすると「認証タイプ」が選択できます。「AWS IAM認証」か「認証なし」です。
IAM認証済のHTTPリクエストを発行するには、署名付きリクエストヘッダを付ける必要があります。
それは少々複雑ですので、ここでは認証なしの「None」を選択します。

作成ボタンを押し関数ができあがると、概要欄にURLが記載されています。

設定画面では、「関数URL」というメニューが追加されています。
この編集画面で、認証方法やCORS設定を変更することができます。

以下のような関数を作り、Lambda実行時に発生するイベントを観測します。

import json

def lambda_handler(event, context):
    print(json.dumps(event))
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

アクセスしてみる

CloudShellからcurlコマンドで上記のURLにアクセスしてみます。

$ curl https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws/
"Hello from Lambda!"

なお、認証方法をAWS IAMに変更してアクセスすると、Forbiddenが返ってきます。

$ curl https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws/
{"Message":"Forbidden"}

発生するイベント

Lambda側で取得できるイベント情報を、CloudWatch Logsで確認してみましょう。
先程のcurlコマンドでアクセスしたときのログは以下のようにが出ます。

{
    "version": "2.0",
    "routeKey": "$default",
    "rawPath": "/",
    "rawQueryString": "",
    "headers": {
        "x-amzn-trace-id": "Root=1-6257d86b-69c9a858353b08756db3a66f",
        "x-forwarded-proto": "https",
        "host": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws",
        "x-forwarded-port": "443",
        "x-forwarded-for": "3.91.80.211",
        "accept": "*/*",
        "user-agent": "curl/7.79.1"
    },
    "requestContext": {
        "accountId": "anonymous",
        "apiId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "domainName": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws",
        "domainPrefix": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "http": {
            "method": "GET",
            "path": "/",
            "protocol": "HTTP/1.1",
            "sourceIp": "3.91.80.211",
            "userAgent": "curl/7.79.1"
        },
        "requestId": "da0c5b1c-a2a8-47ce-b0aa-4aa74bb54ce0",
        "routeKey": "$default",
        "stage": "$default",
        "time": "14/Apr/2022:08:16:43 +0000",
        "timeEpoch": 1649924203704
    },
    "isBase64Encoded": false
}

パラメータ渡し

呼び出し側からパラメータを渡すときは、URLに記載する場合とヘッダに記載する場合があります。
ヘッダに追加した param3は、 "headers" に追加されます。
URLパラメータとして渡した param1param2"queryStringParameters" の中に入ります。

$ curl -H 'param3:piyo' 'https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws/?param1=hoge&param2=fuga'

CloudWatch Logsで以下のように確認できます。

{
    "version": "2.0",
    "routeKey": "$default",
    "rawPath": "/",
    "rawQueryString": "param1=hoge&param2=fuga",
    "headers": {
        "x-amzn-trace-id": "Root=1-6258f919-3441ae34557cc6bd54aaf0a3",
        "x-forwarded-proto": "https",
        "host": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws",
        "x-forwarded-port": "443",
        "x-forwarded-for": "13.230.240.20",
        "param3": "piyo",
        "accept": "*/*",
        "user-agent": "curl/7.79.1"
    },
    "queryStringParameters": {
        "param1": "hoge",
        "param2": "fuga"
    },
    "requestContext": {
        "accountId": "anonymous",
        "apiId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "domainName": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.lambda-url.us-east-1.on.aws",
        "domainPrefix": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "http": {
            "method": "GET",
            "path": "/",
            "protocol": "HTTP/1.1",
            "sourceIp": "13.230.240.20",
            "userAgent": "curl/7.79.1"
        },
        "requestId": "0e8dbb3f-07b9-4ad3-9b56-6922b36c6a1f",
        "routeKey": "$default",
        "stage": "$default",
        "time": "15/Apr/2022:04:48:25 +0000",
        "timeEpoch": 1649998105318
    },
    "isBase64Encoded": false
}

注意事項

Lambda Function URLsは、インターネット側から自由にアクセスできる反面、セキュリティ上の大穴になる可能性もあります。

このURLへのアクセスは、Lambda関数が通常使うネットワークとは異なりAWSの管理側ネットワークを使いアクセスします。以下のように利用者側で接続を抑制することはできません。

  • 閉じられたVPC内に設置しているLambda関数にも、インターネットからこのURLでアクセスできます。
  • URLへの接続は、Lambda関数に付与したセキュリティグループの制限を受けません。

こうしたことから、Lambda Function URLsの利用は注意が必要です。

いずれ改善されるかもしれませんが、今のところこの機能の利用範囲は限られそうです。

 

とはいえ、便利な機能です。Lambdaの活用範囲が広がったのではないでしょうか。
ますますの発展に期待も膨らみます。

タイトルとURLをコピーしました