エンジニアの久保です。
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 の利用を検討してみてはいかがでしょうか。