📙

AWS CLIを使用してLambda関数 + API Gatewayを作成する

2024/07/04に公開

はじめに

今回は、AWS CLIを使用してLambda関数とAPI Gatewayを作成する方法を記述しています。

ハンドラーファイルの作成

Next.jsプロジェクトのルートディレクトリに、Lambda関数用のディレクトリを作成しその中にindex.jsというLambda関数のコードを記述するファイルを作成。

mkdir lambda && touch lambda/index.js
index.js
exports.handler = async (event) => {
    console.log("Event: ", event);
    return {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!')
    };
};

exports.handler = async (event) => { ... }:

Node.jsを使用してAWS Lambda関数を定義する時の書き方です。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-handler.html

exports

Node.jsのモジュールシステムにおいて、特定の関数やオブジェクトを他のファイルからアクセス可能にするための方法です。exportsを用いることで、そのファイルがモジュールとして機能し、定義された関数やオブジェクトが外部から利用可能になります。

handler

Lambda関数のエントリーポイントの名前です。AWS Lambdaがこの関数を呼び出すことにより、関数が起動します。この名前は任意に設定可能ですが、デプロイ時にAWSに指定するハンドラ名(index.handler)と一致させる必要があります。

IAMロールの作成

サービスまたはユースケースではLambdaを選択

AWSLambdaBasicExecutionRoleというポリシーをアタッチして、ロールを作成してください。

Lambda関数の作成

ルートディレクトリで、ZIPファイルを作成

zip -r lambda.zip lambda/

AWS CLIを使用してLambda関数を作成

aws lambda create-function --function-name <Lambda関数名> \
--zip-file fileb://lambda.zip --handler lambda/index.handler --runtime nodejs20.x \
--role arn:aws:iam::<your-account-id>:role/<your-lambda-execution-role>

.gitignorefunction.zipを追記してください。

Lambda関数の更新

ルートディレクトリで、再度ZIPファイルを作成

zip -r function.zip lambda/

更新されたZIPファイルをLambdaにアップロードします。

aws lambda update-function-code --function-name <Lambda関数名>  --zip-file fileb://function.zip

API Gatewayの作成

Lambda関数にリクエストを送るためにAPI Gatewayを作成し、Lambda関数と紐づけることでHTTPリクエストを送信できるようにします。

REST APIを作成

aws apigateway create-rest-api --name 'API Gateway名' --region <リージョン名>

APIのリソースIDを取得

ルートリソースIDはAPI Gatewayでのさまざまな設定や操作に必要です。

aws apigateway get-resources --rest-api-id <REST APIのID> --region <リージョン名>

リソースの作成

リソースの構造を確認

aws apigateway get-resources --rest-api-id <REST APIのID>

API作成直後はルート(/)リソースしか存在ないので、新しくリソースを作成します。

aws apigateway create-resource --rest-api-id <REST APIのID> --parent-id <リソースのID> --path-part <新しく作成されたリソースへのパス名> --region <リージョン名>

ちなみにコンソールでは、CORS (クロスオリジンリソース共有)を選択し、作成してください。

APIエンドポイントは、**エンドポイント + /新しく作成されたリソースへのパス名**になります。

HTTPメソッドの作成

新しく作成したリソースにHTTPメソッド(GETなど)を追加します。

aws apigateway put-method --rest-api-id <REST APIのID> --resource-id <新しく作成したリソースのID> --http-method <追加するGETなどのメソッド> --authorization-type NONE --region <リージョン名>

プロキシ統合

メソッド統合を設定してLambda関数を紐づける

aws apigateway put-integration --rest-api-id <REST APIのID> --resource-id <新しく作成したリソースのID> --http-method GET --type AWS_PROXY --integration-http-method POST --uri arn:aws:apigateway:<リージョン名>:lambda:path/2015-03-31/functions/<Lambda関数のARN>/invocations --region <リージョン名>

httpMethod: "POST"

Lambda関数への統合で使用されるHTTPメソッドはPOSTです。
これは、API GatewayがLambdaを呼び出す際のデフォルトのメソッドです。

APIをデプロイする

aws apigateway create-deployment --rest-api-id <REST APIのID> --stage-name <ステージ名> --region <リージョン名>

API GatewayがLambda関数を実行するための権限設定

aws lambda add-permission \
    --function-name <Lambda関数名またはARN> \
    --statement-id <デプロイID> \
    --action lambda:InvokeFunction \
    --principal apigateway.amazonaws.com \
    --source-arn 'API GatewayメソッドのARN'

Lambda関数を確認すると、下記のように表示されています。
これにより、API Gatewayが特定のLambda関数を呼び出すための権限を設定したことで、初めてLambda関数とAPI Gatewayが紐づき、API GatewayがLambda関数を呼び出すことが可能になったことがわかると思います。

トリガーを確認すると、API エンドポイントは、**エンドポイント + /新しく作成されたリソースへのパス名**になっていることがわかります。

CORS設定

aws apigateway put-method-response --rest-api-id <REST APIのID> --resource-id <リソースのID --http-method GET --status-code 200 --response-models "{\"application/json\": \"Empty\"}" --response-parameters "
{\"method.response.header.Access-Control-Allow-Origin\": true}"

レイヤー作成

下記を参考に.zipファイルを作成します。
https://zenn.dev/nenenemo/articles/61563be669372b#lambdaレイヤーにcryptojsライブラリを追加する

aws lambda publish-layer-version \
    --layer-name レイヤー名 \
    --compatible-runtimes nodejs20.x \
    --zip-file fileb://lambda_layer/zipファイル名

関数にレイヤー追加

Lambda関数にレイヤーを追加

aws lambda update-function-configuration \
    --function-name <Lambda関数名> \
    --layers <作成したレイヤーのARN>

作成したレイヤーのARNは、LayerArnではなくLayerVersionArnです。

終わりに

何かありましたらお気軽にコメント等いただけると助かります。
ここまでお読みいただきありがとうございます🎉

Discussion