0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS SAM入門 Lambdaでマイクロサービス型ToDoアプリハンズオン

Posted at

1.はじめに

1.1.背景

AWS SAMとLambdaを使用して、マイクロサービスパターンの考え方を取り入れたサーバーレスToDoアプリを構築し、その理解を深めることを目的とします。

今回作成したGitHubへのリンク

1.2.マイクロサービスとは?

マイクロサービスとは、一つの大きなアプリケーションを小さなサービスの集合として構成するアーキテクチャパターンです。
このハンズオンでは、ToDoアプリの各機能(一覧取得、作成、更新など)をそれぞれ独立したLambda関数として実装し、マイクロサービスの考え方を適用していきます。

1.3.AWS SAM(Serverless Application Model)とは?

AWS上でサーバーレスアプリケーションを構築・デプロイするためのオープンソースフレームワークです。
CloudFormationを拡張したもので、YAML形式のテンプレートを使って、Lambda関数、API Gateway、DynamoDBテーブルといったリソースを簡潔に定義することが可能でサーバーレス開発を容易にします。

1.4.本ハンズオンの構成

  • 以下のような、マイクロサービスにのっとったToDoアプリを構築していきます。
    image.png

2.ハンズオン

2.1.前提

2.1.1.実行環境

  • 本記事のバージョンはあくまで執筆時点のものです。
    互換性の問題が発生した場合は、適宜読み替えて実行ください。
項目 設定
環境 AWS CloudShell
リージョン バージニア北部(us-east-1)
AWS CLI 2.27.8
Python 3.9.21

2.1.2.ToDoアプリのファイル構成

/
├── template.yaml                       # SAM定義ファイル
├── dispatch/                           # ディスパッチLambda
│   └── app.py
├── get-todos/                          # 一覧取得Lambda
│   └── app.py
├── create-todo/                        # 作成Lambda
│   └── app.py
├── get-todo-by-id/                     # ID指定取得Lambda
│   └── app.py
├── update-todo/                        # 更新Lambda
│   └── app.py
├── delete-todo/                        # 削除Lambda
│   └── app.py
└── layer/                              # 共通レイヤー
    ├── requirements.txt                # Pythonパッケージ定義
    └── todo_common/
      └── __init__.py             # 共通ユーティリティ

2.2.プロジェクト構造のセットアップ

  • 最後まで実行して2.1.2.ToDoアプリのファイル構成と同様なことを確認する。
# メインフォルダ作成
mkdir todo-app && cd todo-app

# 各Lambda関数用ディレクトリ作成
mkdir -p dispatch
mkdir -p get-todos
mkdir -p create-todo
mkdir -p get-todo-by-id
mkdir -p update-todo
mkdir -p delete-todo
mkdir -p layer/todo_common

# テンプレートファイル作成
touch template.yaml
touch dispatch/app.py
touch get-todos/app.py
touch create-todo/app.py
touch get-todo-by-id/app.py
touch update-todo/app.py
touch delete-todo/app.py
touch layer/todo_common/__init__.py
touch layer/requirements.txt

# ディレクトリ構造確認
find . -type f | sort

2.3.SAMテンプレート作成

  • サーバーレスリソースを宣言的にYAMLコードで定義することが可能な、CloudFormationを拡張したサーバーレスアプリケーションの構築に特化したテンプレートです。
  • 多数の小さなLambda関数とそれを連携させるためのリソースが必要となるため、SAMを活用することで各マイクロサービス(Lambda関数)の定義を一箇所で管理する。
  • 今回構築する TodoAPIのCORSについては「AllowOrigin: "'*'"」としており、全てのオリジンからのアクセスを許可する設定としています。
    本番環境ではセキュリティリスクを考慮し、許可するオリジンを具体的に指定することを推奨。
cat > template.yaml << EOF
# CloudFormationのテンプレート形式のバージョンを指定
AWSTemplateFormatVersion: '2010-09-09'

# SAM(Serverless Application Model)変換を有効化
# これによりSAM特有の簡略化された構文が使えるようになる
Transform: AWS::Serverless-2016-10-31

