🐟

AWS SAMを触ってみる(導入編)

2024/10/02に公開

AWS SAM is 何?

AWS Serverless Application Modelの略で、AWS上のサーバーレスアプリケーションの構築・実行をより便利にするためのフレームワークです。
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/what-is-sam.html
SAMテンプレートというものを利用することで、CloudFormationをベースとしたIaCにより、サーバーレスアプリケーションを簡単に構成することができます。
そしてSAM CLIを利用して、サーバーレスアプリケーションのビルドやデプロイ、ローカル実行などを行うことができます。

Let's SAM!

早速SAMを使って、Lambdaを作成していきましょう。
導入に関しては記事内で説明はしませんので、こちらを参照してください。
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html

sam init

適当な場所で以下のコマンドを実行し、プロジェクトを作成してください。

sam init

実行すると色々聞かれますのでお好みで。

You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

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 - 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 - DynamoDB Example
        16 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]:

Which runtime would you like to use?
        1 - aot.dotnet7 (provided.al2)
        2 - dotnet8
        3 - dotnet6
        4 - go (provided.al2)
        5 - go (provided.al2023)
        6 - graalvm.java11 (provided.al2)
        7 - graalvm.java17 (provided.al2)
        8 - java21
        9 - java17
        10 - java11
        11 - java8.al2
        12 - nodejs20.x
        13 - nodejs18.x
        14 - nodejs16.x
        15 - python3.9
        16 - python3.8
        17 - python3.12
        18 - python3.11
        19 - python3.10
        20 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 12

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 1

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: 1

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]:

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]:

Would you like to set Structured Logging in JSON format on your Lambda functions?  [y/N]:

Project name [sam-app]:

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: nodejs20.x
    Architectures: x86_64
    Dependency Manager: npm
    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

今回は簡単に、JavaScriptでHelloWorldするLambdaを作りました。

実行が完了すると、以下のようなフォルダ構成でファイルが作られます。

sam-app
    │  .gitignore
    │  README.md
    │  samconfig.toml
    │  template.yaml
    │
    ├─events
    │      event.json
    │
    └─hello-world
        │  .npmignore
        │  app.mjs
        │  package.json
        │
        └─tests
            └─unit
                    test-handler.mjs

ここでいうtemplate.yamlがSAMテンプレートになります。

SAMテンプレート

それでは作られたSAMテンプレートを確認していきましょう。

template.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

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: nodejs20.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:
  # 今回は触れないので省略~

CloudFunctionをベースとしているので、なんとなく書いてあることは理解できるかもしれません。
Resourcesの中身をいくつか見ていきましょう

HelloWorldFunction

今回作成したLambdaの名前です。

CodeUri

ビルドに含めるソースへの相対パスです。

Events

ここでLambdaのトリガーを設定できます。
初期のテンプレートではAPI Gatewayを利用して、GETメソッド/helloというパスでAPIが呼び出される構成になっています。

他にもSQSやEventBridgeなどなどが設定できます。
詳細については下記公式ドキュメントを参照してください。
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-eventsource.html

sam build

ではそのままアプリケーションをビルドしていきましょう。

sam build

というコマンドでビルドを行ってくれます。

オプションで--use-containerを付けるとコンテナを利用してビルドしてくれるので、ローカル環境を汚さずに開発が行えてとても便利です。

sam local

それではアプリケーションをローカルで実行してみましょう。
今回は2つのローカル実行方法をご紹介します。

invoke

sam local invoke

というコマンドを入力するとLambdaが実行されます。
Lambdaが複数ある場合は

sam local invoke HelloWorldFunction

のような形で指定することができます。

-eオプションでJSONを指定することで入力パラメータを渡せたりもするので、デプロイ前の動作確認としてとても便利です。

start-api

sam local start-api

というコマンドを入力するとAPIとしてLambdaが起動します。
実際にAPIとして動作確認したい場合なんかに便利です。

sam deploy

では動作確認が終了した、ということにして、AWSにデプロイしてみましょう。

sam deploy --guided

--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 [us-east-1]: 
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [Y/n]:
        #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]:
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]:
        HelloWorldFunction has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:y
~省略~

Successfully created/updated stack - sam-app in us-east-1
のような表示が出たらデプロイ完了です!

Save arguments to configuration file [Y/n]:でYesと答えたので、samconfig.tomlに先ほど入力された内容が保存されています。
次回からは--guidedオプションを入れなくても、こちらのファイルを読み込んで前回と同じようにデプロイしてくれます。

まとめ

SAMを使うことで、とても簡単にLambdaの構成からローカル実行、デプロイまでができることがわかりました。
今回は一発目の記事ということもあり、簡単なことしか試しませんでしたが、今後もっと実践的な構成を試していきたいと思います。

参考

https://zenn.dev/fusic/articles/d2a307b12e5288
https://zenn.dev/k_tana/articles/2023-08_how-to-use-of-aws-sam

Discussion