2
0

More than 1 year has passed since last update.

AWS SAMを使用してLambda+ApiGatewayのAPIをデプロイ

Last updated at Posted at 2023-08-05

SAM(Serverless Application Model)とは

サーバーレスアプリケーション構築用のオープンソースフレームワーク
https://aws.amazon.com/jp/serverless/sam/

簡単にまとめると

  • Lambda開発の手間を削減
  • ローカル上でLamabdaを再現してテスト、デバッグができる
  • SAM 構文のテンプレートでサーバーレスアプリケーションの構築を高速化

実行環境

Windowsで実施
AWS SAMを使用するためのCLIをインストール

$ sam --version
SAM CLI, version 1.94.0

前提
Ubuntu 環境導入済み
Docker 導入済み
AWS CLI 導入済み

プロジェクト作成

sam initコマンドでアプリケーションの初期設定
--runtimeオプションでLamabdaのランタイムを設定(今回はpython3.9)

$ cd [作業ディレクトリ] #カレントディレクトリ配下にプロジェクトが作成されるためあらかじめ移動しておく

$ sam init --runtime python3.9
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 for AWS Lambda
        3 - Infrastructure event management
        4 - Multi-step workflow
        5 - Lambda EFS example
        6 - Serverless Connector Hello World Example
        7 - 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 pip.
We will proceed copying the template using pip.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: 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]: n

Project name [sam-app]: sample-app

    -----------------------
    Generating application:
    -----------------------
    Name: sample-app
    Runtime: python3.9
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .
    Configuration file: sample-app\samconfig.toml

    Next steps can be found in the README file at sample-app\README.md


Commands you can use next
=========================
[*] Create pipeline: cd sample-app && sam pipeline init --bootstrap
[*] Validate SAM template: cd sample-app && sam validate
[*] Test Function in the Cloud: cd sample-app && sam sync --stack-name {stack-name} --watch

デプロイ確認までしたいので今回は1 - Hello World Exampleを選択し、ガイド通りに進みプロジェクト名を入力

プロジェクトディレクトリが作成されているのでカレントディレクトリを移動&構造を確認
(今後コマンドはsample-app/ で実施)

sample-app
│  .gitignore
│  README.md
│  samconfig.toml
│  template.yaml #samのテンプレートファイル
│  __init__.py
│
├─events
│      event.json #テストで使用するイベント
│
├─hello_world #アプリのディレクトリ
│      app.py 
│      requirements.txt
│      __init__.py
│
└─tests
    │ testsは省略

template.yamlのResourcesセクション

template.yaml
Transform: AWS::Serverless-2016-10-31

SAMのテンプレートでは上記のTransform宣言がされている

template.yamlのResourcesセクション

template.yaml
Resources:
  HelloWorldFunction: #リソース名 ※CFN内でのみ使用される名前
    Type: AWS::Serverless::Function #リソースの種別はLambda関数
    Properties: #リソースの設定
      CodeUri: hello_world/ #アプリソースのディレクトリ
      Handler: app.lambda_handler #Lambdaハンドラーの指定
      Runtime: python3.9
      Architectures:
        - x86_64
      Events: #関数をトリガーするイベントのを指定
        HelloWorld: #イベント名 ※CFN内でのみ使用される名前
          Type: Api #イベントの種別
          Properties: #イベントの設定
            Path: /hello #呼び出される URI パス
            Method: get #HTTPメソッド

テンプレートを検証

SAMテンプレートが有効かどうか検証

$ sam validate
template.yaml is a valid SAM Template

検証結果問題なし

試しにサポートされていないリソースタイプで実施

template.yaml
Resources:
  HelloWorldFunction:
-    Type: AWS::Serverless::Function
+    Type: AWS::Serverless::ValidateTest
$ sam validate
E3038 Serverless Transform required for Type AWS::Serverless::ValidateTest for resource HelloWorldFunction

Error: Linting failed. At least one linting rule was matched to the provided template.