# テンプレートの説明
Description: Python ToDo API

# グローバル設定 - すべてのLambda関数に適用される共通設定
Globals:
  # すべてのLambda関数に適用される設定
  Function:
    # 関数のタイムアウト時間(秒単位)- 10秒でタイムアウトする
    Timeout: 10
    # 使用するランタイム - Python 3.9を使用
    Runtime: python3.9
    # CPU/メモリアーキテクチャ - x86_64を使用
    Architectures:
      - x86_64
    # すべての関数に共通の環境変数
    Environment:
      Variables:
        # DynamoDBテーブル名を環境変数として設定
        # !Refを使用して別のリソース(TodosTable)を参照
        TABLE_NAME: !Ref TodosTable

# テンプレート内で定義されるAWSリソース
Resources:
  # 共通レイヤー - 複数のLambda関数で共有されるコード
  CommonLayer:
    # AWS::Serverless::LayerVersionはSAMの拡張リソースタイプ
    Type: AWS::Serverless::LayerVersion
    Properties:
      # レイヤーの名前
      LayerName: todo-common-layer
      # レイヤーの説明
      Description: Common dependencies for Todo functions
      # レイヤーのコードの場所(ローカルパス)
      ContentUri: layer/
      # このレイヤーと互換性のあるランタイム
      CompatibleRuntimes:
        - python3.9
    # レイヤーのビルド方法に関するメタデータ
    Metadata:
      BuildMethod: python3.9

  # API Gateway - すべてのHTTPリクエストのエントリポイント
  TodoApi:
    # AWS::Serverless::ApiはSAMの拡張リソースタイプ
    Type: AWS::Serverless::Api
    Properties:
      # APIのデプロイステージ名
      StageName: Prod
      # CORS(クロスオリジンリソース共有)の設定
      Cors:
        # 許可するオリジン - *は全てのドメインからのアクセスを許可
        AllowOrigin: "'*'"
        # 許可するHTTPヘッダー
        AllowHeaders: "'Content-Type,Authorization'"
        # 許可するHTTPメソッド
        AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"

  # ディスパッチ(管理)用Lambda関数 - APIのルートパスを処理
  DispatchFunction:
    # AWS::Serverless::FunctionはSAMの拡張リソースタイプ
    Type: AWS::Serverless::Function
    Properties:
      # 関数のコードの場所(ローカルパス)
      CodeUri: dispatch/
      # 関数のハンドラー(ファイル名.関数名)
      Handler: app.lambda_handler
      # 関数が使用するレイヤー
      Layers:
        # CommonLayerを参照
        - !Ref CommonLayer
      # 関数のトリガーとなるイベント
      Events:
        # APIルートパスのイベント
        ApiRoot:
          # APIイベントタイプ
          Type: Api
          Properties:
            # 使用するAPI Gateway
            RestApiId: !Ref TodoApi
            # APIのパス
            Path: /
            # 対象のHTTPメソッド(ANYは全メソッド対応)
            Method: ANY

  # ToDo一覧取得用Lambda関数
  GetTodosFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 関数のコードの場所
      CodeUri: get-todos/
      # 関数のハンドラー
      Handler: app.lambda_handler
      # 関数が使用するレイヤー
      Layers:
        - !Ref CommonLayer
      # 関数のトリガーとなるイベント
      Events:
        # API /todos GETイベント
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref TodoApi
            # /todosパスを処理
            Path: /todos
            # GETメソッドのみを処理
            Method: GET
      # 関数に付与するIAMポリシー
      Policies:
        # DynamoDBの読み取り専用ポリシー
        - DynamoDBReadPolicy:
            # 対象のテーブル名
            TableName: !Ref TodosTable

  # ToDo作成用Lambda関数
  CreateTodoFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 関数のコードの場所
      CodeUri: create-todo/
      # 関数のハンドラー
      Handler: app.lambda_handler
      # 関数が使用するレイヤー
      Layers:
        - !Ref CommonLayer
      # 関数のトリガーとなるイベント
      Events:
        # API /todos POSTイベント
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref TodoApi
            # /todosパスを処理
            Path: /todos
            # POSTメソッドのみを処理
            Method: POST
      # 関数に付与するIAMポリシー
      Policies:
        # DynamoDBの書き込み専用ポリシー
        - DynamoDBWritePolicy:
            # 対象のテーブル名
            TableName: !Ref TodosTable

  # 個別ToDo取得用Lambda関数
  GetTodoByIdFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 関数のコードの場所
      CodeUri: get-todo-by-id/
      # 関数のハンドラー
      Handler: app.lambda_handler
      # 関数が使用するレイヤー
      Layers:
        - !Ref CommonLayer
      # 関数のトリガーとなるイベント
      Events:
        # API /todos/{id} GETイベント
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref TodoApi
            # /todos/{id}パスを処理 - {id}は動的パラメータ
            Path: /todos/{id}
            # GETメソッドのみを処理
            Method: GET
      # 関数に付与するIAMポリシー
      Policies:
        # DynamoDBの読み取り専用ポリシー
        - DynamoDBReadPolicy:
            # 対象のテーブル名
            TableName: !Ref TodosTable

  # ToDo更新用Lambda関数
  UpdateTodoFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 関数のコードの場所
      CodeUri: update-todo/
      # 関数のハンドラー
      Handler: app.lambda_handler
      # 関数が使用するレイヤー
      Layers:
        - !Ref CommonLayer
      # 関数のトリガーとなるイベント
      Events:
        # API /todos/{id} PUTイベント
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref TodoApi
            # /todos/{id}パスを処理
            Path: /todos/{id}
            # PUTメソッドのみを処理
            Method: PUT
      # 関数に付与するIAMポリシー
      Policies:
        # DynamoDBのCRUD(作成・読取・更新・削除)ポリシー
        - DynamoDBCrudPolicy:
            # 対象のテーブル名
            TableName: !Ref TodosTable

  # ToDo削除用Lambda関数
  DeleteTodoFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 関数のコードの場所
      CodeUri: delete-todo/
      # 関数のハンドラー
      Handler: app.lambda_handler
      # 関数が使用するレイヤー
      Layers:
        - !Ref CommonLayer
      # 関数のトリガーとなるイベント
      Events:
        # API /todos/{id} DELETEイベント
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref TodoApi
            # /todos/{id}パスを処理
            Path: /todos/{id}
            # DELETEメソッドのみを処理
            Method: DELETE
      # 関数に付与するIAMポリシー
      Policies:
        # DynamoDBのCRUDポリシー
        - DynamoDBCrudPolicy:
            # 対象のテーブル名
            TableName: !Ref TodosTable

  # DynamoDBテーブル - ToDoデータの永続化に使用
  TodosTable:
    # AWS::DynamoDB::TableはCloudFormationの標準リソースタイプ
    Type: AWS::DynamoDB::Table
    Properties:
      # テーブルの名前
      TableName: PythonTodos
      # 課金モード - PAY_PER_REQUESTはオンデマンド課金
      BillingMode: PAY_PER_REQUEST
      # テーブルの属性(カラム)定義
      AttributeDefinitions:
        # id属性を定義
        - AttributeName: id
          # S = 文字列型
          AttributeType: S
      # テーブルのキースキーマ
      KeySchema:
        # idをハッシュキー(プライマリキー)として使用
        - AttributeName: id
          KeyType: HASH

