ChatGPT先生に教えてもらう第二弾はLambdaとAPIGatewayです。
Lambda関数はPythonを使いたいと思います。
やりたいこと
APIのパスパラメーターで指定したIDをファイル名に持つテキストファイルを、S3の特定のディレクトリから読み込んで、そのまま返却するだけのAPIを作りたいんじゃっ
早速先生に手順を聞いてみる
挨拶は人間として基本です。先生はいつもニコニコ機嫌がよくて優しい。

長いので省略しますが以下のような手順だそうです。
- Lambda関数の作成
- API Gatewayの作成
- リソースとメソッドの設定
- リソースのデプロイ
- APIのテスト
- APIのカスタムドメインの設定(オプション)
- セキュリティの設定(オプション)
- APIのデプロイ
④のリソースのデプロイってのがちょっと意味不明でしたが流れとかキーワードなどがざっくり把握できます。
とりあえずサンプルプログラムをください!
まだAWSコンソールにログインすらしていませんが、とりあえず貰えるものを先にもらいたい性分なのでプログラムを書いてもらいました。
import json
import boto3
s3 = boto3.client('s3')
def lambda_handler(event, context):
# URLのパラメータから{id}を取得
id = event['pathParameters']['id']
# S3バケットとオブジェクトキーを指定
bucket_name = 'your-s3-bucket'
object_key = f'{id}.json'
try:
# S3からJSONファイルを読み込む
response = s3.get_object(Bucket=bucket_name, Key=object_key)
json_content = response['Body'].read().decode('utf-8')
json_data = json.loads(json_content)
# レスポンスを構築
response_data = {
'statusCode': 200,
'body': json.dumps(json_data),
'headers': {
'Content-Type': 'application/json'
}
}
return response_data
except Exception as e:
# エラーハンドリング
response_data = {
'statusCode': 500,
'body': json.dumps({'error': str(e)}),
'headers': {
'Content-Type': 'application/json'
}
}
return response_data
S3バケットの作成
ここからはAWSコンソールでの作業のためGoogleで検索してAWSのドキュメントなどを参考に準備していきました。
Amazon S3のコンソールから「バケットを作成」で作成します。以下のようなセッティングにしました。
・ACL無効
・パブリックアクセスをすべてブロック
・バケットのバージョニング無効
・暗号化タイプ:AmazonS3マネージドキー
・バケットキー有効
・オブジェクトロック無効
そしてサンプルファイルを一つアップロードしておきました。
Lambda関数の作成
AWS Lambdaのコンソールから「関数の作成」を実行します。以下のようなセッティングにしました。
・一から作成
・ランタイム:Python 3.11
・アーキテクチャ:x86x64
・実行ロール:基本的なLambdaアクセス権限で新しいロールを作成
作成したLambda関数のコード欄にChatGPT先生にいただいたサンプルをペタリしてS3のバケット名やオブジェクトキー(ファイルのパス)を変更して、テストを行いました。
しかしAccessDeniedエラーが出ます。S3ファイルにアクセスできないようです。
S3バケットに対するアクセス権を設定する必要があります。
Lambda関数のロールにS3へのアクセス権を設定する
IAMのコンソールで、Lambda関数作成した時に作られたロールを確認します。Lambda実行に関する基本的なポリシーがすでに設定されています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:xxxxxxxxxxxx:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:xxxxxxxxxxxx:log-group:/aws/lambda/my-lambda-function-name:*"
]
}
]
}
ポリシーの編集ページで新しくポリシーを作成します。先ほど作成したS3バケットへのアクセス(get, post, put)を許可するポリシーを設定します。コンソールからポリシーエディタのチェックボックスで権限をチェックしてもいいし、ポリシー編集画面にjsonを貼り付けでもよいです。権限設定はS3側のポリシーにすることもできます(書き方は違います)。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-s3-bucket/*"
}
]
}
上記のポリシーを、先ほどのロールの編集画面で「許可を追加」→「ポリシーをアタッチ」で適用します。
この状態で再度Lambda関数のテストを行うと無事ファイルを取得して表示することが出来ました。
API Gatewayの作成
API GatewayコンソールからAPIを作成します。下記のようなセッティングにしました。
・APIタイプ:REST API
・APIの詳細:新しいAPI
・APIエンドポイントタイプ:リージョン
作成したAPIの管理画面で、リソースを作成します。
リソースはディレクトリ構造のようになっていて、これがURLというかエンドポイントとなっていきます。

「test/{id}」というリソースを作成します。この{}はパスパラメーターとなります。
この{id}リソースに対してGETメソッドを作成します。以下のようなセッティングにしました。
・統合タイプ:Lambda関数
・Lambdaプロキシ統合を有効にします!(大事)
・Lambda関数:作成したLambda関数のARNを指定します。
「Lambdaプロキシ統合」を有効にすると、Lambda関数の中で上記の{id}をパスパラメーターとして簡単に利用することができます。Lambda関数内ではevent[‘pathParameters’][‘id’]の中に格納されることになります。
API Gatewayのメソッドの「テスト」タブでidを指定してテストすることが出来ます。
テストしてみると無事に指定したidのファイル名のjsonがS3から取得できました。
この状態で「APIをデプロイ」ボタンを押して、ステージを作成(prodとかstgとか)してデプロイすると、APIのURLが発行されてAPIが利用できるようになります。
まとめ
ChatGPT先生はキャプチャを例示してくれないので、管理画面操作などが絡む事のレクチャーには不向きかなと思いました。
しかし大まかな流れを知りたい、調べるためのキーワードすらわからないようなときには色々聞いてみるのが良いと思います。
また、設定で詰まった時などは解決につながるヒントが得られるかもしれません。