【AWS】Serverless Frameworkメモ
はじめに
ローカル端末上でLambdaの開発を進めたく、Serverless Framework を実際に使ってみながらメモを残す。
補足
似たツールで「AWS SAM」もあるが、今回は利用を見送った。
(ローカル実行する際にDockerが必要で、仕事で使うにはDockerの有料サブスクリプションの契約が必要になるため)
Serverless Framework参考
開発環境
最低限のツール類のインストールと、IAMユーザーの作成&認証情報の設定(Profileの設定)は完了済みとする。
環境 | バージョンなど | 備考 |
---|---|---|
MacOS | Sonoma v14.5 | - |
AWS CLI | aws-cli/2.17.22 Python/3.11.9 Darwin/23.5.0 exe/x86_64 | - |
Node.js | v20.11.1 | - |
npm | v10.2.4 | Node.jsと一緒にインストールされたバージョンを利用 |
Serverless Frameworkのインストール
- インストール(v3系をインストールしたいので、以下とした)
npm install -g serverless@3.39.0
- バージョン確認
sls -v
# 出力例:
Framework Core: 3.39.0
Plugin: 7.2.3
SDK: 4.5.1
バージョン情報の参考元
今回インストール時に指定したバージョンは、以下から参照して選択した
Serverlessプロジェクトを作成する
- プロジェクト用のディレクトリ作成
mkdir serverless-func
cd serverless-func
- Serverlessプロジェクト作成(今回は Node.jsのHTTP API として作成する)
「serverless or sls」コマンドを入力すると、対話形式でプロジェクトを作成できた
% sls
Creating a new serverless project
? What do you want to make? (Use arrow keys)
AWS - Node.js - Starter
❯ AWS - Node.js - HTTP API
AWS - Node.js - Scheduled Task
AWS - Node.js - SQS Worker
AWS - Node.js - Express API
AWS - Node.js - Express API with DynamoDB
AWS - Python - Starter
AWS - Python - HTTP API
AWS - Python - Scheduled Task
AWS - Python - SQS Worker
AWS - Python - Flask API
AWS - Python - Flask API with DynamoDB
Other
? What do you want to call this project? serverless-lambda
✔ Project successfully created in serverless-lambda folder
? Register or Login to Serverless Framework No
? Do you want to deploy now? No
What next?
Run these commands in the project directory:
serverless deploy Deploy changes
serverless info View deployed endpoints and resources
serverless invoke Invoke deployed functions
serverless --help Discover more commands
作成されたプロジェクト構成と設定ファイル内容
デフォルトは以下のフォルダ構成と、設定ファイル内容(serverless.yml)で作成された
プロジェクト内の関数を、ローカル実行する
- ローカル実行
# 作成したプロジェクト配下へ移動
cd serverless-lambda
# 実行
## 書式: serverless invoke local --function <ファンクション名>
## 書式(エイリアス版): sls invoke local -f <ファンクション名>
sls invoke local -f api
- 実行結果
ローカル実行後、「index.js」に記載された内容が出力されたら完了
{
"statusCode": 200,
"body": "{\n \"message\": \"Go Serverless v3.0! Your function executed successfully!\",\n \"input\": \"\"\n}"
}
serverless.ymlの参考情報
プロジェクト内の関数を、AWS上にデプロイする
- 「serverless.yml」の変更
プロファイルやリージョンの指定など、以下最低限の変更を加えた
service: serverless-lambda
frameworkVersion: '3'
provider:
name: aws
-- runtime: nodejs18.x
++ runtime: nodejs20.x
++ stage: dev
++ region: ap-northeast-1
++ profile: <認証用プロファイル名>
functions:
api:
handler: index.handler
events:
- httpApi:
path: /
method: get
- デプロイの実行
sls deploy
デプロイされた環境の確認
AWS上に、LambdaとAPI Gatewayが一つずつ作成された
デプロイ後の名称に「dev」などのステージ名がついているが、デフォルトだとそれぞれ以下になる?
- Lambda名: <作成時に指定したPJ名>-${sls:stage}-<ファンクション名>
- API Gateway名: ${sls:stage}-<作成時に指定したPJ名>
デプロイした関数を実行する
デプロイ時にAPIのエンドポイントが出力されるので、エンドポイントをcurlコマンドで叩いてみる
- API呼び出し
curl https://<id>.execute-api.ap-northeast-1.amazonaws.com/
- 実行結果
{
"message": "Go Serverless v3.0! Your function executed successfully!",
"input": {
"version": "2.0",
"routeKey": "GET /",
"rawPath": "/",
"rawQueryString": "",
"headers": {
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"cache-control": "no-cache",
〜省略〜
}
デプロイ後のレスポンス結果が、想定していた内容と異なる点の確認
元々は、以下のレスポンス内容を想定していた。
異なるレスポンス結果だったため、何か設定やパスに誤りがあったのか確認進める。
※:想定していたレスポンス内容
{
"statusCode": 200,
"body": "{\n \"message\": \"Go Serverless v3.0! Your function executed successfully!\",\n \"input\": {}\n}"
}
確認結果
Serverless Frameworkの、公式のGitHubのREADMEを参照すると、以下の記載があった。そのため上記のレスポンス結果で問題ない模様。
呼び出し
デプロイが成功すると、作成されたアプリケーションを HTTP 経由で呼び出すことができます。
curl https://xxxxxxx.execute-api.us-east-1.amazonaws.com/
次のような応答が返されるはずです (input簡潔にするためにコンテンツは削除されています)。
{
"message": "Go Serverless v2.0! Your function executed successfully!",
"input": {
...
}
}
デプロイしたリソースの削除
以下コマンドで削除可能
今回だと、デプロイされたLambdaとAPI Gatewayの両方がAWS上から削除される
sls remove
Lambdaのみをデプロイしたい(API Gatewayを含まない形でデプロイしたい)
上記で試した「AWS - Node.js - HTTP API 」のプロジェクトだと、デプロイ後にAPI Gatewayも同時に作成される形であった。
Lambdaのみをデプロイしたいので、別のテンプレートプロジェクトについて確認する
結論
プロジェクト作成時に、「AWS - Node.js - Starter(aws-nodeテンプレート)」を選択するとLambdaのみのデプロイが可能そう。
※上記を選択してプロジェクト作成したところ、READMEに以下記載があっため
This template demonstrates how to deploy a NodeJS function running on AWS Lambda using the traditional Serverless Framework. The deployed function does not include any event definitions as well as any kind of persistence (database).
日本語訳
このテンプレートは、従来の Serverless Framework を使用して AWS Lambda で実行される NodeJS 関数をデプロイする方法を示します。デプロイされた関数には、イベント定義や永続性 (データベース) は含まれません。
引用元: Serverless Framework AWS NodeJS Example
aws-nodeテンプレートの参考情報(v3)
「serverless.yml」による、Lambdaのロール指定
デフォルトの「serverless.yml」のままデプロイすると、IAMロールが新規作成されたものが付与される。
既存のIAMロールを指定する方法について確認する。
結論
「serverless.yml」に、以下の「iam.role」部分を追加すると既存のIAMロールを指定できた。
service: serverless-starter-api
frameworkVersion: '3'
provider:
name: aws
runtime: nodejs20.x
++ iam:
++ role: arn:aws:iam::xxxxxxxxxxxx:role/xxxxx-role/xxxxxxxxxx <=IAMロールのARNを設定
functions:
hello:
handler: index.handler
ロール設定に関する参考情報
AWS SDK(v3)の動作確認
ローカル実行した際に、AWS上のリソースアクセスも問題ないのか確認したい。
今回はS3へのアクセスについて、簡単な動作確認を行ってみる。
AWS SDK(v3)のインストール
# 書式: npm install @aws-sdk/client-SERVICE
npm install @aws-sdk/client-s3
index.jsの編集
以下の公式ドキュメントより、S3のバケットリストを取得するコードを試す
Amazon S3 examples using SDK for JavaScript (v3)
// The following code example shows how to use ListBuckets.
const { ListBucketsCommand, S3Client } = require('@aws-sdk/client-s3');
const client = new S3Client({});
module.exports.handler = async (event) => {
const command = new ListBucketsCommand({});
try {
const { Owner, Buckets } = await client.send(command);
console.log(
`${Owner.DisplayName} owns ${Buckets.length} bucket${
Buckets.length === 1 ? "" : "s"
}:`,
);
console.log(`${Buckets.map((b) => ` • ${b.Name}`).join("\n")}`);
} catch (err) {
console.error(err);
}
};
ローカル実行
認証情報に問題あるせいかWARNINGが出たものの、正常にバケット一覧が出力されることを確認できた。
# 書式: sls invoke local -f <ファンクション名>
sls invoke local -f api
@aws-sdk/credential-provider-node - defaultProvider::fromEnv WARNING:
Multiple credential sources detected:
Both AWS_PROFILE and the pair AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY static credentials are set.
This SDK will proceed with the AWS_PROFILE value.
However, a future version may change this behavior to prefer the ENV static credentials.
Please ensure that your environment only sets either the AWS_PROFILE or the
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY pair.
<AWSアカウント名> owns 7 buckets:
• <バケット名1>
• <バケット名2>
• <バケット名3>
• <バケット名4>
• <バケット名5>
• <バケット名6>
• <バケット名7>
参考情報