# テンプレートの出力値
Outputs:
  # API URLを出力値として定義
  ApiUrl:
    # 出力値の説明
    Description: URL of the API endpoint
    # APIのURL - !Subを使用して文字列を組み立て
    # ${TodoApi}はAPI IDに、${AWS::Region}は現在のリージョンに置き換えられる
    Value: !Sub "https://${TodoApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
EOF

2.4.共通レイヤの作成

2.4.1.共通レイヤとは?

  • 複数のLambda関数間で共有される汎用的なコード
  • 共有することでコードの重複ロジックの一貫性変更の一元管理などのメリットがある。

■ 今回は以下の要素を共通レイヤとする

項番 項目名 詳細
1 共通のユーティリティ関数 複数の場所で使われる汎用的な機能
2 データベース接続のセットアップ DynamoDBなどへの接続初期化
3 レスポンス形式の標準化 API応答の一貫したフォーマット
4 ビジネスロジックの共通部分 アプリケーション固有の共有機能

2.4.2.ファイルの作成

# 共通ユーティリティの作成
cat > layer/todo_common/__init__.py << EOF
import os
import json
import boto3
import decimal
import uuid
from datetime import datetime

# デシマル型をJSONに変換するためのエンコーダ
class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            return float(obj)
        return super(DecimalEncoder, self).default(obj)

