Technology部の菊池です。
今回はAWS SAM(Serverless Application Model)を使ったローカル開発環境構築手順と、デプロイする方法について解説します。
目次
AWS SAMとは
AWS SAM(Serverless Application Model。以下、SAMと記載)は、Amazon Web Services(AWS)が提供しているフレームワークです。
SMAは「AWS SAMテンプレート」と「AWS SAMコマンドラインインターフェイス」(SAM CLI)の2つで構成されており、サーバーレスアプリケーションの作成、デプロイ、管理を簡単にするために利用されています。
SAMには以下のような機能が備わっています。
サーバーレスアーキテクチャのテンプレート化
SAMはYAMLやJSON形式のテンプレートを使用し、AWSのサーバーレスリソース(例:AWS Lambda関数、Amazon API Gatewayエンドポイント、Amazon DynamoDBテーブルなど)を簡単に定義、管理、デプロイできます。
ローカルテストとデバッグ
SAM CLIを使用すれば、ローカル環境でのテストとデバッグが容易に可能です。コードをAWSにデプロイする前に、ローカルマシンで機能とパフォーマンスをテストできます。
自動デプロイ
AWS CloudFormationを利用してリソースを自動的に作成し、アプリケーションをAWSにデプロイできます。
その他、SAMの詳細については公式ページをご覧ください。
構成について
ローカル環境
SAMを通じてローカル環境にLambda、API Gatewayを構築します。今回ソースコードは、Node.js(version16)並びにTypescriptを使う前提です。
デプロイフロー
上記のように、ローカル環境内にソースコードとSAM Templateを構築・Package化して、AWSへデプロイすることを目指します。
ローカル開発環境の構築
ここではローカルPC側で行う準備を説明します。
SAM CLIをインストール
まずはAWS SAMの公式ページからインストールをします。インストールの方法は公式ページをご参照ください。
SAM環境構築
インストール完了後、以下のようにコマンド実行して環境構築を実施してください。
console
sam init --runtime nodejs16.x --name sam-app
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Hello World Example With Powertools
3 - Multi-step workflow
4 - Standalone function
5 - Scheduled task
6 - Data processing
7 - Serverless API
8 - Serverless Connector Hello World Example
9 - Multi-step workflow with Connectors
Template: 1
Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.
Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.
Select your starter template
1 - Hello World Example
2 - Hello World Example TypeScript
Template: 2
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details
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]: y
AppInsights monitoring may incur additional cost. View https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/appinsights-what-is.html#appinsights-pricing for more details
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: nodejs16.x
Architectures: x86_64
Dependency Manager: npm
Application Template: hello-world-typescript
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
このコードを実施すると開発環境の初期状態が生成されます。フォルダ構成は以下をご参照ください。
テンプレートファイルとしてtemplate.yamlも生成されますが、いろいろと不必要な構築やoutputがされています。今回は記事の解説用に、下記の通りLambdaとapigatewayの設定のみ残すようにしました。
yaml
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
MemorySize: 128
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
Metadata: # Manage esbuild properties
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: es2020
# Sourcemap: true # Enabling source maps will create the required NODE_OPTIONS environment variables on your lambda function during sam build
EntryPoints:
- app.ts
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/"
esbuildのインストール
TypescriptからNode.jsを変換するにあたり、ビルドツール「esbuild」が必要となるためインストールします。以下コマンドを実施してください。
console
npm install -g esbuild
ビルド
続いてLambdaのコードをビルドします。buildした結果は、.aws-sam/buildに出力されますので確認してください。
console
sam build
ちなみにtemplateファイルの妥当性確認として以下のコマンドを実施すると、templateの構文にエラーがないかチェックしてくれます。こちらもあわせて実施しておくとよいです。
console
sam validate
ローカルホスト起動
以下のコマンドを実行することで、localhostの3000ポートに対してAPIを実行できる状態となります。
console
sam local start-api
環境構築時は/helloのエンドポイントのみが有効な状態となっています。そのため、以下のGetリクエストを実施した場合、{“message”:”hello world”}がレスポンスされれば、ローカル環境構築は成功です。
console
http://127.0.0.1:3000/hello
デプロイ方法
ローカル環境においてソースコード構築とUnitテストを完了したら、AWSへデプロイします。
SAM CLIを使えば、AWSへのデプロイも可能です。ただし、AWSへLambdaやAPI Gateway作成するためには、Cloudformationでこれらを作成するためのIAMのポリシーを事前に用意しておく必要があります。
IAMユーザー作成
まずは上の画像のポリシーを有したIAMユーザーを作成し、AWS CLIを使ってインポートしてください。基本的には作成したいサービスに対して、作成権限を設定するようにしましょう。各サービスはCloudformationを通じて構築されるため、Cloudformationの実行権限に関するポリシー設定も必要です。
ビルドされたソースコードやSAMのTemplateはS3へアップされるため、S3のバケットに対するファイルアップロードに関するポリシー設定も忘れないようにしてください。
IAMFullAccessについては、実際にSAMを通じてAWSへデプロイする際に必ずIAM Roleが作成を要求され、IAMロールの作成権限を含むポリシーを追加します。
なお、今回の例はFullアクセス権限ポリシーを設定するようにしましたが、セキュリティの観点から各リソースへのアクセス権限は必要に応じて制限させる方法が望ましいです。
デプロイコマンド
AWSへデプロイするためには、sam deployコマンドを実施します。初回においてはオプションとして、–guidedを入力して、ロールバックの要否など各種設定を行いましょう。
そうすることで、ローカル環境上においてtemplate.yamlが生成されるため、2度目以降はsam deployのみ実施することで、初回実施された設定内容に基づいてdeployが実施されるようになります。
console
sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
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
#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
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: n
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1x0pcwsr8wme7
A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
File with same data already exists at sam-app/7b33e513850748d9482c8e504aacefb2, skipping upload
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-1x0pcwsr8wme7
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
File with same data already exists at sam-app/aee1201c5997067c859c3db9bc7ff250.template, skipping upload
Waiting for changeset to be created..
CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-----------------------------------------------------------------------------------------------------------------------------------------------------
+ Add HelloWorldFunctionHelloWorldPermiss AWS::Lambda::Permission N/A
ionProd
+ Add HelloWorldFunctionRole AWS::IAM::Role N/A
+ Add HelloWorldFunction AWS::Lambda::Function N/A
+ Add ServerlessRestApiDeployment47fc2d5f AWS::ApiGateway::Deployment N/A
9d
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A
+ Add ServerlessRestApi AWS::ApiGateway::RestApi N/A
-----------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:changeSet/samcli-deploy1686442089/1bbbca01-15b6-4b0d-865e-caca2730d708
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2023-06-11 09:08:18 - 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::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_COMPLETE AWS::Lambda::Function HelloWorldFunction -
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::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f -
9d
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermiss -
ionProd
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermiss Resource creation Initiated
ionProd
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f Resource creation Initiated
9d
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f -
9d
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::Lambda::Permission HelloWorldFunctionHelloWorldPermiss -
ionProd
CREATE_COMPLETE AWS::CloudFormation::Stack sam-app -
-----------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------------------------------------------------------------------
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://0qeuvpr8w7.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
--------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
ソースコードのアップデートやサービス構成変更が発生した場合
ソースコードのアップデートやサービス構成変更が発生した場合、基本的にはsam buildを実施して再度、sam deploy実施してください。そうすることで、更新内容がAWSに反映されるようになります。
デプロイしたサービスを削除する方法
デプロイしたサービスを停止したい場合は、以下のコマンドを実施することでAWSから削除できます。
console
sam delete
まとめ
SAM(Serverless Application Model)を使ったLambdaコード開発並びにデプロイ手順を解説しました。あらためてまとめると、AWS SAMとSAM CLIには以下のような役割があります。
AWS SAM:Lambdaを使ったアプリケーションないしAPI開発が可能
SAM CLI:ローカル環境とAWSへの環境構築が可能
その他、API gatewayなどのサービスについても、cloudformation形式で記載が可能ですので、結果的にローカル環境とAWSの環境差異を抑えられます。
今回の記事がご参考になれば幸いです。