今から始めるLambda②「ローカルでの実行とCLIからのデプロイ」
はじめに
前回の記事ではAWS Lambda
の概要と、コンソールから関数を作成・変更・デプロイする方法を紹介しました。
しかしながら、実際の開発現場ではローカル環境で関数を開発・検証の上デプロイしたいと思います。
そこで今回は、ローカルでLambda
を実行する環境構築とデプロイ方法について紹介します。
AWS CLIのインストール
今回は最終的にローカルからAWS
にデプロイを行います。
そのためにAWS
のCLI
を端末にインストールしましょう。
下記はHomebrew
を使った例ですが、他のツールを使っている場合はそちらを使用しても構いません。
brew install awscli
以下コマンドでバージョンが表示されればOKです。
aws --version
IAMアクセスキーの発行
以降AWS CLI
からコマンドを実行するためにIAM
からアクセスキーを発行します。
このアクセスキーを用いて認証を行います。
AWS
のダッシュボードの【すべてのサービス】から【IAM】を選択します。
上記のような画面が出てきたら【アクセスキーの作成】を押下することで、アクセスキーとシークレットが出力されます。
この内容を控えておきましょう。
CLIに登録
以下コマンドでAWS CLI
に認証情報を登録します。
aws configure
アクセスキー、シークレット、リージョン、出力形式を対話形式で入力していきます。
プロジェクトディレクトリ作成
まずはプロジェクトのディレクトリを作成します。
mkdir lambda-deploy-sample
cd lambda-deploy-sample
ここにindex.js
とevent.json
を作成します。
それぞれの内容は以下の通りです。
exports.handler = async function (event, context) {
console.log("EVENT: \n" + JSON.stringify(event, null, 2));
return context.logStreamName;
};
{
"type": "test",
"value": 100
}
event.json
はLambda
関数の引数用のデータです。
実際にはLambda
のトリガーとなったサービスによって構造が異なりますが、ここでは簡単のため上記のようなJSON
データとしています。
ローカル実行
さっそく上記の関数をローカルで実行していきたいと思います。
ローカルでLambda
を実行するために、今回は配布されているDocker
イメージを使用します。
使用するDockerイメージ
以下が今回使用するlambci/lambda
というイメージです。
今回はNode.js
ですが、他の言語のランタイムも用意されており、DockerHub
ページのDocker tags
の項目を参照すると対応しているランタイムが分かります。
ここではnodejs12.x
というランタイムを使用したいと思います。
実行コマンドは以下のような形式です。
docker run --rm \
-v <code_dir>:/var/task:ro,delegated \
[-v <layer_dir>:/opt:ro,delegated] \
lambci/lambda:<runtime> \
[<handler>] [<event>]
<code_dir>
は実行する関数があるディレクトリです。
従って今回はカレントディレクトリを指したいので$PWD
を使用します。
<layer_dir>
の節については今回省略します。
<runtime>
は先にある通りnodejs12.x
を使用し、<handler>
はindex.js
のhandler
関数を、<event>
には先のevent.json
を文字列にパースして渡します。
ローカルで実行
それでは実行してみましょう。
下記コマンドで実行されます。
docker run --rm -v "$PWD":/var/task lambci/lambda:nodejs12.x index.handler $(printf '%s' $(cat event.json))
コンソールに以下のように表示されれば成功です。
START RequestId: 26612a00-1447-14c7-04ef-b612abf62773 Version: $LATEST
2021-10-20T04:23:16.574Z 26612a00-1447-14c7-04ef-b612abf62773 INFO EVENT:
{
"type": "test",
"value": 100
}
END RequestId: 26612a00-1447-14c7-04ef-b612abf62773
REPORT RequestId: 26612a00-1447-14c7-04ef-b612abf62773 Init Duration: 117.51 ms Duration: 6.19 ms Billed Duration: 7 ms Memory Size: 1536 MB Max Memory Used: 41 MB
console.log()
が動作してevent.json
の中身が表示されました。
応用:APIとして起動する
応用的な内容として、指定のLambda
関数をAPI
として起動することができます。
docker run --rm -e DOCKER_LAMBDA_STAY_OPEN=1 -p 9001:9001 -v "$PWD":/var/task lambci/lambda:nodejs12.x index.handler
この状態でlocalhost:9001
にcurl
等でリクエストを投げることでLambda
を動かすことができます。
curl -d '{"aaa": "bbb"}' http://127.0.0.1:9001/2015-03-31/functions/index/invocations
実査にはAPI Gateway
などを使うことになりますが、擬似的にその状況を再現することができます。
デプロイする
ここまでで、ローカル環境でLambda
用の関数を作成し動かすことができるようになりました。
最終的にはこの関数をAWS
にデプロイする必要があります。
今回はより実務的な内容に近づけるため、前述のAWS CLI
を用いて行いますが、コンソール上からソースをデプロイすることもできます。
いずれにせよ、ソース一式をZIP
で固める必要があります。
zip -r9 deploy_package.zip .
こうすることでdeploy_package.zip
が作成されます。
Roleの作成
新規のLambda
をデプロイするには、対応したロールを作成する必要があります。
ロールの作成もコマンドで行えますが、いくつかの情報をJSON
形式で渡す必要があるため、先に以下のようなrole.json
を作成しておきます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
内容の細かい解説については割愛しますが、Lambda
に限らずここに「どんなサービスを使うか」等の情報を記載していきます。
ロールの作成は下記コマンドで行えます。
ここではtestFunction2
という名称で作成を行います。
aws iam create-role --role-name testFunction2 --assume-role-policy-document file://role.json
すると、以下のようなJSON
が出力されました。
{
"Role": {
"Path": "/",
"RoleName": "testFunction2",
"RoleId": "【ロールID】",
"Arn": "【ARN】",
"CreateDate": "2021-10-20T07:21:53+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
このJSON
の中のARN
を使ってデプロイを行います。
デプロイ
AWS
側で未作成のLambda
をデプロイするにはcreate-function
コマンドを使います。
オプションとしてZIP
ファイルパス、先ほどのロールのARN
、ランタイムの情報などを付けて実行します。
aws lambda create-function --role 【ARNの値】 --function-name testFunction2 --zip-file fileb://deploy_package.zip --handler index.handler --runtime nodejs12.x
実行後JSON
が返って来れば成功です。
AWS
のLambda
のダッシュボード上にtestFunction2
が作成されているかと思います。
lambci/lambda
を使ってデプロイ用ファルを作成
別パターン:
上記記事で、Lambda
のローカル実行に用いたlambci/lambda
を使ってデプロイする方法が紹介されていました。
今回の例ではライブラリを使いませんでしたが、一般には何かしらのライブラリが使われる(=package.json
やnode_modules
がある)ケースが殆どだと思います。
そういった諸々を包括してデプロイするにはデプロイ用のDocker
イメージを作った方が良いかと思います。
以下のようなDockerfile
を作成しましょう。
# 使用するイメージ
FROM lambci/lambda:build-nodejs12.x
# エンコード設定
ENV LANG C.UTF-8
# リージョン設定
ENV AWS_DEFAULT_REGION us-east-2
COPY . .
# 依存パッケージのインストール
CMD npm install
# ZIPの作成
CMD zip -r9 deploy_package.zip .
Dockerfile
を作ったら、イメージを作成し実行します。
# Dockerfileからイメージの作成
docker build -t deploypackage .
# 実行
docker run --rm -v "$PWD":/var/task deploypackage:latest
実行後ZIP
ファイルが作成されていればOKです。
デプロイについては先ほどのパターンと同じ手順になります。
おまけ「環境変数の設定」
ローカルで実行した際に使用していた環境変数をデプロイ後は切り替えたい場合のTipsです。
以下コマンドで、対象のLambda
関数の環境変数を設定することができます。
例えば以下はHOGE
という環境変数にtesttest
という値を格納している例です。
aws lambda update-function-configuration --function-name 【FUCTION_NAME】 \
--environment "Variables={HOGE=testtest}"
まとめ
今回はLambda
用の関数をローカルで作成・検証を行い、AWS CLI
からデプロイするまでの手順をまとめました。
想定していたより必要な手順が多く、ちょっととっつきにくい印象でしたが、後半のデプロイ部分などは実運用的にはCI
でやってしまうパターンが殆どなので、そこまで大変ではないのかもしれません。
今回の内容が役立てば幸いです。
Discussion