# DynamoDB接続
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ.get('TABLE_NAME', 'PythonTodos'))

# レスポンス作成ヘルパー
def create_response(status_code, body=None):
    response = {
        'statusCode': status_code,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS',
            'Access-Control-Allow-Headers': 'Content-Type,Authorization'
        }
    }
    
    if body is not None:
        response['body'] = json.dumps(body, cls=DecimalEncoder)
        
    return response

# 新しいToDo ID生成
def generate_todo_id():
    return str(uuid.uuid4())

# 現在のタイムスタンプ取得
def get_timestamp():
    return datetime.now().isoformat()
EOF

2.5.各Lambda関数の実装

2.5.1.ディスパッチ(管理用)関数

  • リクエストの受付の役割を果たす関数
cat > dispatch/app.py << EOF
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps({
            'message': 'Welcome to ToDo API',
            'endpoints': {
                'GET /todos': 'List all todos',
                'POST /todos': 'Create a new todo',
                'GET /todos/{id}': 'Get a specific todo',
                'PUT /todos/{id}': 'Update a todo',
                'DELETE /todos/{id}': 'Delete a todo'
            }
        })
    }
EOF

2.5.2.ToDo一覧取得関数

  • DynamoDBからToDoの一覧を取得する関数
  • table.scan()については、テーブル全体をスキャンするため大規模なテーブルではパフォーマンスやコストに影響を与える可能性があります。
    実運用では、クエリやインデックスの利用を検討してください。
cat > get-todos/app.py << EOF
from todo_common import table, create_response

def lambda_handler(event, context):
    try:
        # DynamoDBからすべてのToDoを取得
        response = table.scan()
        items = response.get('Items', [])
        
        return create_response(200, {'todos': items})
    except Exception as e:
        print(f"Error: {str(e)}")
        return create_response(500, {'error': 'Error fetching todos'})
EOF

2.5.3.ToDo作成関数

  • DynamoDBへToDoを保存する関数
cat > create-todo/app.py << EOF
import json
from todo_common import table, create_response, generate_todo_id, get_timestamp

def lambda_handler(event, context):
    try:
        # リクエストボディを取得
        body = json.loads(event['body']) if event.get('body') else {}
        
        # タイトルがなければエラー
        if 'title' not in body:
            return create_response(400, {'error': 'Title is required'})
        
        # 新しいToDoアイテムを作成
        todo_id = generate_todo_id()
        new_todo = {
            'id': todo_id,
            'title': body['title'],
            'completed': False,
            'createdAt': get_timestamp()
        }
        
        # DynamoDBに保存
        table.put_item(Item=new_todo)
        
        return create_response(201, new_todo)
    except Exception as e:
        print(f"Error: {str(e)}")
        return create_response(500, {'error': 'Error creating todo'})
EOF

2.5.4.ToDo個別取得関数

  • 特定のToDoのみを取得する関数
cat > get-todo-by-id/app.py << EOF
from todo_common import table, create_response

def lambda_handler(event, context):
    try:
        # パスパラメータからIDを取得
        todo_id = event['pathParameters']['id']
        
        # DynamoDBから指定されたIDのToDoを取得
        response = table.get_item(Key={'id': todo_id})
        
        # アイテムが見つからない場合は404エラー
        if 'Item' not in response:
            return create_response(404, {'error': 'Todo not found'})
        
        return create_response(200, response['Item'])
    except Exception as e:
        print(f"Error: {str(e)}")
        return create_response(500, {'error': 'Error fetching todo'})