template.yamlを変更してもビルドやデプロイ前に構文エラーを発見できるので初めのうちはお世話になりそう👍

ビルド

$ sam build

成功するとビルドされたモジュールが.aws-sam/ に生成

テスト(省略可)

まずは期待される結果を確認
{"message": "hello world"}をボディとしてstatusCode: 200で返すアプリ

app.py
import json

def lambda_handler(event, context):

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        }),
    }

Lambda関数のローカル実行してテスト実施

$ sam local invoke
Invoking app.lambda_handler (python3.9)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64.

Mounting ~~~\sample-app\.aws-sam\build\HelloWorldFunction as /var/task:ro,delegated, inside runtime container
START RequestId: 011dd512-cd77-4599-8ed8-0a4d88403790 Version: $LATEST
END RequestId: 011dd512-cd77-4599-8ed8-0a4d88403790
REPORT RequestId: 011dd512-cd77-4599-8ed8-0a4d88403790  Init Duration: 0.32 ms  Duration: 185.27 ms     Billed Duration: 186 ms Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}

START RequestIdの行からREPORT RequestIdの行までがLambdaが出力したログ
最後の{"statusCode": 200, "body": "{"message": "hello world"}"}がレスポンス内容

ローカルでapigwを起動して実際にAPIを叩いてみる
$ sam local start-api --port 6000
~
~
~
 * Running on http://127.0.0.1:6000
2023-08-05 18:19:47 Press CTRL+C to quit

最後の2行がこのように表示されたらローカルでapiを叩く準備は完了

template.yamlでapiの設定値は下記だったのでcurlコマンドを用意してテスト実施
Path: /hello
Method: get

$ curl http://127.0.0.1:6000/hello
{"message": "hello world"}

期待通りの内容が出力を確認

パッケージング

$ sam package --template-file template.yaml --output-template-file packaged.yaml
~
Successfully packaged artifacts and wrote output template to file packaged.yaml.
~

sam package
--template-file テンプレートファイルを指定
--output-template-file デプロイ用に出力されるテンプレートファイル名を指定

Successfully packaged ~~~ が表示されていたら成功

デプロイ

$ sam deploy --template-file packaged.yaml --stack-name sample-app-stack --region ap-northeast-1 --guided
~
Stack Name [sample-app-stack]:#そのままEnter
AWS Region [ap-northeast-1]:#そのままEnter
#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
The resource AWS::Serverless::Function 'HelloWorldFunction' has specified S3 location for CodeUri. It will not be built and SAM CLI does not support invoking it locally.
        Save arguments to configuration file [Y/n]: y
        SAM configuration file [samconfig.toml]:#そのままEnter
        SAM configuration environment [default]:#そのままEnter
~
~
Deploy this changeset? [y/N]: y
~
~
Successfully created/updated stack - sample-app-stack in ap-northeast-1

sam deploy
--template-file パッケージングで出力されたファイルを指定
--stack-name スタック名を指定
--region リージョンを指定
--guided ガイド付きでデプロイ

Successfully ~~~ が最後に出力されていれば完了

コマンドライン上ではstackの差分やデプロイ状況など表示されている。
ローカル上での操作が完了したのでAWSコンソールでCloudFormationの画面を開きスタックのステータスを確認
image.png

また、スタックごと削除すれば紐づいているリソースなどを綺麗に削除できる
逆にスタックで消さないとめんどくさくなる?

動作確認

API Gatewayから作成されたAPIのProdステージのURLを取得
https://*****.execute-api.[リージョン].amazonaws.com/Prod[path]
[path]は/helloにしてGetメソッドでapiを叩く

curl https://*****.execute-api.[リージョン].amazonaws.com/Prod/hello

StatusCode        : 200
StatusDescription : OK
Content           : {"message": "hello world"}
~
~
~

レスポンス内容はAPI Gatewayの設定により変更されているが{"message": "hello world"}とレスポンス自体を確認できたので動作確認完了

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0