AWS SAMを使ったLambdaコード開発とデプロイ手順を解説

AWS SAMを使ったLambdaコード開発とデプロイ手順を解説

Hiroyuki Kikuchi

Hiroyuki Kikuchi

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の環境差異を抑えられます。

今回の記事がご参考になれば幸いです。

この記事のシェア数

2004年大学卒業後に大手SIerにて組み込み系エンジニアとして10年従事。一度はIT業界から足を洗う形にはなるものの、2016年からSES企業にてサイドエンジニアとしてチャレンジ。2020年からLIGにジョインし、様々な案件のテクニカルディレクター並びにプロジェクトマネージャーとして参加する。

このメンバーの記事をもっと読む
10年以上の開発実績があるLIGが、最適な開発体制や見積もりをご提案します
相談する サービス概要を見る