EOF

2.5.5.ToDo更新関数

-ToDoの更新をおこなう関数

cat > update-todo/app.py << EOF
import json
from todo_common import table, create_response, get_timestamp

def lambda_handler(event, context):
    try:
        # パスパラメータからIDを取得
        todo_id = event['pathParameters']['id']
        
        # リクエストボディを取得
        body = json.loads(event['body']) if event.get('body') else {}
        
        # 既存のToDoを確認
        response = table.get_item(Key={'id': todo_id})
        if 'Item' not in response:
            return create_response(404, {'error': 'Todo not found'})
        
        # 更新式の構築
        update_expression = "SET "
        expression_values = {}
        
        if 'title' in body:
            update_expression += "title = :title, "
            expression_values[':title'] = body['title']
        
        if 'completed' in body:
            update_expression += "completed = :completed, "
            expression_values[':completed'] = body['completed']
        
        update_expression += "updatedAt = :updatedAt"
        expression_values[':updatedAt'] = get_timestamp()
        
        # DynamoDBを更新
        response = table.update_item(
            Key={'id': todo_id},
            UpdateExpression=update_expression,
            ExpressionAttributeValues=expression_values,
            ReturnValues="ALL_NEW"
        )
        
        return create_response(200, response['Attributes'])
    except Exception as e:
        print(f"Error: {str(e)}")
        return create_response(500, {'error': 'Error updating todo'})
EOF

2.5.6.ToDo削除関数

  • ToDoを削除する関数
cat > delete-todo/app.py << EOF
from todo_common import table, create_response

def lambda_handler(event, context):
    try:
        # パスパラメータからIDを取得
        todo_id = event['pathParameters']['id']
        
        # DynamoDBから削除
        table.delete_item(Key={'id': todo_id})
        
        return create_response(204)
    except Exception as e:
        print(f"Error: {str(e)}")
        return create_response(500, {'error': 'Error deleting todo'})
EOF

2.6.ビルドとデプロイ

2.6.1.SAMによるビルド

  • ビルドが成功するとBuild Succeededが表示される
# samコマンドによるビルド
sam build

2.6.2.SAMによるデプロイ

  • 以下コマンドを実施するとウィザード形式で質問される
  • デプロイコマンド後 Successfully created/updated stack - todo-app in us-east-1 が表示される。

■ 質問への回答例

項番 項目 項目(日本語) 回答内容
1 Stack Name [sam-app] スタック名 todo-app
2 AWS Region [us-east-1] リージョン us-east-1
3 Confirm changes before deploy [y/N] デプロイを実行する前に、変更内容を確認しますか? y
4 Allow SAM CLI IAM role creation [Y/n] SAMがIAMロール作成を許可するか? y
5 Disable rollback [y/N] ロールバックを無効にするか? n
6 ${関数名} Function has no authentication. Is this okay? [y/N] (※各関数で聞かれる)認証が設定されていませんが、これでよいですか? y
7 Save arguments to configuration file [Y/n] 設定ファイルに引数を保存しますか? y
8 SAM configuration file [samconfig.toml] SAM設定ファイルの名前 ENTER(デフォルトの「samconfig.toml」)
9 SAM configuration environment [default] ファイル内で異なる環境(開発環境、テスト環境、本番環境など)の設定 ENTER(デフォルトの「default」)
# samコマンドによるデプロイ
sam deploy --guided
2.6.2.1.デプロイして発生したエラー
  • 問題:今回デプロイコマンドを実施した際、以下のようなエラー(S3バケットが存在しないエラー)が表示されました。
  • 原因:SAM CLIがデプロイパッケージをアップロードするためのS3バケットを見つけられない、または自動作成できない。
  • 解決策:マネージドS3バケットを手動作成
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-XXXXXXXXXXXX
マネージドS3バケット: aws-sam-cli-managed-default-samclisourcebucket-XXXXXXXXXXXX

A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
samconfig.tomlで別のデフォルトS3バケットを設定できます。また、resolve_s3=Falseと設定することで、バケットの自動解決をオフにできます。
(中略)
S3 Bucket does not exist.
S3バケットが存在しません。

