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