@infodb/lctl
v0.15.1
Published
AWS Lambda Control Tool - Simple CLI for managing Lambda functions
Maintainers
Readme
lctl - Lambda Control Tool
概要
AWS Lambda関数を簡単に管理するためのCLIツール。YAML設定ファイルによる設定管理と、内部的なAWS CLIを使用したLambda関数の作成、更新、削除を行います。
インストール・実行方法
pnpx @infodb/lctl [コマンド] [設定ファイル名] [オプション]基本的な使用方法
1. プロジェクト構成を作成
project/
├── configs/ # 設定ファイル(必須)
│ ├── my-function.yaml
│ └── other-function.yaml
├── functions/ # Lambda関数コード(必須)
│ ├── my-function.py
│ └── utils.py
└── my-function.zip # 生成されるデプロイパッケージ2. YAML設定ファイルを作成
configs/my-function.yaml:
# 基本設定
function_name: my_function # 実際のLambda関数名
runtime: python3.12
handler: my_function.handler
role: arn:aws:iam::123456789012:role/lambda-execution-role
# ファイル設定
files:
- my_function.py
- utils.py
# Python依存関係(自動インストール)
requirements:
- requests>=2.28.0
- boto3>=1.26.0
# 環境変数
environment:
ENV: production
# 権限設定
permissions:
- service: apigateway
source_arn: "arn:aws:execute-api:us-east-1:123456789012:*"3. デプロイ実行
# 一括デプロイ(推奨)
pnpx @infodb/lctl deploy my-function
# または個別実行
pnpx @infodb/lctl makezip my-function # ZIPパッケージ作成
pnpx @infodb/lctl export my-function # スクリプト生成
bash deploy-my-function.sh # デプロイ実行コマンド一覧
1. makezip - デプロイパッケージの作成
pnpx @infodb/lctl makezip <config-name> [オプション]必須引数:
config-name: 設定ファイル名(.yaml拡張子は不要)
オプション:
--output-dir <dir>: ZIPパッケージの出力先ディレクトリ(デフォルト: カレントディレクトリ)--verbose: 詳細なログを出力
機能:
requirementsセクションがあれば自動的にpip installを実行- 既存のvendorフォルダを削除
- 適切なディレクトリ構造で
<function-name>.zipを作成
例:
pnpx @infodb/lctl makezip my-function --verbose
pnpx @infodb/lctl makezip my-function --output-dir ./dist2. deploy - Lambda関数の完全デプロイ(推奨)
pnpx @infodb/lctl deploy <config-name> [オプション]必須引数:
config-name: 設定ファイル名(.yaml拡張子は不要)
オプション:
--verbose: 詳細なログを出力
動作:
makezipコマンドを自動実行(ZIPパッケージ作成)exportコマンドを自動実行(デプロイスクリプト生成)- 生成されたスクリプトを実行(AWS Lambda関数デプロイ)
例:
# 基本的な使用方法
pnpx @infodb/lctl deploy my-function
# 詳細ログ付き
pnpx @infodb/lctl deploy my-function --verbose3. export - デプロイスクリプトの生成
pnpx @infodb/lctl export <config-name> [オプション]必須引数:
config-name: 設定ファイル名(.yaml拡張子は不要)
オプション:
--output <file>: 出力ファイルパス(デフォルト: deploy-{config-name}.sh)--output-dir <dir>: スクリプトの出力先ディレクトリ(デフォルト: カレントディレクトリ、--output指定時は無視)--verbose: 詳細なログを出力
機能:
<function-name>.zipの存在チェックを含むスクリプトを生成- CI/CD環境で個別実行するのに適している
例:
# スクリプト生成
pnpx @infodb/lctl export my-function
# カスタム出力ファイル
pnpx @infodb/lctl export my-function --output custom-deploy.sh
# 出力先ディレクトリを指定(makezipと同じディレクトリを指定するとそのままデプロイに使える)
pnpx @infodb/lctl makezip my-function --output-dir ./dist
pnpx @infodb/lctl export my-function --output-dir ./dist4. delete - Lambda関数の削除
pnpx @infodb/lctl delete <config-name> [オプション]必須引数:
config-name: 設定ファイル名(.yaml拡張子は不要)
オプション:
--verbose: 詳細なログを出力
例:
pnpx @infodb/lctl delete my-function5. info - Lambda関数の詳細情報表示
pnpx @infodb/lctl info <config-name> [オプション]必須引数:
config-name: 設定ファイル名(.yaml拡張子は不要)
オプション:
--verbose: 詳細なログを出力
例:
pnpx @infodb/lctl info my-function6. gen-routes - Terraform定義から routes.json を生成
pnpx @infodb/lctl gen-routes <plan-json> [オプション]入力:
plan-json:terraform show -jsonを保存したファイルパス
オプション:
--output <file>: 生成するroutes.jsonの出力先(デフォルト:routes.json)--verbose: 解析過程を詳細表示
機能:
aws_apigatewayv2_route/aws_apigatewayv2_integrationリソースを走査し、routeKeyと Lambda の紐付けを抽出- Integration URI から Lambda 関数名を解析して
{ "method": "GET", "path": "/foo", "lambda": "lambda_foo" }形式に整形 - 紐付けが不完全な場合はエラー終了し、問題箇所を表示
例:
terraform show -json tfplan.out > tfplan.json
pnpx @infodb/lctl gen-routes tfplan.json --output routes.json7. serve - HTTP → Lambda ローカルサーバを起動
pnpx @infodb/lctl serve [オプション]オプション:
--routes <file>:routes.jsonのパス(デフォルト:routes.json)--port <port>: 起動ポート(デフォルト:3000)--config-dir <dir>:configs/を別パスに変更したい場合に指定--functions-dir <dir>: Lambda ソースが配置されたディレクトリ(デフォルト:functions/)--verbose: ルーティングや Lambda 実行ログを詳細表示
機能:
routes.jsonと YAML 設定からローカルの Lambda ハンドラーを特定- Express ベースの HTTP サーバを起動し、API Gateway HTTP API v2 のイベント(
version,routeKey,rawPath,headers,body,requestContext.http)を再現 - Node.js ランタイムは
requireで直接呼び出し、Python ランタイムはpython3サブプロセス経由でhandler(event, context)を実行 - Lambda の戻り値
{ statusCode, headers, body }を HTTP レスポンスへ変換
利用例:
# 1. Terraform から routes.json を生成
pnpx @infodb/lctl gen-routes tfplan.json
# 2. ローカル HTTP サーバを起動
pnpx @infodb/lctl serve --routes routes.json --port 4000注意:
routes.jsonに存在しない Lambda、またはhandlerがエクスポートされていない場合は起動時/実行時に例外となります。- Python モジュールは
functions/をPYTHONPATHに追加してインポートします。依存モジュールは同ディレクトリに配置してください。
使用シナリオ
ローカル開発
# 一括デプロイ(最も簡単)
pnpx @infodb/lctl deploy my-functionCI/CD環境
# 段階的デプロイ(制御しやすい)
pnpx @infodb/lctl makezip my-function # ZIPパッケージ作成
pnpx @infodb/lctl export my-function # スクリプト生成
bash deploy-my-function.sh # デプロイ実行レガシーコマンド(v0.8.0以前との互換性)
export - デプロイメントスクリプトの出力
pnpx @infodb/lctl export <config-name> [オプション]必須引数:
config-name: 設定ファイル名(.yaml拡張子は不要)
オプション:
--output <file>: 出力ファイルパス(デフォルト: deploy-{config-name}.sh)--output-dir <dir>: スクリプトの出力先ディレクトリ(デフォルト: カレントディレクトリ、--output指定時は無視)--verbose: 詳細なログを出力
例:
# スクリプト出力
pnpx @infodb/lctl export my-function --output deploy-script.sh
# 環境変数を使用してスクリプト出力
ENV_NAME=prod DB_HOST=prod.example.com pnpx @infodb/lctl export my-functionエクスポートされたスクリプトについて(v0.14.0+):
- スクリプトは bash + AWS CLI のみで動作します(lctl / Node.js は不要)。
jqがあれば出力を整形しますが、無くても動作します。 - YAML内の
${VAR}はmakezip/exportの実行時には展開せず、生成されたスクリプトの実行時にすべて展開します(function_name、role、environment、tags、permissions、vpc、function_url/corsなど、スクリプトに出力される全フィールドが対象)。これにより同じ ZIP + スクリプトを、実行環境ごとに変数を変えて複数の環境(dev/staging/prod など)へ使い回せます。参照している変数が未設定の場合、スクリプトは冒頭で明確なエラーを出して停止します。 - スクリプトは実行後も ZIP ファイルを削除しません(deploy コマンド経由の場合は deploy が後始末します)。
- スクリプトと
<config-name>.zipを同じディレクトリに配置して実行してください。リージョンは実行環境の AWS CLI 設定(AWS_DEFAULT_REGION等)に従います。
YAML設定ファイル(必須)
設定ファイルは configs/ ディレクトリに配置し、configs/<config-name>.yaml 形式で命名します。
基本的な設定例
# configs/my-function.yaml
# 関数名設定(オプション)
function_name: ${ENV_NAME}_my_function # 環境変数を使用した動的命名
# function_name: my_function # 固定名
# 未設定の場合、設定ファイル名(my-function)を使用
# 基本設定
runtime: python3.12
handler: my_function.handler
role: arn:aws:iam::123456789012:role/lambda-execution-role
architecture: x86_64 # x86_64 または arm64
memory: 256
timeout: 30
description: "マイ Lambda 関数"
# デプロイするファイル(functionsディレクトリ内の相対パス)
files:
- my_function.py
- utils.py
- "lib/**/*.py" # glob パターンも使用可能
# Python依存関係(自動インストール)
requirements:
- requests>=2.28.0
- boto3>=1.26.0
- pandas>=1.5.0
# 環境変数
environment:
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
API_KEY: ${API_KEY}
ENV: ${ENV_NAME}
# 権限設定(外部サービスからの呼び出し許可)
permissions:
- service: apigateway
source_arn: "arn:aws:execute-api:us-east-1:123456789012:*"
statement_id: "api-gateway-invoke"
- service: events
source_arn: "arn:aws:events:us-east-1:123456789012:rule/my-rule"
statement_id: "eventbridge-invoke"
# ログ設定
log_retention_days: 14 # ログ保持期間(日)
auto_create_log_group: true # ロググループ自動作成
# ZIP除外設定
zip_excludes: # ZIP化時の除外パターン
- "*.git*"
- "node_modules/*"
- "*.zip"
- "*.pyc"
- "__pycache__/*"
# タグ
tags:
Environment: ${ENV_NAME}
Team: backend
Project: my-project高度な設定例
# 高度な設定
reserved_concurrency: 100
provisioned_concurrency: 10
ephemeral_storage: 1024 # MB (512-10240)
# レイヤー
layers:
- arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1
- arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14
# VPC設定
vpc:
subnets:
- subnet-12345678
- subnet-87654321
security_groups:
- sg-12345678
# デッドレターキュー
dead_letter_queue:
target_arn: arn:aws:sqs:us-east-1:123456789012:my-dlq権限設定(permissions)
外部サービスやIAMユーザー・ロールからLambda関数を呼び出すための権限を自動設定します。
サービス別の権限設定
permissions:
- service: apigateway # API Gateway
source_arn: "arn:aws:execute-api:region:account:api-id/*"
- service: events # EventBridge
source_arn: "arn:aws:events:region:account:rule/rule-name"
- service: sns # SNS
source_arn: "arn:aws:sns:region:account:topic-name"
- service: s3 # S3
source_arn: "arn:aws:s3:::bucket-name"
- service: elasticloadbalancing # ALB
source_arn: "arn:aws:elasticloadbalancing:region:account:targetgroup/name"IAMユーザー・ロールの直接指定
permissions:
- principal: "arn:aws:iam::123456789012:user/MyUser"
statement_id: "allow-my-user"
action: "lambda:InvokeFunction"
- principal: "arn:aws:iam::123456789012:role/MyRole"
statement_id: "allow-my-role"
- principal: "123456789012" # AWS Account ID
statement_id: "allow-account"混合設定例
permissions:
# サービス別設定(principalは自動設定)
- service: apigateway
source_arn: "arn:aws:execute-api:region:account:api-id/*"
statement_id: "api-gateway-invoke"
# IAMユーザー直接指定
- principal: "arn:aws:iam::123456789012:user/DeployUser"
statement_id: "deploy-user-invoke"
action: "lambda:InvokeFunction"
# IAMロール直接指定
- principal: "arn:aws:iam::123456789012:role/CrossAccountRole"
statement_id: "cross-account-invoke"
source_arn: "arn:aws:iam::123456789012:role/CrossAccountRole"注意: service または principal のどちらか一方を必ず指定してください。両方指定した場合は principal が優先されます。
環境変数による動的設定
# 環境変数を使用した設定
function_name: ${ENV_NAME}_my_function
role: arn:aws:iam::123456789012:role/lambda-role-${ENV_NAME}
environment:
DB_HOST: ${DB_HOST}
ENV: ${ENV_NAME}
tags:
Environment: ${ENV_NAME}実行時に環境変数を設定:
ENV_NAME=prod DB_HOST=prod.example.com pnpx @infodb/lctl deploy my-function変数展開のタイミング(v0.14.0+):
makezip/exportは、スクリプトに出力されるフィールド(function_name、role、environment、tags、permissions、vpc、function_urlなど)の${VAR}を一切展開せず、生成スクリプトにプレースホルダのまま埋め込みます。実際の展開は生成されたスクリプトの実行時に行われます。- そのため
makezip/export(および両方をまとめて実行するdeploy)はビルド時にデプロイ先の環境変数を知っている必要がありません。同じ ZIP + スクリプトを、実行時に環境変数を変えるだけで dev/staging/prod など複数環境へデプロイできます。 deployはスクリプト生成直後に同じプロセスの環境変数でスクリプトを実行するため、これまで通り一括で完結します。info/deleteは AWS を直接呼び出すため、コマンド実行時に${VAR}を即時展開します(実行するシェルで対象環境の変数を設定してください)。
- そのため
環境要件
- Node.js 16以上
- AWS CLI v2がインストールされていること
- 適切なAWS認証情報が設定されていること
configs/とfunctions/ディレクトリが存在すること
AWS認証情報の設定
以下のいずれかの方法でAWS認証情報を設定してください:
- AWS CLIによる設定:
aws configure- 環境変数による設定:
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
export AWS_DEFAULT_REGION=us-east-1- IAMロールの使用(EC2、Lambda等)
必要なIAM権限
lctl自体はAWS CLIを呼び出すラッパーなので、実行するユーザー/ロールには以下のIAM権限が必要です。--actionに何を指定していても、add-permission/remove-permissionの呼び出しに必要なIAMアクションは常にlambda:AddPermission/lambda:RemovePermissionです(--actionはリソースベースポリシー側で許可する対象を指定するものであり、呼び出し元のIAM権限とは別物です)。
deploy / exportで生成されるスクリプトの実行に必要な権限
| 権限 | 用途 |
|---|---|
| lambda:GetFunction | 関数の存在確認、wait function-updated、タグ付け時のARN取得 |
| lambda:CreateFunction | 新規関数の作成 |
| lambda:UpdateFunctionCode | 既存関数のコード更新 |
| lambda:UpdateFunctionConfiguration | 設定更新(VPC、デッドレターキュー、エフェメラルストレージを含む) |
| lambda:PutFunctionConcurrency | reserved_concurrency設定時 |
| lambda:DeleteFunctionConcurrency | reserved_concurrency未設定時、既存の予約済み同時実行数の解除 |
| lambda:TagResource | tags設定時 |
| lambda:AddPermission | permissions設定、Function URLの公開許可 |
| lambda:RemovePermission | 上記の再デプロイ時のクリーンアップ |
| lambda:GetFunctionUrlConfig | Function URL設定の存在確認・表示 |
| lambda:CreateFunctionUrlConfig | Function URLの新規作成 |
| lambda:UpdateFunctionUrlConfig | Function URLの設定更新 |
| lambda:DeleteFunctionUrlConfig | function_url未設定時の既存設定削除 |
| logs:DescribeLogGroups | ロググループの存在確認 |
| logs:CreateLogGroup | ロググループの作成(auto_create_log_group: true時) |
| logs:PutRetentionPolicy | ログ保持期間の設定 |
| iam:PassRole(対象: roleに指定したLambda実行ロールのARN) | 関数の作成・更新時にLambda実行ロールを渡すために必須 |
deleteコマンドに必要な権限
| 権限 | 用途 |
|---|---|
| lambda:DeleteFunctionUrlConfig | Function URL設定の削除 |
| lambda:DeleteFunction | 関数の削除 |
infoコマンドに必要な権限
| 権限 | 用途 |
|---|---|
| lambda:GetFunction | 関数情報の取得 |
| lambda:GetFunctionUrlConfig | Function URL情報の取得 |
IAMポリシー例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:GetFunction",
"lambda:CreateFunction",
"lambda:UpdateFunctionCode",
"lambda:UpdateFunctionConfiguration",
"lambda:PutFunctionConcurrency",
"lambda:DeleteFunctionConcurrency",
"lambda:TagResource",
"lambda:AddPermission",
"lambda:RemovePermission",
"lambda:GetFunctionUrlConfig",
"lambda:CreateFunctionUrlConfig",
"lambda:UpdateFunctionUrlConfig",
"lambda:DeleteFunctionUrlConfig",
"lambda:DeleteFunction"
],
"Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:*"
},
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogGroups",
"logs:CreateLogGroup",
"logs:PutRetentionPolicy"
],
"Resource": "arn:aws:logs:REGION:ACCOUNT_ID:log-group:/aws/lambda/*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::ACCOUNT_ID:role/lambda-execution-role"
}
]
}Resourceはできるだけ絞り込み、対象のLambda関数・ロググループ・実行ロールのARNに限定することを推奨します。
トラブルシューティング
よくある問題
- AWS CLI not found: AWS CLI v2がインストールされていることを確認
- 権限エラー: 適切なIAMロールとポリシーが設定されていることを確認
- YAML設定ファイルが見つからない:
configs/<config-name>.yamlが存在することを確認 - YAML構文エラー: YAML ファイルの構文を確認
- 環境変数が見つからない:
${VAR_NAME}で参照する環境変数が設定されていることを確認
デバッグ
# 詳細ログ出力
pnpx @infodb/lctl deploy my-function --verbose
# スクリプト出力してデバッグ
pnpx @infodb/lctl export my-function --output debug-script.sh
bash debug-script.sh