参考: Facing some issues with AWS EventBridge Application

2.6.2.2.解決に向けた実行コマンド
# マネージドS3バケット作成コマンド実施
aws s3 mb s3://aws-sam-cli-managed-default-samclisourcebucket-XXXXXXXXXXXX --region us-east-1

# 再度samコマンドによるデプロイ
sam deploy --guided

2.7.挙動の確認

  • デプロイが完了すると SAMからAPI URLが表示されるため、以下コマンドのURL部分を適宜修正してテストを実施する。
  • 本ハンズオンはAWS CloudShellでの実行を前提としているため、CloudShellには jq がプリインストールされています。
    ローカル環境で実行する場合は、別途 jq をインストールしてください。

2.7.1.URL取得

# デプロイされたURLを設定 (実際のURLに置き換えてください)
export API_URL=https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod

# または以下のコマンドでURLを取得
export API_URL="https://$(aws cloudformation list-stack-resources --stack-name todo-app --query "StackResourceSummaries[?ResourceType=='AWS::ApiGateway::RestApi'].PhysicalResourceId" --output text).execute-api.us-east-1.amazonaws.com/Prod/"

echo $API_URL

2.7.2.一連の挙動確認

2.7.2.1.ToDoの作成
# ディスパッチ関数(ルート)をテスト
curl $API_URL

# 新しいToDoを作成し、そのIDを変数に保存
TODO_ID=$(curl -X POST $API_URL/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "AWS SAMを使いこなす"}' | jq -r '.id')

# 参考レスポンス
{
  "completed": false,
  "createdAt": "2025-05-13T13:34:35.480359",
  "id": "00653957-229a-49e8-99e0-6dc8baf11cac",
  "title": "AWS SAMを使いこなす"
}
2.7.2.2.ToDoの更新
# ToDoを完了済みに更新
curl -X PUT $API_URL/todos/$TODO_ID \
  -H "Content-Type: application/json" \
  -d '{"completed": true}' | jq

# 参考レスポンス
{
  "completed": true,
  "createdAt": "2025-05-13T13:34:35.480359",
  "id": "00653957-229a-49e8-99e0-6dc8baf11cac",
  "updatedAt": "2025-05-13T13:36:55.682951",
  "title": "AWS SAMを使いこなす"
}
2.7.2.3.ToDo一覧取得
# ToDo一覧取得
curl $API_URL/todos | jq

# 参考レスポンス
{
  "todos": [
    {
      "completed": true,
      "createdAt": "2025-05-13T13:34:35.480359",
      "id": "00653957-229a-49e8-99e0-6dc8baf11cac",
      "updatedAt": "2025-05-13T13:36:55.682951",
      "title": "AWS SAMを使いこなす"
    }
  ]
}
2.7.2.4.ToDo削除
# ToDo削除
curl -X DELETE $API_URL/todos/$TODO_ID

# 参考レスポンス
なし

# ToDo一覧取得
curl $API_URL/todos | jq

# 参考レスポンス
{
  "todos": []
}

2.8.クリーンアップ

  • 以下コマンドで、本ハンズオンで作成したリソースを削除します。
    不要な課金を避けるために、ハンズオン終了後は実行することを推奨します。
  • 削除の際に以下2点が聞かれるが、どちらもyと答えることを推奨する。
項番 項目 項目(日本語) 回答内容
1 Are you sure you want to delete the stack todo-app in the region us-east-1 ? [y/N] us-east-1リージョンのtodo-appスタックを削除してもよいか? y
2 Are you sure you want to delete the folder todo-app in S3 which contains the artifacts? [y/N] S3のtodo-appフォルダを削除してもよいか? y
# 削除コマンド
sam delete

3.おわりに

3.1.得られた知見

  • マイクロサービスの基本的な考え方の理解。
  • SAM (Serverless Application Model) を使用することで、多数のLambda関数や関連リソースを効率的に定義・管理・デプロイすることを体験。

3.2.今後の課題

  • X-Rayなどを用いた分散トレーシングによるパフォーマンス監視とデバッグ。
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?