AWS

SAMを使用したサーバーレスアプリ

スポンサーリンク
SAMを使ってAPI GatewayとLambdaでサーバレスアプリを作成する AWS
スポンサーリンク
スポンサーリンク

SAMを使ってAPI GatewayとLambdaでサーバーレスアプリケーションを作成する

以下のページで、API GatewayとLambdaを使ったサーバーレスアプリを作成する方法を取り上げましたが、今回はSAMを使用して、同様の構成を再現したいと思います。

SAM(Serverless Application Model)とは、AWSが提供するサーバーレスアプリケーションアプリ開発用フレームワークです。

AWS サーバーレスアプリケーションモデル (SAM、Serverless Application Model) は、サーバーレスアプリケーション構築用のオープンソースフレームワークです。迅速に記述可能な構文で関数、API、データベース、イベントソースマッピングを表現できます。 (中略) デプロイ中、SAM が SAM 構文を AWS CloudFormation 構文に変換および拡張することで、サーバーレスアプリケーションの構築を高速化することができます。

AWS サーバーレスアプリケーションモデル

本ページでは、AWS公式のチュートリアル「チュートリアル: Hello World アプリケーションのデプロイ」の手順に従ってSAMを確認します。

構築する環境

Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Diagram of serverless app using SAM.

LambdaとAPI Gatewayを使用したサーバーレスアプリ」と同様の環境を構築します。

今回作成するアプリケーションは以下の設定で作成します。

  • アプリケーション名:fa-006
  • Lambda関数のランタイム環境:Python3.8

SAMアプリ作成

AWS SAM CLIでアプリケーションを作成します。

同ツールを未インストールの場合は「AWS SAM CLI のインストール」をご確認ください。

$ sam init
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1
What package type would you like to use?
        1 - Zip (artifact is a zip uploaded to S3)
        2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1

Which runtime would you like to use?
        1 - nodejs12.x
        2 - python3.8
        3 - ruby2.7
        4 - go1.x
        5 - java11
        6 - dotnetcore3.1
        7 - nodejs10.x
        8 - python3.7
        9 - python3.6
        10 - python2.7
        11 - ruby2.5
        12 - java8.al2
        13 - java8
        14 - dotnetcore2.1
Runtime: 2

Project name [sam-app]: fa-006

Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates

AWS quick start application templates:
        1 - Hello World Example
        2 - EventBridge Hello World
        3 - EventBridge App from scratch (100+ Event Schemas)
        4 - Step Functions Sample App (Stock Trader)
        5 - Elastic File System Sample App
Template selection: 1

    -----------------------
    Generating application:
    -----------------------
    Name: fa-006
    Runtime: python3.8
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .
Code language: Bash (bash)

SAM設定ファイル

以下のURLに、SAMのテンプレートファイルを配置します。

awstut-fa/template.yaml at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

テンプレートファイルのポイント解説

今回の環境を構成するための、テンプレートファイルのポイントを取り上げます。

Lambda関数はAWS::Serverless::Functionで定義する

SAMでLambda関数を定義します。

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          #Type: Api
          Type: HttpApi
          Properties:
            Path: /hello
            Method: get
Code language: YAML (yaml)

CloudFormationでは、Typeプロパティで作成するリソースのタイプを指定します。通常、Lambda関数を定義する場合は「AWS::Lambda::Function」を使用しますが、SAMの記法に従うと「AWS::Serverless::Function」となります。

CodeUriプロパティで実行するスクリプトが設置されているディレクトリPATHを指定します。PATHの指定は本テンプレートファイルからの相対PATHで指定することが可能です。今回は本テンプレートファイルと同じ位置に設置されている「hello_world」ディレクトリにスクリプトを設置するという意味となります。

HandlerプロパティはLambda関数が呼び出された際に、実際に実行する関数を指定するパラメータです。「app.lambda_handler」と指定することで、先述の「hello_world」ディレクトリに設置されているapp.pyファイル内の、lamabda_handler関数を実行するという意味になります。

Runtimeプロパティは関数のランタイム環境を指定するパラメータです。今回はPython3.8で実行するように指定します。

Eventsプロパティは本関数に関連付くイベントを定義することができます。

この関数をトリガーするイベントを指定します。イベントは、1 つのタイプと、そのタイプに依存する一連のプロパティで構成されます。

AWS::Serverless::Function

今回は本プロパティを使用して、本関数に紐づくAPI Gatewayを定義します。

Eventsプロパティ内のTypeプロパティで、作成するリソースを指定できます。

このイベントマッピングのプロパティを記述するオブジェクト。プロパティのセットは、定義された Type に準拠する必要があります。

Type: S3|SNS|Kinesis|DynamoDB|SQS|Api|Schedule|CloudWatchEvent|EventBridgeRule|CloudWatchLogs|IoTRule|AlexaSkill|Cognito|HttpApi|MSK|MQ

EventSource

今回はHTTP APIタイプのAPI Gatewayを作成しますので、「HttpApi」を指定します。

Propertiesプロパティで作成するリソースの各種パラメータを指定します。

PathおよびMethodプロパティはAPI Gatewayのルートに関するパラメータです。今回は作成されるエンドポイントの「/hello」にGETでアクセスされた場合、本関数が実行されるように指定します。

なお実行する関数の内容ですが、「LambdaとAPI Gatewayを使用したサーバーレスアプリ」と同様ですので、そちらをご確認ください。

SAMアプリケーションデプロイ

AWS SAM CLIでビルドおよびデプロイします。

まずビルドします。

