外部サービスからのローカル用コールバックをLambdaのビルトインHTTPSエンドポイントにした話

AWS Lambdaの組み込みHTTPSエンドポイント使ってますか?

先日*1、Lambda関数の組み込みHTTPSエンドポイント機能がリリースされました。

aws.amazon.com

これまで、Lambda関数をHTTPリクエストで実行したいと考えたらAPI Gatewayを通す必要があるところ、Lambda単体で行えるようになった形です。

プライベートでAzure Functionの同様機能を愛用していた身としては待望の機能でした。

というわけで早速? 使ってみました。

この記事は id:koudenpa が書いています。Hatena Developer Blogの記事としては小さな出来事ですが、ガンガン発信していきます!

ユースケース

Webサービスの開発に当たっては他のWebサービスと連携する場面が多々あります。

連携の手法の1つとして「インターネットに公開したエンドポイントにコールバックしてもらう」というものがあります。当然これを受けるにはインターネットにエンドポイントを公開しなくてはなりません。

インターネット上にWebサービスをホスティングしている環境なら特に問題はありません。しかし、ローカル環境での開発中はどうでしょうか? 自然にはエンドポイントは作られません。

ngrokのようなサービスを使ってローカル環境をインターネットに公開すればいい? 面倒くさいし、非エンジニア(ローカル環境を動かしながらデザイナーがデザインする、のような場面もあります)にとっては設定のハードルも高いです。

この状況に対して、簡易的にコールバックを受けるためにダミーのエンドポイントを設けていました。

1つのエンドポイントを用意するために、PaaSで。

ちょっと大仰ですよね。LambdaのビルトインHTTPSエンドポイントなら小さく用意できるのではないか? と考えて試してみた次第です。

とても簡単な実装

スタブ応答の関数コード。

exports.handler = async (event) => {
    console.info(JSON.stringify(event))
    const response = {
        statusCode: 200,
        body: 'OK',
    };
    return response;
};

関数を発行するためのTerraformコード。

# 関数本体
resource "aws_lambda_function" "callback_for_local" {
  function_name = "callback-for-local"

  filename         = data.archive_file.callback_for_local.output_path
  source_code_hash = data.archive_file.callback_for_local.output_base64sha256

  role    = aws_iam_role.callback_for_local.arn
  handler = "index.handler"
  runtime = "nodejs16.x"
}

# 先のJavaScriptコードが格納されているディレクトリを配置するためのデータ
data "archive_file" "callback_for_local" {
  type        = "zip"
  source_dir  = "callback_for_local/function"
  output_path = "callback_for_local/function.zip"
}

# このリソースの宣言でLambda関数のHTTPSエンドポイントが有効になる
resource "aws_lambda_function_url" "callback_for_local" {
  function_name      = aws_lambda_function.callback_for_local.function_name
  authorization_type = "NONE"
}

# ロールは基本的なLambda関数と同様
resource "aws_iam_role" "callback_for_local" {
  name = "callback_for_local"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "callback_for_local_basic_execution" {
  role       = aws_iam_role.callback_for_local.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

ほぼこれだけ!*2 これだけでこんなURLhttps://abcxyz.lambda-url.ap-northeast-1.on.aws/のHTTPSエンドポイントが出来上がります。

あとはこのURLをローカル環境で使うコールバック先に指定しておけばよいです。

CloudWatch Logsでコールバックされたログも見られます。

まとめ?

ちょっとした処理をHTTPリクエストで行いたいときには便利。おススメ機能です。

*1:2022年4月上旬は先日と言えるのか?

*2:AWSプロバイダの設定などは別途必要です