AWS SAMで始めるサーバーレス開発: AWS SAMのチュートリアルを試してみた
はじめに
こんにちは、Shunです。
皆さん、AWS SAM(AWS Serverless Application Model 以降、SAM)を利用されたことはありますか?
SAMは、サーバーレスアプリケーションの構築と管理を簡単にするためのフレームワークです。
これはCloudFormationをベースにしており、サーバーレス開発に特化した拡張を提供しています。
AWS SAM は、AWS SAM テンプレートと AWS SAM コマンドラインインターフェイス (AWS SAM CLI) の 2 つの部分で構成されています。AWS SAM テンプレートは、サーバーレスアプリケーション用の Infrastructure as Code (IaC) の定義に最適化された簡潔な構文を提供します。AWS CloudFormation の拡張機能として、AWS SAM テンプレートを AWS CloudFormation に直接デプロイできます。これにより、AWS での広範な IaC サポートの恩恵を受けることができます。AWS SAM CLI は、AWS SAM の機能をすぐに使えるようにするデベロッパーツールです。これを使用すると、サーバーレスアプリケーションをすばやく作成、開発、デプロイできます。AWS SAM の多くの機能には、ローカル開発とクラウドテストをスピードアップする SAM Accelerate や、AWS SAM を AWS CDK や Terraform などの他のツールに拡張する SAM CLI 統合などがあります。
引用: AWS Serverless Application Model
SAMを使用すると、必要なリソース、その関係性、および設定を1つのテンプレートファイルで定義できます。SAM CLIを利用することで、これらのアプリケーションをローカルでテストしたり、AWSにデプロイしたり、管理することが可能になります。
最近、SAMを使用する機会があったので、AWSが提供するチュートリアルをもとに実際の検証を行いました。
*チュートリアル: Hello World アプリケーションのデプロイ
この記事では、チュートリアルの内容を共有します。
前提
前提条件は以下です。
- AWS CLIがセットアップ済みであること
- AWS SAM CLIがセットアップ済みであること
- Dockerがセットアップ済みであること
これらのセットアップがまだの方は、CloudShellを使用すると簡単です。
(DockerもCloudShell上で使えるようになりました。)
構成図
実施するアプリケーションの構成図は以下の通りです。
この構成を使用して、API GatewayとLambdaを構築し、hello worldメッセージをレスポンスとして受け取ります。
料金
本記事で紹介するチュートリアルでは料金は発生しません。
チュートリアル内容
以下の内容に沿って、実施します。
チュートリアル: Hello World アプリケーションのデプロイ
1. サンプルの Hello World アプリケーションを初期化する
SAMを開始するには、以下のコマンドを実行します。
$ sam init
実行すると、対話形式でセットアップ方法を選択していきます。
You can preselect a particular runtime or package type when using the `sam init` experience. Call `sam init --help` to learn more. # AWSのテンプレートを使用するか、自前のテンプレートを使用するかを聞かれます。AWSのテンプレート(1)を選択します。 Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 # AWS のどのテンプレートを使用するかを聞かれます。今回は、Hello Worldのテンプレート(1)を選択します。 Choose an AWS Quick Start application template 1 - Hello World Example 2 - Data processing 3 - Hello World Example with Powertools for AWS Lambda 4 - Multi-step workflow 5 - Scheduled task 6 - Standalone function 7 - Serverless API 8 - Infrastructure event management 9 - Lambda Response Streaming 10 - Serverless Connector Hello World Example 11 - Multi-step workflow with Connectors 12 - GraphQLApi Hello World Example 13 - Full Stack 14 - Lambda EFS example 15 - Hello World Example With Powertools for AWS Lambda 16 - DynamoDB Example 17 - Machine Learning Template: 1 # ランタイムとパッケージのタイプを聞かれます。yを選択します。 Use the most popular runtime and package type? (Python and zip) [y/N]: y # 今回は、簡単な検証のため、X-Rayは必要ありません。 Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: N # CloudWatch Application Insightsも同様に必要ありません。 Would you like to enable monitoring using CloudWatch Application Insights? For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: N # ログも取得しません。 Would you like to set Structured Logging in JSON format on your Lambda functions? [y/N]: N # プロジェクト名を入力します。本記事では、デフォルトのsam-appをプロジェクト名としています。 Project name [sam-app]:[プロジェクト名を入力]
上記の入力が終わると、GitHubから以下のようにクローンされます。
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment) ----------------------- Generating application: ----------------------- Name: sam-app Runtime: python3.9 Architectures: x86_64 Dependency Manager: pip Application Template: hello-world Output Directory: . Configuration file: sam-app/samconfig.toml Next steps can be found in the README file at sam-app/README.md Commands you can use next ========================= [*] Create pipeline: cd sam-app && sam pipeline init --bootstrap [*] Validate SAM template: cd sam-app && sam validate [*] Test Function in the Cloud: cd sam-app && sam sync --stack-name {stack-name} --watch
sam init
以降は、作成したプロジェクトのディレクトリへ移動し、作業を行います。
2. アプリケーションを構築する
次に、アプリケーションを構築します。
以下のコマンドで、関数の依存関係、プロジェクトコードやプロジェクトファイルが整理されます。
$ sam build
実行結果は以下です。
Starting Build use cache Building codeuri: /home/cloudshell-user/eto-test/hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: HelloWorldFunction requirements.txt file not found. Continuing the build without dependencies. Running PythonPipBuilder:CopySource Skipping copy operation since source /home/cloudshell-user/eto-test/hello_world does not exist Build Succeeded # 以下の場所にビルドアーティファクトとテンプレートが格納されます。 Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml # ここで次にどのようなコマンドを打てば良いのかのガイドがあります。 Commands you can use next ========================= [*] Validate SAM template: sam validate [*] Invoke Function: sam local invoke [*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch # 次の章では、以下のコマンドを用いてAWSへデプロイを行います。 [*] Deploy: sam deploy --guided
.aws-sam/build/template.yaml
の中身は以下です。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: 'sam-app Sample SAM Template for sam-app ' Globals: Function: Timeout: 3 MemorySize: 128 LoggingConfig: LogFormat: JSON Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: HelloWorldFunction Handler: app.lambda_handler Runtime: python3.9 Architectures: - x86_64 Events: HelloWorld: Type: Api Properties: Path: /hello Method: get Metadata: SamResourceId: HelloWorldFunction Outputs: HelloWorldApi: Description: API Gateway endpoint URL for Prod stage for Hello World function Value: Fn::Sub: https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/ HelloWorldFunction: Description: Hello World Lambda Function ARN Value: Fn::GetAtt: - HelloWorldFunction - Arn HelloWorldFunctionIamRole: Description: Implicit IAM Role created for Hello World function Value: Fn::GetAtt: - HelloWorldFunctionRole - Arn
ハイライト箇所のAWS::Serverless::Function
でLambdaに関連するリソースを定義しています。
CloudFormaitonであれば、IAMリソースを定義する必要がありますが、SAMではLambdaを実行するために必要なIAMロールを自動的に生成し、適切な権限を割り当てることができます。
それにより、テンプレートの記述量を減らし、Lambdaの実行に必要な権限管理を簡単に行うことができます。
3. アプリケーションをAWSへデプロイする
以下のコマンドを使用して、AWS環境へデプロイを行います。
$ sam deploy --guided
実行すると、対話形式で諸々聞かれます。
Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Found Reading default arguments : Success Setting default arguments for 'sam deploy' ========================================= # CloudFormaitonのスタックネームを入力します。 Stack Name [sam-app]: # デプロイするリージョンを入力します。 AWS Region [ap-northeast-1]: # 変更セットの確認を問われます。 #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [Y/n]: Y # IAMを作成するか問題ないかを問われます。必要なため、Yとします。 #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: Y # ロールバックは行いたいため、Nとします。 #Preserves the state of previously provisioned resources when an operation fails Disable rollback [y/N]: N # Lambdaに権限はないが問題ないかを聞かれます。問題ないため、yとします。 HelloWorldFunction has no authentication. Is this okay? [y/N]: y # デプロイオプションの定義ファイルを作成するかを問われます。不要なため、nとします。 Save arguments to configuration file [Y/n]: n
作成するリソースの確認画面になります。問題なければ、yとします。
Looking for resources needed for deployment: Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-prvgzz2w4a1n A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False Uploading to sam-app/e3c7ec584c3e043c5b3ac0b1d166480c 551464 / 551464 (100.00%) Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : True Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-prvgzz2w4a1n Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-app/2fc3f85cfbebff18a688b21b01b463b9.template 1199 / 1199 (100.00%) Waiting for changeset to be created.. CloudFormation stack changeset ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Add HelloWorldFunctionHelloWorldPermissionProd AWS::Lambda::Permission N/A + Add HelloWorldFunctionRole AWS::IAM::Role N/A + Add HelloWorldFunction AWS::Lambda::Function N/A + Add ServerlessRestApiDeployment47fc2d5f9d AWS::ApiGateway::Deployment N/A + Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A + Add ServerlessRestApi AWS::ApiGateway::RestApi N/A ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:xxxxx:changeSet/samcli-deploy1710207813/786ffbee-9714-42eb-abee-b8d39a690789 Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: y
これで作成完了です。ハイライト箇所は次章で使用します。
2024-03-12 01:49:12 - Waiting for stack create/update to complete CloudFormation events from stack operations (refresh every 5.0 seconds) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::CloudFormation::Stack sam-app User Initiated CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Resource creation Initiated CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Eventual consistency check initiated CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd - CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d - CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd - CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d - CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_COMPLETE AWS::CloudFormation::Stack sam-app - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CloudFormation outputs from deployed stack ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Outputs ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::xxxxx:role/sam-app-HelloWorldFunctionRole-PkHjHeJFycab Key HelloWorldApi Description API Gateway endpoint URL for Prod stage for Hello World function Value https://7qt9u1y1jc.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ Key HelloWorldFunction Description Hello World Lambda Function ARN Value arn:aws:lambda:ap-northeast-1:xxxxx:function:sam-app-HelloWorldFunction-2AEAK6AzH6PM ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Successfully created/updated stack - sam-app in ap-northeast-1
4. アプリケーションを実行する
デプロイしたアプリケーションの出力を確認します。
デプロイ時にOutputs
へHelloWorldApi
が出力されています。
HelloWorldApi
へGETリクエストを送ると、以下のようにhello world
が出力されます。
$ curl https://7qt9u1y1jc.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ {"message": "hello world"}
5. 直接Lambdaを呼び出す
ここではAPIではなく、Lambdaを直接呼び出します。
以下のコマンドを打つことで、Lambdaを実行することができます。
$ sam remote invoke HelloWorldFunction --stack-name sam-app Invoking Lambda Function HelloWorldFunction START RequestId: 14f3870f-aeb0-4393-b578-c82b20cd7e61 Version: $LATEST END RequestId: 14f3870f-aeb0-4393-b578-c82b20cd7e61 REPORT RequestId: 14f3870f-aeb0-4393-b578-c82b20cd7e61 Duration: 1.07 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 30 MB {"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
6. アプリケーションを変更してAWSに同期する
以下のコマンドを打つことでローカルとAWSを同期させることができます。
$ sam sync --watch
これでローカルで変更した内容がリアルタイムでAWSへ同期されます。そのため、開発環境以外での使用は推奨されていません。
挙動を検証するために、sam-app/hello_world/app.py
を変更します。
Hello World
をHello everyone!
とします。
すると、ローカルの変更がすぐにAWS環境のLambdaへ反映されます。
$ curl https://7qt9u1y1jc.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ {"message": "hello everyone!"}
7. アプリケーションをローカルでテストする
ローカル環境へDockerがセットアップされていれば、ローカルでアプリケーションのテストを実施することができます。
まず、Lambdaのローカル環境を作成し、呼び出します。
$ sam local invoke Invoking app.lambda_handler (python3.9) Local image was not found. Removing rapid images for repo public.ecr.aws/sam/emulation-python3.9 Building image............................................................................................................................................................................................................................ Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64. Mounting /home/cloudshell-user/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: ce9f5304-4915-481e-a9e1-8fd57fa734f7 Version: $LATEST END RequestId: bc8f3fd8-1663-40de-9594-ea829efc047a REPORT RequestId: bc8f3fd8-1663-40de-9594-ea829efc047a Init Duration: 0.16 ms Duration: 81.85 ms Billed Duration: 82 ms Memory Size: 128 MB Max Memory Used: 128 MB {"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
続いて、HTTP API エンドポイントをローカルでホストし、Lambdaを呼び出します。
$ sam local start-api Initializing the lambda functions containers. Local image is up-to-date Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64. Mounting /home/cloudshell-user/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container Containers Initialization is done. Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET] You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template 2024-03-12 02:32:34 WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:3000 2024-03-12 02:32:34 Press CTRL+C to quit
ローカルのAPIエンドポイントからもhello world
のレスポンスを確認することができました。
$ curl http://127.0.0.1:3000/hello {"message": "hello world"}
8. AWSアプリケーションを削除する
最後に、作成したリソースを削除します。
以下のコマンドを実行することでリソースを削除します。
$ sam delete # 対話形式でリソースを削除してよいか確認されます。 Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y Do you want to delete the template file 20ea9ca62b8332cc08fa5c96ebf5e715.template in S3? [y/N]: y - Deleting S3 object with key c6ce8fa8b5a97dd022ecd006536eb5a4 - Deleting S3 object with key 5b3336c1cabd0374ab90521d9acb1965.template - Deleting S3 object with key 20ea9ca62b8332cc08fa5c96ebf5e715.template - Deleting Cloudformation stack sam-app Deleted successfully
さいごに
今回は、SAMのチュートリアルを一通り実施してみました。
正直、SAMのサービス概要のみではどのようなサービスかイメージができなかったのですが、実際に手を動かすことでサービスイメージを掴むことができました。
本来は、開発環境を構築する必要がありますが、CloudShellを使えば、開発環境のセットアップ無しにSAMを体験することが可能です。
是非、SAMを試してみてください。
最後まで読んでいただきありがとうございます!
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitterGoogle Cloud11冠、2024 AWS All Cert、ビール検定1冠
Recommends
こちらもおすすめ
-
【Amazon Route53】AWS CLIで特定文字列レコードを抽出してみた
2023.12.5
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16