エンジニアの久保です。
2022/4 に AWS Lambda の関数 URL(AWS Lambda FunctionURLs)がリリースされました。この機能を使うと、Lambda を使った WebAPI を作成する際に必要だった Amazon API Gateway が不要になります。
今回はこの関数 URL を AWS SAM(AWS Serverless Application Model)から利用してみました。

作業環境

AWS SAM CLI は次のバージョンを利用しています。

% sam --version
SAM CLI, version 1.51.0

プロジェクトの作成

sam init でプロジェクトを作成します。
今回はおなじみの hello-world テンプレートを利用しています。

% sam init \
  --runtime nodejs16.x \
  --dependency-manager npm \
  --app-template hello-world \
  --tracing \
  --name sam-app

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

このとき作成される SAM のテンプレート template.yml は以下のようになっています。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    Tracing: Active
  Api:
    TracingEnabled: True

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs16.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

関数 URL(Function URLs)を有効にする

それでは、関数 URLを 有効にしてみます。
template.yml の Resources → HelloWorldFunction のセクションに FunctionUrlConfig を追加します。

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs16.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get
      FunctionUrlConfig:
        AuthType: NONE

FunctionUrlConfig については、ドキュメントに詳細が書かれています。
今回は特に認証なしでアクセスできるようにしたいので、 AuthType: NONE を設定しています。

また、作成された関数URLを確認できるように、Outputsのセクションで以下のように HelloWorldFunctionUrl を追記します。

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn
  HelloWorldFunctionUrl:
    Description: "Function URLs endpoint"
    Value: !GetAtt HelloWorldFunctionUrl.FunctionUrl

デプロイして動作確認

それではデプロイして動作を確認してみましょう。

まずはビルドします。

% sam build

続いてデプロイします。

% sam deploy \
    --template-file template.yaml \
    --stack-name sam-app \
    --resolve-s3 \
    --capabilities CAPABILITY_IAM

デプロイが完了するとデプロイされたスタックが表示されます。

CloudFormation outputs from deployed stack
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::000000000000:role/sam-app-HelloWorldFunctionRole-114EYP0OM26CS

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://jlw92sp9w4.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

Key                 HelloWorldFunctionUrl
Description         Function URLs endpoint
Value               https://rwu4uvcrsa5yxsecf3dliu2fpu0vmrty.lambda-url.ap-northeast-1.on.aws/

Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:000000000000:function:sam-app-HelloWorldFunction-Ynj767nxr0Xw
-----------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

動作確認

それでは実際に動かしてみます。

API Gateway のエンドポイント

hello-world テンプレート に最初から含まれている API Gateway のエンドポイントに接続してみます。

% curl https://jlw92sp9w4.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message":"hello world"}

関数 URL(Function URLs)のエンドポイント

次に、今回追加した関数 URL のエンドポイントに接続してみます。

% curl https://rwu4uvcrsa5yxsecf3dliu2fpu0vmrty.lambda-url.ap-northeast-1.on.aws/
{"message":"hello world"}

API Gateway のエンドポイントと同様に動作しました!

今回の template.yml の最終結果

参考までに、今回利用した SAM テンプレート template.yml の最終結果を以下に記載します。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    Tracing: Active
  Api:
    TracingEnabled: True

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs16.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get
      FunctionUrlConfig:
        AuthType: NONE

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn
  HelloWorldFunctionUrl:
    Description: "Function URLs endpoint"
    Value: !GetAtt HelloWorldFunctionUrl.FunctionUrl

まとめ

今回は AWS Lambda の関数 URL(AWS Lambda Function URLs)を AWS SAM から利用する方法を紹介しました。

現在社内で進行しているプロジェクトでは関数 URL を積極的に利用しています。
先述の通り、従来の API Gateway + Lambda で構成される WebAPI の場合、Lambda 関数 URL を使った構成へ変更することで API Gateway が不要になります。
弊社の場合、Lambda 関数 URL を利用することで月に $30 ほど節約できるケースがありました。

API Gateway で提供される機能を必要としていない場合は、関数 URL の利用を検討してみてはいかがでしょうか。

Join Us !

ウエディングパークでは、一緒に働く仲間を募集しています!
ご興味ある方は、お気軽にお問合せください(カジュアル面談から可)

採用情報を見る