【CFn/API Gateway/DynamoDB/Lambda】API呼び出しでDynamoDBを操作する<デプロイ編>
1.はじめに
今回は実装編で作成したLambda関数をAWS環境にデプロイします。
加えて、各リソースをテンプレート化して、CloudFormationでまとめてデプロ
イします。
紹介する内容としては以下の通りとなります。
- template.yamlでLambda関数・DynamoDB・API Gateway・APIキーを定義する
- CloudFormationからリソースを一括デプロイする
- PowerShellからAPIを呼び出しDynamoDBに項目を登録する
この記事は実装編・デプロイ編・フロント編の3部構成となっています。
- 実装編:PythonでのLambda関数実装が中心
- デプロイ編:「template.yaml」の記述方法・デプロイ後の動作確認方法が中心
- フロント編(未執筆):HTMLで画面を作成してAPIを呼び出す方法について
今回はデプロイ編ということでtemplate.yamlの記述方法やデプロイ時の動作確認方法の説明をします。
本記事で実装するものは以下リポジトリに上げています。
2.準備
本記事では以下を前提とします。
- AWS環境があることを前提とします
- 実装編で作成したLambda関数が実装済みであること
- AWS SAMの環境構築を終えていること
- AWS SAM CLI利用の準備
■ ディレクトリ構成
本記事では以下のディレクトリ構成で進めます。
親ディレクトリ
┣ samconfig.toml ← デプロイ編で作成
┣ template.yaml ← デプロイ編で作成
┣ common_layer
┃ ┗ requirements.txt ← 実装編で作成
┗ dynamo_lambda_function
┗ app.py ← 実装編で作成
┗ lambda_function.py ← 実装編で作成
3.template.yamlの作成
今回は「template.yaml」を元にCloudFormationから各リソースを作成します。
作成するリソースとしては以下の通りです。
作成するリソース | 説明 |
---|---|
S3バケット | ファイル格納先となるS3バケットです |
Lambda関数 | S3へのファイル格納をトリガーとして実行する関数 S3に格納されたファイル内容を取得します |
作成する「template.yaml」全体としては以下の通りです。
template.yamlの全体
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: DynamoDB Lambda Application
# AWS SAM テンプレートを使ってサーバーレスアプリケーションをデプロイするための基本設定
Globals:
Function:
Timeout: 5 # デフォルトのタイムアウト(5秒)
MemorySize: 128 # Lambda 関数のメモリサイズ(128MB)
Runtime: python3.11 # 使用する Python ランタイムバージョン (Python 3.11)
Architectures:
- arm64 # Lambda 関数を ARM64 アーキテクチャで実行
LoggingConfig:
LogFormat: JSON # ログフォーマットを JSON に設定
ApplicationLogLevel: INFO # ログレベルを INFO に設定
Environment:
Variables:
POWERTOOLS_SERVICE_NAME: DynamoApplication # AWS Lambda Powertools で使うサービス名
AWS_REGION_NAME: ap-northeast-1 # デフォルトの AWS リージョン名
# パラメータセクション:テンプレートに対して外部から渡される引数
Parameters:
OverridesParam:
Type: String # パラメータの型 (String)
Description: OverridesParam # パラメータの説明
Stage:
Type: String # ステージ名のパラメータ(例:dev, prod)
Default: dev # デフォルト値として dev を設定
Description: Stage Name # ステージ名の説明
# リソースセクション:サーバーレスアプリケーションに必要な AWS リソースを定義
Resources:
# API Gateway を定義
Api:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ApiGateway-${OverridesParam} # API Gateway 名を OverridesParam でカスタマイズ
StageName: !Ref Stage # ステージ名を指定
EndpointConfiguration:
Type: REGIONAL # エンドポイントをリージョン限定に設定
# 共通の Lambda Layer を定義
CommonLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: CommonLayer # レイヤーの名前を定義
Description: Common Layer # レイヤーの説明
ContentUri: common_layer/ # レイヤーのソースコードパス
CompatibleRuntimes:
- python3.11 # レイヤーが対応するランタイム
RetentionPolicy: Delete # 不要になったレイヤーは削除するポリシー
Metadata:
BuildMethod: python3.11 # SAM がレイヤーをビルドするためのランタイム
BuildArchitecture: arm64 # ARM64 アーキテクチャ用にビルド
# DynamoDB と連携する Lambda 関数
DynamoLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler # Lambda 関数のハンドラ
CodeUri: src/dynamo_lambda_function # 関数コードの場所
Description: DynamoDB lambda handler # 関数の説明
Layers:
- !Ref CommonLayer # CommonLayer を Lambda 関数に追加
Events:
ApiEvent:
Type: Api
Properties:
RestApiId: !Ref Api # API Gateway を参照
Path: /{proxy+} # プロキシ統合(すべてのパスを処理)
Method: Any # HTTP メソッド(GET, POST など全て)
Auth:
ApiKeyRequired: true # API キーが必要
Environment:
Variables:
DYNAMO_TABLE_NAME: !Ref DynamoDBLambdaTable # DynamoDB テーブル名を環境変数で設定
Policies:
- DynamoDBCrudPolicy: # DynamoDB に対する CRUD 権限
TableName: !Ref DynamoDBLambdaTable
Tags:
Name: "dynamo-lambda-function" # タグとして関数の名前を設定
Timeout: 300 # タイムアウト(300秒)
# DynamoDB テーブルを定義
DynamoDBLambdaTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Sub "dynamo-${OverridesParam}" # DynamoDB テーブル名をパラメータに基づき設定
AttributeDefinitions:
- AttributeName: dynamo_id # パーティションキーとして使用する属性名
AttributeType: S # 属性タイプ(S:文字列)
KeySchema:
- AttributeName: dynamo_id # パーティションキー(HASHキー)
KeyType: HASH
BillingMode: PAY_PER_REQUEST # リクエストごとの課金モデル(オンデマンド)
# API キーを定義
ApiKey:
Type: AWS::ApiGateway::ApiKey
Properties:
Name: !Sub ApiKey-${OverridesParam} # API キー名
Description: APIKey # API キーの説明
Enabled: true # API キーを有効化
StageKeys:
- RestApiId: !Ref Api # API Gateway ID
StageName: !Ref Stage # ステージ名
DependsOn:
- Api
- ApiStage
# API の利用制限設定
ApiUsagePlan:
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref Api # API ID
Stage: !Ref Stage # ステージ名
Throttle:
BurstLimit: 100 # バースト制限(リクエストの瞬間最大数)
RateLimit: 100 # レート制限(リクエストの毎秒最大数)
UsagePlanName: !Sub UsagePlan-${OverridesParam} # 使用プランの名前
DependsOn:
- Api
- ApiStage
# ApiKey と ApiUsagePlan の紐づけ設定
ApiUsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey # API キーの ID
KeyType: API_KEY # キータイプ(API キー)
UsagePlanId: !Ref ApiUsagePlan # 使用プランの ID
4.samconfig.tomlの作成
続いて「samconfig.toml」を作成します。
「samconfig.toml」はAWS SAM (Serverless Application Model) を使用する際に、SAM CLI コマンドの設定を管理するためのファイルです。
このファイルにより、デプロイ・ビルド時のオプションや設定を明示的に指定することができます。
主な用途としては以下が挙げられます。
- デプロイ設定の自動化:「samconfig.toml」にデプロイ設定を保存しておくことで、簡単に同じ設定を使ってデプロイを行えます。
- 環境ごとの設定:開発環境・本番環境など、異なる環境に応じた設定を分けて管理できます。
作成する「samconfig.toml」全体としては以下の通りです。
samconfig.tomlの全体
# More information about the configuration file can be found here:
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
version = 0.1
[default]
[default.global.parameters]
stack_name = "dynamo-application"
[default.build.parameters]
cached = true
parallel = true
[default.validate.parameters]
lint = true
[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
parameter_overrides = ["OverridesParam='20241030'"]
[default.package.parameters]
resolve_s3 = true
[default.sync.parameters]
watch = true
[default.local_start_api.parameters]
warm_containers = "EAGER"
[default.local_start_lambda.parameters]
warm_containers = "EAGER"
5.ビルド&デプロイ
それでは、実装物のビルドとデプロイを行います。
※AWS SAM CLIが使用できることを前提としています
以下のコマンドを実行することでビルドとAWS環境へのデプロイができます。
$ sam build
$ sam deploy --config-file samconfig.toml
Successfully created/updated stack - dynamo-application in ap-northeast-1
上記が表示されデプロイが正常終了したことを確認します。
続いてAWSのマネジメントコンソールから以下画面に移動します。
- CloudFormation → スタック → dynamo-application
ステータスが「CREATE_COMPLETE」となっていることを確認します。
また、デプロイした各リソースが作成されていることを確認します。
Lambda関数
Lambda → 関数 → dynamo-application-DynamoLambdaFunction-XXX
DynamoDB
DynamoDB → テーブル → dynamo-20241029
API Gateway
API Gateway → API → ApiGateway-20241029
6.動作確認
それではLambda関数の動作確認を行います。
今回は以下手順で動作確認を行います。
- API Gatewayの画面からAPIを呼び出す際のURLを確認する
- API Gatewayの画面からAPIキーを確認する
- PowerShellからAPIを呼び出す
- DynamoDBに項目が登録されていることを確認する
手順1:API Gatewayの画面からAPIを呼び出す際のURLを確認する
APIを呼び出す際のURLを確認します。
マネジメントコンソールの以下画面から、APIを呼び出す際のURLをメモしておきます。
- API Gateway → API → ApiGateway-20241029 → ステージ
手順2:API Gatewayの画面からAPIキーを確認する
API呼び出しに必要なAPIキーを確認します。
マネジメントコンソールの以下画面から、APIキーを確認しメモしておきます。
- API Gateway → API → API キー
手順3:PowerShellからAPIを呼び出す
PowerShellからAPIを呼び出します。
実装編で作成したlambda_functionが以下の形で実装されているため、
以下コマンドで呼び出すことができます。
Invoke-WebRequest -Uri "https://手順1でメモしたURL/data/00001" -Method Post -Headers @{"Content-Type"="application/json";"x-api-key"="手順2でメモしたAPIキー"} -Body '{"name": "登録したい名称"}'
実行時のログは以下の通りです。
$ Invoke-WebRequest -Uri "https://手順1でメモしたURL/data/00001" -Method Post -Headers @{"Content-Type"="application/json";"x-api-key"="手順2でメモしたAPIキー"} -Body '{"name": "登録したい名称"}'
StatusCode : 200
StatusDescription : OK
Content : {"ResponseMetadata": {"RequestId": "ダミー", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Tue, 29 Oct 2024 15:3
1:01 GMT", "content-...
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
x-amzn-RequestId: ダミー
x-amz-apigw-id: ダミー
X-Amzn-Trace-Id: ダミー
Forms : {}
Headers : {[Connection, keep-alive], [x-amzn-RequestId, ダミー], [x-amz-apigw-id, ダミー], [X-Amzn-Trace-Id, Root=ダミー;
Parent=ダミー;Lineage=ダミー]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : System.__ComObject
RawContentLength : 414
手順4:DynamoDBに項目が登録されていることを確認する
最後にDynamoDBに項目が登録されているか確認します。
マネジメントコンソールの以下画面から項目が登録されているか確認します。
- DynamoDB → 項目を探索 → dynamo-20241029
7.おわりに
今回のデプロイ編では、実装編の成果物をAWS環境にデプロイし以下を確認しました。
- API GatewayにAPIキーを設定
- PowerShellからAPIを呼び出す
- API呼び出しによるDynamoDBへの項目登録
実装編とデプロイ編を合わせた内容になりますので実装編も目を通していただけると嬉しいです。
Discussion