$ sam build --use-container
Starting Build inside a container
Building codeuri: hello_world/ runtime: python3.8 metadata: {} functions: ['HelloWorldFunction']

Fetching amazon/aws-sam-cli-build-image-python3.8 Docker container image...................................................................................................................................................................................................................................................................
Mounting /your-directory/hello_world as /tmp/samcli/source:ro,delegated inside runtime container

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
    
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Code language: Bash (bash)

use-containerオプションを使用することで、アプリケーションのビルドをDockerの専用コンテナ内で実施することができます。

関数がネイティブにコンパイルされた依存関係を持つパッケージに依存する場合は、このオプションを使用して Lambda に似た Docker コンテナ内で関数を構築します。

sam build

今回で言いますと、ランタイム環境にPython3.8をしていますので、CLIを実行するローカルに同環境が用意されている必要があります。しかし本オプションを使用することで、ビルドはコンテナ内で完結しますので、ローカル環境を気にする必要はありません。

続いてアプリケーションのデプロイに進みます。

$ sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Not found

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: fa-006
        AWS Region [us-east-1]: 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
        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]: 

....

        Deploying with following values
        ===============================
        Stack name                   : fa-006
        Region                       : ap-northeast-1
        Confirm changeset            : True
        Deployment s3 bucket         : [bucket-name]
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}

Initiating deployment
=====================
HelloWorldFunction may not have authorization defined.

Waiting for changeset to be created..

CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                                LogicalResourceId                        ResourceType                             Replacement                            
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                    HelloWorldFunctionHelloWorldPermission   AWS::Lambda::Permission                  N/A                                    
+ Add                                    HelloWorldFunctionRole                   AWS::IAM::Role                           N/A                                    
+ Add                                    HelloWorldFunction                       AWS::Lambda::Function                    N/A                                    
+ Add                                    ServerlessHttpApiApiGatewayDefaultStage   AWS::ApiGatewayV2::Stage                 N/A                                    
+ Add                                    ServerlessHttpApi                        AWS::ApiGatewayV2::Api                   N/A                                    
-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:[accound-id]:changeSet/samcli-deploy1641285770/e5418e4b-792d-4e96-93ae-5d10a45ee858

Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

...

CloudFormation outputs from deployed stack
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs                                                                                                                                                         
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                                                                                   
Description         Implicit IAM Role created for Hello World function                                                                                          
Value               arn:aws:iam::[account-id]:role/fa-006-HelloWorldFunctionRole-VBT1AK5MRG5J

Key                 HelloWorldApi                                                                                                                               
Description         API Gateway endpoint URL for Prod stage for Hello World function                                                                            
Value               https://25ypbm7one.execute-api.ap-northeast-1.amazonaws.com/hello

Key                 HelloWorldFunction                                                                                                                          
Description         Hello World Lambda Function ARN                                                                                                             
Value               arn:aws:lambda:ap-northeast-1:[account-id]:function:fa-006-HelloWorldFunction-qajs4WIMSN60
-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - fa-006 in ap-northeast-1
Code language: Bash (bash)

正常にデプロイが完了しました。

デプロイのログから、今回は5つのリソースが生成されたことが確認できます。

またOutputsセクションに記載した出力内容から、今回作成されたAPI Gatewayエンドポイントは「https://25ypbm7one.execute-api.ap-northeast-1.amazonaws.com/hello」であることがわかります。

SAMアプリにアクセス

それでは実際にアクセスします。

$ curl https://25ypbm7one.execute-api.ap-northeast-1.amazonaws.com/hello
{"message": "hello world from Awstut !"}
Code language: Bash (bash)

正常にLambda関数の実行結果を取得することができました。

このようにSAMを使用することによって、通常のCloudFormationの記法に比べ、より簡潔にサーバーレスアプリケーションを構築することができることがわかりました。

(参考)SAMで作成された各種リソースの詳細

SAMでデプロイしたアプリケーションの各種リソースの状況を確認します。

冒頭で確認した通り、SAMはCloudFormationの変形版とも言えるサービスですので、SAMアプリケーションをデプロイすると、CloudFormationスタックが作成されます。

AWS Management Consoleからスタックの作成状況を確認します。

The list of resources created by SAM

テンプレートファイルでは直接定義していませんが、API GatewayがLambda関数を呼び出すためのPermissionと、Lambda関数に付与するIAMロールも、自動的に作成されていることがわかります。

Permissionの中身は以下の通りです。

Permission automatically generated by SAM

Lambda関数の呼び出しに関する条件が定義されています。今回作成したAPI Gatewayで、かつURLが/helloのGETメソッドからの呼び出しの場合のみに許可されるという内容です。

以下は作成されたIAMロールです。

IAM roles automatically created by SAM

AWS管理ポリシーAWSLambdaBasicExecutionRoleがアタッチされていることがわかります。Lambda関数を実行する上での最低限の権限を付与しているということになります。

本スタックには含まれていませんが、API Gatewayのルート・統合リソースも作成されています。

まず統合です。

Integration automatically generated by SAM

作成したLambda関数が関連づいていることがわかります。

次にルートです。

Routes automatically generated by SAM

/helloのGETメソッドに先ほどの統合が関連づいています。これらの設定が合わさってAPI Gatewayにアクセスがあった場合に、Lambda関数が実行されるという動作を実現することができます。

まとめ

SAMを使用することによって、通常のCloudFormationの記法に比べ、より簡潔にサーバーレスアプリケーションを構築することができることがわかりました。

タイトルとURLをコピーしました