フォーム読み込み中
2022年9月28日掲載
AWS Lambdaはサーバレスコンピューティングプラットフォームであり、開発ユーザーは小さな関数のコードを作成するだけで、開発ユーザーはサーバをプロビジョニングすることなく、その関数のコードを実行することができます。
・参考記事
サーバレスってなに?Alibaba Cloud, AWS, Azure, Google Cloud のサーバレスサービスを比べてみました
AWS LambdaにZIPファイル化したNode.jsおよびPythonのコードをデプロイしてみた(GUI編)
本記事では、AWS Lambdaのデプロイ方法の1つである、AWS Command Line Interface(AWS CLI) でNode.jsおよびPythonそれぞれをデプロイする方法を説明します。
AWS Command Line Interface(AWS CLI)は、コマンドラインシェルのコマンドを使用してAWSサービスと対話することを可能にするオープンソースツールです。最小限の設定で、AWS CLIを使用すると、ターミナルプログラムのコマンドプロンプトから、ブラウザベースのAWS Management Consoleが提供する機能と同等の機能を実装するコマンドの実行を開始することができます。
・参考リンク
AWS Command Line Interface(AWS CLI)
CLIを使ってデプロイするモチベーションとして、例えばスクリプトの中身が定期的に更新されていくようなDevOps環境のもとで開発運用する場合、サーバレスの設定を外在化、つまり設定データをGitHubやZookeeper、Consul等CI/CDツールなど外部サードパーティやファイルに配置して、無人でもInfrastructure as Code(以降IaC)ベースで素早く自動デプロイするために、IaCを意識したCLIデプロイアプローチが重要になってきます。
※本記事は 2022年9月時点の情報をもとにしております。実際のご利用にあたっては、必ず各社の最新情報をご確認ください。
AWS Lambda上でのNode.jsおよびPythonコードをAWS CLIでデプロイする際の流れ、構成図としては次の通りになります。
最初にAWS CLIコマンドツールを導入します。
AWS CLIコマンドツールを使用するには、Install Guidelineのガイドラインに従ってCLIコマンドツールをインストールし、設定します。著者はWindowsPCを使用しているので、Windowsを例に説明します。Windowsの場合、AWS CLI V2からインストールパッケージをダウンロードした後、ウィザードを使用してインストールプロセスをステップごとに完了できます。
インストールが完了したら、`aws --version`コマンドを実行してステータスを確認できます。ツールが正常にインストールされていれば、関連するバージョン情報が表示されます。
`aws configure` コマンドを実行して、AWS CLIインストールをセットアップするための設定を行います。以下の情報が既にあることを確認します。
既存のアクセスキーがない場合は、IAM > User > Access Keys に移動し、`Create access key` ボタンをクリックして新しいアクセスキーを作成し、キー情報をコピーし、先ほどのセットアップ情報に入力します。
`aws lambda help`コマンドを使用すると、lambdaサービスで利用可能なすべてのコマンドが表示されます。
コマンド`aws lambda <command> help`は、特定のコマンドに関する詳細なヘルプ情報を表示します。ここで`aws lambda create-function help`を例にとると、サポートされているすべてのパラメータと値を見つけることができます。
AWS LambdaでデプロイしたいNode.jsソースコードを準備します。本記事では、node_test_zipというソースコードフォルダを作成し、Lambdaのハンドラーが含まれるindex.jsを作成します。
ハンドラー(handler)はサーバレスとして利用する言語の関数の開始位置となるもので、HTTPトリガー、イベントトリガーなど様々なトリガーによって実行される際に呼び出すエントリポイントです。このハンドラーは必須項目であり、ハンドラーを呼び出すことで、サーバレスとしての関数コード(以降スクリプト)が実行開始されます。ここでは、event handlerを例とします。
上記のソースコードは次の通りです。
'use strict';
const moment = require('moment');
exports.handler = (event, context, callback) => {
console.log('hello world');
callback(null, moment().utcOffset(9).format('YYYY-MM-DD HH:mm:ss'));
}
LambdaのNode.jsランタイム環境は、一般的なNode.jsモジュールと、使用可能な共通モジュールを提供します。カスタマイズされたScriptには、サードパーティの依存関係を必要とする場合があります。
上記のソースコードでは、日付を操作するためのmomentと呼ばれるパッケージが必要であり、デプロイ前に準備する必要があります。これらのパッケージはnpmでローカルに管理します。
`npm i<package name>--save` コマンドを実行して必要なパッケージをローカルにインストールした後、node_modulesフォルダ(関連するパッケージコードを含む)とpackage.json(必要なパッケージ情報を含む)が index.jsと同じフォルダの下にあります。
最後に、これらが含まれているソースコードフォルダ内のすべてのファイルをZIPファイルへ圧縮します。ZIPファイル生成後はLambda上でデプロイする際に使用します。
ソースコードの準備ができたら、そのソースコードをベースとしながらLambda関数を作成します。次のように入力パラメータを指定してコマンドを入力します。
aws lambda create-function --function-name ohara-bob-node-cli --zip-file fileb://node_test_zip.zip --handler index.handler --timeout 900 --runtime nodejs16.x --role
コマンド入力が正しければ、コンソール画面にて関数名等が表示されます。
コードを呼び出し実行するためにinvokeコマンドを使用します。
以下のコマンド例にある、`eyJ0ZXN0IjoiQm9iIn0=` は `{ "test": "Bob" }` をbase64でエンコードしたものです。JSON文字列を直接コマンドで使用するとエラーが発生します。
このコマンド実行後、その結果はresponse.jsonに保存されます。
aws lambda invoke --function-name ohara-bob-node-cli --payload eyJ0ZXN0IjoiQm9iIn0= response.json
結果、現在の日付情報が特定の形式で返されます。
以上が、CLIベースでAWS Lambda上のNode.jsソースコードをデプロイする方法になります。
参考として、コマンド行から呼び出しのログを取得するには、--log-typeオプションを使用します。応答には、LogResultフィールドが含まれます。このフィールドには、呼び出しからのbase 64でエンコードされたログが最大4KB含まれます。
コマンドは次のようになります。
aws lambda invoke --function-name ohara-bob-node-cli out --log-type Tail
`LogResults`の情報をデコードすると、関連するログ情報が取得できます。
次はPythonソースコードをLambdaでデプロイする方法をご紹介します。python_test_zip_awsというソースコードフォルダを作成し、lambda_handler関数を含めたindex.pyを作成します。ここでは、Event Handlerを例とします。
上記のソースコードは次の通りです。
import requests
def handler(event, context):
response = requests.get('http://google.com/')
print(response.text)
return response.status_code
LambdaのPythonランタイム環境は、一般的なPythonモジュールに加えて、AWS SDKライブラリを含むビルドインモジュールを提供します。カスタマイズされたScriptには、サードパーティの依存関係が必要な場合があります。
今回のスクリプトでは、HTTP通信用ライブラリのrequestsという名前のサードパーティパッケージが必要であり、デプロイ前にローカルで準備する必要があります。これらのパッケージはpipを使用してローカルで管理します。
`pip3 install <パッケージ名> -t .` コマンドを実行して必要なパッケージをローカルにインストールすると、index.pyに関連するパッケージフォルダができます。
次に、ソースコードフォルダ内のすべてのファイルをZIPファイルへ圧縮します。ZIPファイル生成後はLambda上でデプロイする際に使用します。
デプロイしたいPythonソースコードの準備が出来たら、ターミナルからCLIコマンドを使用して新しいlambda関数を作成します。今回はPythonスクリプトなので、Handlerおよびランタイムに注意する必要があります。参考のために lambda runtimes を確認することもできます。
aws lambda create-function --function-name ohara-bob-python-cli --zip-file fileb://python_test_zip_aws.zip --handler lambda_function.lambda_handler --timeout 900 --runtime python3.9 --role
コマンド入力が正しければ、コンソール画面にてFunction Nameとコードが表示されます。
コンソール画面で作成した関数のコード、スクリプト、ランタイム、などをチェックします。コマンドの引数パラメータが正しければ、関連するソースコードと依存パッケージが正しく表示されています。
payloadパラメータとlogパラメータを指定して作成された関数を呼び出します。上記のデプロイする関数コードの中身は、Googleホームページにアクセスし、関連するHTTPステータスコードを返すものです。
以下の通りコマンドを入力します。
aws lambda invoke --function-name ohara-bob-python-cli --payload eyJ0ZXN0IjoiQm9iIn0= response.json --log-type Tail
テストの結果、HTTP 200が無事返却されたので、成功です。以上が、CLIベースでLambda上のPythonソースコードをデプロイする方法になります。
次のようなエラーが発生した場合は、ヒントに従って修正してください。
Missing required parameters(必要なパラメータが見つかりません) → 正しい値で追加してください。
Set invalid values for parameters(パラメータに無効な値を設定) → サポートされている値を確認して修正してください。
Permission errors(アクセス許可エラー) → ユーザーと共にラムダサービスに関連ポリシーを付加します。
Error with assume role actions(権限を引き受けるアクションのエラー)→ 信頼ポリシーで役割を更新するか、有効な役割に切り替えてください。
選択されたロールには、サービスプリンシパル lambda.amazonaws.com に AWS Security Token Service (AWS STS) AssumeRoleアクションを呼び出す権限を与えることで、Lambdaがロールの権限を使用できるようにする信頼ポリシーが必要です。
詳細については、実行ロールを確認してください。
Invalid payload(無効なペイロード)→ base64に基づいてエンコードされた正しいjson文字列をペイロードとして使用します。
これを行うには、update-function-codeコマンドを使用します。既存のPythonコードを更新し、最初にZIPパッケージを再準備します。
ローカルのZIPパッケージからソースコードを更新するコマンドを実行します。
aws lambda update-function-code --function-name ohara-bob-python-cli --zip-file fileb://python_test_zip_aws_new.zip
コンソールからコードを確認します。
AWS Lambda をCLIベースでNode.jsおよびPythonそれぞれをデプロイする方法をご紹介しました。サーバレスアプリケーションはコードを記述しながら実行できるクラウドサービスなので、エンジニアリングリソースを小さくしてくれるため非常に便利です。
一方、複数の開発者による並列操作、環境構成の管理、ランタイムで例えばPythonのバージョン変更など各環境で些細な変更が生じても素早く変更、自動的にデプロイしたい場合は、コンソール画面での操作では手入力等反映リソースが追いつかなくなるため、Infrastructure as Code(IaC)ベースで運用するのがベターです。
本記事では、IaCを意識しながらAWS CLIコマンドツールを介して、ローカルにあるソースコードをLambdaへ直接アップロード保存し、そのままイベント操作をする方法を記載していますので、CI/CDパイプラインでサーバレスアプリケーションを構築する際はご参考になれば幸いです。(実際はCloud9、CodePipline、Codebuild、CodeDeployなどを併用利用する場合がありますが、機会があればその旨紹介したいと思います)
条件に該当するページがございません