- AWS
AWS CLIでLambdaを作成・更新 環境変数とレイヤー
AWS CLI で Lambda 関数を扱う流れは、「実行ロールを作る → コードを zip にする → create-function で作る → update-function-code と update-function-configuration で更新する」の4段階です。 コードの更新と設定の更新は別のコマンドに分かれていて、環境変数とレイヤーは「指定した内容で全体を置き換える」動きをします。
この記事では、ロール作成から関数の削除までを1本の流れとして、コマンドと返ってくる JSON をそろえて順に載せます。環境変数が置き換えで消える様子を前後の出力で示し、既存の変数を残したまま1つ追加する手順、エラー文と原因の対応表、wait コマンドの使い方までまとめました。
確認環境:Ubuntu 24.04 / AWS CLI 1.46.1 / Python 3.11.15 / Zip 3.0。AWS の API をローカルで再現するツール(moto 5.2.3)で実行しています。掲載コマンドは接続先の指定を外してあり、実際の AWS でそのまま使える形です。アカウント ID は 123456789012、リージョンは ap-northeast-1 で統一しています。
aws lambda サブコマンドの早見表
| やりたいこと | コマンド | 主な必須オプション | 返ってくるもの |
|---|---|---|---|
| 関数を作る | aws lambda create-function |
--function-name --runtime --handler --role --zip-file |
関数の設定 JSON |
| コードを更新する | aws lambda update-function-code |
--function-name --zip-file |
関数の設定 JSON(CodeSha256 が変わる) |
| 設定を更新する | aws lambda update-function-configuration |
--function-name と変えたい項目 |
関数の設定 JSON |
| 環境変数を設定する | aws lambda update-function-configuration --environment |
Variables={KEY=値,...} |
関数の設定 JSON(Environment) |
| 設定を見る | aws lambda get-function-configuration |
--function-name |
関数の設定 JSON |
| 設定とコードの場所を見る | aws lambda get-function |
--function-name |
Configuration と Code |
| 関数を一覧する | aws lambda list-functions |
なし | Functions の配列 |
| レイヤーを公開する | aws lambda publish-layer-version |
--layer-name --zip-file |
LayerVersionArn と Version |
| レイヤーを関数に付ける | aws lambda update-function-configuration --layers |
レイヤーバージョンの ARN | 関数の設定 JSON(Layers) |
| レイヤーを一覧する | aws lambda list-layers / list-layer-versions |
--layer-name(後者) |
レイヤーとバージョンの配列 |
| バージョンを発行する | aws lambda publish-version |
--function-name |
Version が数字になった設定 JSON |
| エイリアスを作る | aws lambda create-alias |
--function-name --name --function-version |
AliasArn など |
| エイリアスの向き先を変える | aws lambda update-alias |
--function-name --name --function-version |
AliasArn など |
| バージョンを一覧する | aws lambda list-versions-by-function |
--function-name |
Versions の配列 |
| 状態が整うまで待つ | aws lambda wait function-active-v2 / function-updated-v2 |
--function-name |
出力なし(終了コードで判定) |
| 関数を消す | aws lambda delete-function |
--function-name |
出力は StatusCode のみ |
| レイヤーのバージョンを消す | aws lambda delete-layer-version |
--layer-name --version-number |
出力なし |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS CLIでLambdaを作成・更新 環境変数とレイヤー」
準備:実行ロールを作る(iam create-role)
Lambda 関数には、関数が動くときに使う IAM ロール(実行ロール)が必ず1つ必要です。create-function の --role に、このロールの ARN を渡します。
まず「Lambda サービスがこのロールを引き受けてよい」と書いた信頼ポリシーをファイルにします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
これを trust-policy.json として保存し、ロールを作ります。
aws iam create-role \
--role-name lambda-basic-role \
--assume-role-policy-document file://trust-policy.json
{
"Role": {
"Path": "/",
"RoleName": "lambda-basic-role",
"RoleId": "AROARZPUZDIKD6W643C7C",
"Arn": "arn:aws:iam::123456789012:role/lambda-basic-role",
"CreateDate": "2026-10-05T06:32:16.655987Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"MaxSessionDuration": 3600,
"RoleLastUsed": {}
}
}
出力の Arn が、あとで --role に渡す値です。
ログを CloudWatch Logs に書けるようにするには、AWS が用意している管理ポリシー AWSLambdaBasicExecutionRole を付けます。AWS 公式ドキュメント「Lambda 実行ロール」に載っているコマンドは次のとおりです。
aws iam attach-role-policy \
--role-name lambda-basic-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
zip を作って関数を作成する(create-function)
コードを zip にまとめる
関数のコードを lambda_function.py として用意します。
import os
def lambda_handler(event, context):
return {"message": "hello", "stage": os.environ.get("STAGE", "none")}
zip function.zip lambda_function.py
adding: lambda_function.py (deflated 10%)
ハンドラーのファイルは zip の最上位に置きます。 フォルダごと固めると、zip の中でフォルダの下に入ってしまい、--handler の指定と合わなくなります。フォルダの中身を固めたいときは、そのフォルダに移動してから zip -r ../function.zip . のようにします。
create-function を実行する
aws lambda create-function \
--function-name hello-fn \
--runtime python3.13 \
--handler lambda_function.lambda_handler \
--role arn:aws:iam::123456789012:role/lambda-basic-role \
--zip-file fileb://function.zip
{
"FunctionName": "hello-fn",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:hello-fn",
"Runtime": "python3.13",
"Role": "arn:aws:iam::123456789012:role/lambda-basic-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 296,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"CodeSha256": "UloxOeWAsFb139dAVuYiOWezoOZkyAP7RT0xsNH8a1Y=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"Layers": [],
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
…(省略)…
}
出力から読み取れる要点は次のとおりです。
| 項目 | 値 | 意味 |
|---|---|---|
| Timeout | 3 | 指定しないと 3 秒 |
| MemorySize | 128 | 指定しないと 128 MB |
| Version | $LATEST |
作った直後は「最新」を指す特別なバージョンだけがある |
| CodeSha256 | ハッシュ値 | zip の中身から計算される値。コードを更新すると変わる |
| Architectures | x86_64 | 指定しないと x86_64。--architectures arm64 で変えられる |
--handler は「ファイル名(拡張子なし).関数名」の形です。lambda_function.py の lambda_handler なら lambda_function.lambda_handler になります。
--zip-file は fileb:// で渡す
zip はバイナリなので、file:// ではなく fileb:// を使います。 3通りの書き間違いで、それぞれ次のメッセージが出ます。
aws lambda create-function --function-name hello-fn2 (中略) --zip-file file://function.zip
Error parsing parameter '--zip-file': Unable to load paramfile (function.zip), text contents could not be decoded. If this is a binary file, please use the fileb:// prefix instead of the file:// prefix.
aws lambda create-function --function-name hello-fn2 (中略) --zip-file function.zip
--zip-file must be a zip file with the fileb:// prefix.
Example usage: --zip-file fileb://path/to/file.zip
aws lambda create-function --function-name hello-fn2 (中略) --zip-file fileb://nothing.zip
Error parsing parameter '--zip-file': Unable to load paramfile fileb://nothing.zip: [Errno 2] No such file or directory: 'nothing.zip'
パスは、コマンドを実行しているフォルダからの相対パスです。絶対パスなら fileb:///home/taro/app/function.zip のようにスラッシュが3つ並びます。
状態が整うまで待つ(wait)
AWS 公式ドキュメント「Lambda 関数の状態」によると、関数は作成直後に Pending という状態になり、準備が終わると Active に変わります。Pending の間は Invoke・UpdateFunctionCode・UpdateFunctionConfiguration・PublishVersion が受け付けられません。 同じように、更新が進行中(LastUpdateStatus が InProgress)の間は UpdateFunctionCode・UpdateFunctionConfiguration・PublishVersion・TagResource が受け付けられません。
そこで、作成や更新のコマンドの直後に wait を挟むと、次のコマンドを安心して続けられます。
aws lambda wait function-active-v2 --function-name hello-fn
aws lambda get-function-configuration --function-name hello-fn \
--query '[State,LastUpdateStatus]'
[
"Active",
"Successful"
]
wait は条件を満たすと何も出力せずに終了コード 0 で終わります。使える待機条件と、確認の間隔・回数は次のとおりです(AWS CLI 1.46.1 に入っている定義から取り出した値です)。
| wait のサブコマンド | 待つ条件 | 確認の間隔 | 最大回数 |
|---|---|---|---|
function-active-v2 |
State が Active になる | 1 秒 | 300 回 |
function-updated-v2 |
LastUpdateStatus が Successful になる | 1 秒 | 300 回 |
function-exists |
関数が存在する | 1 秒 | 20 回 |
function-active |
State が Active になる | 5 秒 | 60 回 |
function-updated |
LastUpdateStatus が Successful になる | 5 秒 | 60 回 |
published-version-active |
発行したバージョンが Active になる | 5 秒 | 312 回 |
最大回数まで確認しても条件を満たさないと、終了コード 255 で止まります。存在しない関数に function-exists を使うと、20 回確認したあとに次のメッセージが出ました。
Waiter FunctionExists failed: Max attempts exceeded. Previously accepted state: Matched expected service error code: ResourceNotFoundException
コードを更新する(update-function-code)
lambda_function.py の "hello" を "hello v2" に書き換え、zip を作り直してから更新します。
zip function.zip lambda_function.py
aws lambda update-function-code \
--function-name hello-fn \
--zip-file fileb://function.zip
aws lambda wait function-updated-v2 --function-name hello-fn
{
"FunctionName": "hello-fn",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:hello-fn",
"Runtime": "python3.13",
"Role": "arn:aws:iam::123456789012:role/lambda-basic-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 299,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"CodeSha256": "JwsLOq1tBtMfSlHbbbmXjile5WMi06U2YzfrF4EVnso=",
"Version": "$LATEST",
…(省略)…
"LastUpdateStatus": "Successful",
…(省略)…
}
CodeSize が 296 から 299 に、CodeSha256 が別の値に変わっています。 この2つを見れば、新しい zip が反映されたことを確かめられます。update-function-code が変えるのはコードだけで、タイムアウトや環境変数などの設定はそのまま残ります。
--publish を付けると、更新と同時にバージョンも発行できます(後述の publish-version を続けて実行するのと同じ結果です)。
設定を更新する(update-function-configuration)
タイムアウト・メモリ・説明・ランタイム・ハンドラーなどは update-function-configuration で変えます。指定した項目だけが変わり、指定しなかった項目はそのままです。
aws lambda update-function-configuration \
--function-name hello-fn \
--timeout 30 \
--memory-size 256 \
--description 'hello function'
{
"FunctionName": "hello-fn",
…(省略)…
"Handler": "lambda_function.lambda_handler",
"CodeSize": 299,
"Description": "hello function",
"Timeout": 30,
"MemorySize": 256,
…(省略)…
}
よく使うオプションをまとめます。
| 変えたいもの | オプション | 例 |
|---|---|---|
| タイムアウト(秒) | --timeout |
--timeout 30 |
| メモリ(MB) | --memory-size |
--memory-size 256 |
| 説明 | --description |
--description 'hello function' |
| ランタイム | --runtime |
--runtime python3.14 |
| ハンドラー | --handler |
--handler app.handler |
| 実行ロール | --role |
--role arn:aws:iam::123456789012:role/別のロール |
| 環境変数 | --environment |
--environment 'Variables={STAGE=dev}' |
| レイヤー | --layers |
--layers レイヤーバージョンのARN |
返ってくる JSON は長いので、確かめたい項目だけを --query で取り出すと読みやすくなります。
aws lambda get-function-configuration --function-name hello-fn \
--query '{name:FunctionName,runtime:Runtime,handler:Handler,state:State}'
{
"name": "hello-fn",
"runtime": "python3.13",
"handler": "lambda_function.lambda_handler",
"state": "Active"
}
環境変数を設定する(--environment は全体置き換え)
最初の設定
aws lambda update-function-configuration \
--function-name hello-fn \
--environment 'Variables={STAGE=dev,TABLE_NAME=orders}'
aws lambda get-function-configuration --function-name hello-fn --query Environment
{
"Variables": {
"STAGE": "dev",
"TABLE_NAME": "orders"
}
}
1つ足したつもりで実行すると、既存の変数が消える
ここで LOG_LEVEL を追加しようとして、追加したい変数だけを書いて実行します。
aws lambda update-function-configuration \
--function-name hello-fn \
--environment 'Variables={LOG_LEVEL=DEBUG}' \
--query Environment
{
"Variables": {
"LOG_LEVEL": "DEBUG"
}
}
STAGE と TABLE_NAME が消え、LOG_LEVEL だけになりました。 --environment は「足す」のではなく「Variables 全体を、渡した内容に置き換える」動きをします。AWS 公式ドキュメント「Lambda 環境変数」にも、update-function-configuration で環境変数を適用すると Variables 構造体の内容全体が置き換わること、既存の変数を残すにはすべての値をリクエストに含めることが書かれています。
| 実行前 | 渡した内容 | 実行後 |
|---|---|---|
| STAGE, TABLE_NAME | LOG_LEVEL | LOG_LEVEL だけ |
| STAGE, TABLE_NAME | STAGE, TABLE_NAME, LOG_LEVEL | 3つとも残る |
| STAGE, TABLE_NAME | Variables={} |
0個(Environment が null になる) |
既存の変数を残して1つ追加する手順(ファイルを使う)
安全に追加するには、今の変数を取り出す → 追加する変数を合わせる → 全体を渡す、の順に進めます。途中の JSON をファイルに残すので、渡す内容を目で確かめてから実行できます。
# 1. 今の変数を取り出す
aws lambda get-function-configuration --function-name hello-fn \
--query Environment.Variables --output json > vars.json
cat vars.json
{
"STAGE": "dev",
"TABLE_NAME": "orders"
}
# 2. 追加する変数を合わせて、Variables で包んだ JSON を作る
python3 -c "import json;v=json.load(open('vars.json')) or {};v['LOG_LEVEL']='DEBUG';json.dump({'Variables':v},open('env.json','w'),indent=2)"
cat env.json
{
"Variables": {
"STAGE": "dev",
"TABLE_NAME": "orders",
"LOG_LEVEL": "DEBUG"
}
}
# 3. ファイルごと渡す
aws lambda update-function-configuration \
--function-name hello-fn \
--environment file://env.json \
--query Environment.Variables
{
"STAGE": "dev",
"TABLE_NAME": "orders",
"LOG_LEVEL": "DEBUG"
}
手順2の or {} は、変数が1つも無い関数で vars.json が null になる場合に備えたものです。env.json はテキストなので、こちらは file:// で渡します。
--query の merge で1行にまとめる
--query(JMESPath という問い合わせ言語)の merge 関数を使うと、取り出しと合成を1回で済ませられます。
aws lambda update-function-configuration \
--function-name hello-fn \
--environment "$(aws lambda get-function-configuration \
--function-name hello-fn \
--query '{Variables: merge(Environment.Variables, `{"REGION_LABEL":"tokyo"}`)}' \
--output json)" \
--query Environment.Variables
{
"STAGE": "dev",
"TABLE_NAME": "orders",
"LOG_LEVEL": "DEBUG",
"REGION_LABEL": "tokyo"
}
バッククォートで囲んだ部分は JMESPath の JSON リテラルで、追加したいキーと値を書きます。同じキーがすでにあれば、後ろに書いた値で上書きされます。
値にカンマや記号が入るときは JSON で渡す
Variables={KEY=値,KEY=値} の短縮記法は、値にカンマ・等号・空白が入ると区切りと見分けがつかなくなります。接続文字列や URL のような値は、env.json のような JSON ファイルにして file:// で渡すと確実です。
環境変数の決まり(公式ドキュメントより)
AWS 公式ドキュメント「Lambda 環境変数」に書かれている決まりです。
| 項目 | 決まり |
|---|---|
| 合計サイズ | すべての環境変数を合わせて 4 KB まで |
| キーの形 | 文字で始まり、2文字以上。使えるのは英字・数字・アンダースコア |
| 予約済みのキー | AWS_REGION、AWS_DEFAULT_REGION、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN、AWS_LAMBDA_FUNCTION_NAME、LAMBDA_TASK_ROOT、_HANDLER などは設定できない |
| バージョンとの関係 | バージョンを発行すると、その時点の環境変数がそのバージョンに固定される |
レイヤーを公開して関数に付ける
レイヤーは、ライブラリや共通コードを関数本体と分けて持つための zip です。Python の場合、zip の中の python フォルダに入れたものが import できるようになります。
レイヤーを公開する(publish-layer-version)
mkdir -p python
echo 'def greet(name): return f"hi {name}"' > python/mylib.py
zip -r layer.zip python
adding: python/ (stored 0%)
adding: python/mylib.py (stored 0%)
aws lambda publish-layer-version \
--layer-name common-lib \
--description 'shared helpers' \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.13
{
"Content": {
"CodeSha256": "3MbNj+7XeH52vmf5Q94CqlozSBHO9vhwLeXUcA0KxyE=",
"CodeSize": 359,
…(省略)…
},
"LayerArn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib",
"LayerVersionArn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:1",
"Description": "shared helpers",
"CreatedDate": "2026-10-05T06:32:55.918+0000",
"Version": 1,
"CompatibleRuntimes": [
"python3.13"
],
…(省略)…
}
関数に付けるときに使うのは、末尾にバージョン番号が付いた LayerVersionArn のほうです。 LayerArn(番号なし)とは別の値なので、取り違えに気をつけます。
関数に付ける(--layers)
aws lambda update-function-configuration \
--function-name hello-fn \
--layers arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:1 \
--query Layers
[
{
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:1",
"CodeSize": 359
}
]
レイヤーを更新する:公開し直して、関数の指定も変える
レイヤーの中身を変えたいときは、同じ --layer-name でもう一度 publish-layer-version を実行します。上書きではなく、新しい番号が発行されます。
aws lambda publish-layer-version \
--layer-name common-lib \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.13 \
--query '[Version,LayerVersionArn]'
[
2,
"arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:2"
]
aws lambda list-layer-versions --layer-name common-lib \
--query 'LayerVersions[].[Version,LayerVersionArn]' --output text
2 arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:2
1 arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:1
関数は番号つきの ARN を覚えているので、新しい番号を公開しただけでは切り替わりません。 --layers に ...:common-lib:2 を渡して、関数側の指定も更新します。
--layers も全体置き換え
--layers も環境変数と同じく、渡した一覧で全体が置き換わります。複数のレイヤーを使う関数に1つ足すときは、今付いている ARN も並べて渡します。値を付けずに --layers だけを書くと、レイヤーがすべて外れました。
aws lambda update-function-configuration \
--function-name hello-fn --layers --query Layers
[]
今付いているレイヤーの ARN は次のコマンドで取り出せます。
aws lambda get-function-configuration --function-name hello-fn \
--query 'Layers[].Arn' --output text
バージョンを発行してエイリアスを付ける
バージョンを発行する(publish-version)
$LATEST は更新のたびに中身が変わります。publish-version を実行すると、その時点のコードと設定を写し取った、変更できない番号つきのバージョンができます。
aws lambda publish-version \
--function-name hello-fn \
--description 'first release'
{
"FunctionName": "hello-fn",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:hello-fn:1",
"Runtime": "python3.13",
…(省略)…
"Description": "first release",
"Timeout": 30,
"MemorySize": 256,
"CodeSha256": "JwsLOq1tBtMfSlHbbbmXjile5WMi06U2YzfrF4EVnso=",
"Version": "1",
"Environment": {
"Variables": {
"STAGE": "dev",
"TABLE_NAME": "orders",
"LOG_LEVEL": "DEBUG"
}
},
"Layers": [
{
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:common-lib:2",
"CodeSize": 359
}
],
…(省略)…
}
Version が "1" になり、FunctionArn の末尾にも :1 が付きました。環境変数とレイヤーも、この時点の内容がバージョン 1 に含まれています。
エイリアスを作る(create-alias)
エイリアスは、バージョンに付ける名前です。呼び出す側が hello-fn:prod のようにエイリアスで指定しておけば、新しいバージョンに切り替えるときはエイリアスの向き先を変えるだけで済みます。
aws lambda create-alias \
--function-name hello-fn \
--name prod \
--function-version 1
{
"AliasArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:hello-fn:prod",
"Name": "prod",
"FunctionVersion": "1",
"Description": "",
"RevisionId": "8bfd77b7-09f7-4c06-98a5-4c5d61f9c18d"
}
新しいバージョンに切り替える(update-alias)
コードを更新してバージョン 2 を発行し、prod を 2 に向け直します。
aws lambda update-function-code --function-name hello-fn \
--zip-file fileb://function.zip --publish \
--query '[Version,CodeSha256]'
[
"2",
"LsGkp/KGBBVuXQk5MOwsdrOslcfJ/0k3NbIqOQ/wRp4="
]
aws lambda update-alias --function-name hello-fn --name prod \
--function-version 2 --query '[Name,FunctionVersion]'
[
"prod",
"2"
]
元に戻したいときは --function-version 1 で同じコマンドを実行します。
一部の呼び出しだけ新しいバージョンに流す
--routing-config を使うと、エイリアスへの呼び出しを2つのバージョンに割合で振り分けられます。次の例は、基本はバージョン 1、1割だけバージョン 2 に流す設定です。
aws lambda update-alias --function-name hello-fn --name prod \
--function-version 1 \
--routing-config 'AdditionalVersionWeights={2=0.1}' \
--query '[Name,FunctionVersion,RoutingConfig]'
[
"prod",
"1",
{
"AdditionalVersionWeights": {
"2": 0.1
}
}
]
バージョン番号を引用符で囲んで {"2"=0.1} と書くと、CLI の解析で次のように止まります。短縮記法ではキーに引用符を付けません。
Error parsing parameter '--routing-config': Expected: '=', received: '"' for input:
AdditionalVersionWeights={"2"=0.1}
^
バージョンとエイリアスを一覧する
aws lambda list-versions-by-function --function-name hello-fn \
--query 'Versions[].[Version,Description,CodeSha256]' --output table
-------------------------------------------------------------------------------
| ListVersionsByFunction |
+---------+-----------------+-------------------------------------------------+
| $LATEST| hello function | LsGkp/KGBBVuXQk5MOwsdrOslcfJ/0k3NbIqOQ/wRp4= |
| 1 | first release | JwsLOq1tBtMfSlHbbbmXjile5WMi06U2YzfrF4EVnso= |
| 2 | hello function | LsGkp/KGBBVuXQk5MOwsdrOslcfJ/0k3NbIqOQ/wRp4= |
+---------+-----------------+-------------------------------------------------+
バージョン 1 は以前のコードのハッシュ値を保ったままで、$LATEST と 2 が同じ新しいコードを指しています。
関数名の後ろに :エイリアス名 を付けると、エイリアスが指すバージョンの情報を取れます。
aws lambda get-function --function-name hello-fn:prod \
--query 'Configuration.[FunctionArn,Version]'
[
"arn:aws:lambda:ap-northeast-1:123456789012:function:hello-fn:2",
"2"
]
関数を一覧・削除する
aws lambda list-functions \
--query 'Functions[].[FunctionName,Runtime,MemorySize,Timeout]' --output table
-----------------------------------------
| ListFunctions |
+-----------+--------------+------+-----+
| hello-fn | python3.13 | 256 | 30 |
+-----------+--------------+------+-----+
削除は、範囲の小さいものから順に進めると整理しやすくなります。
# エイリアスを消す(出力なし)
aws lambda delete-alias --function-name hello-fn --name prod
# 特定のバージョンだけ消す
aws lambda delete-function --function-name hello-fn --qualifier 1
# 関数をまるごと消す(すべてのバージョンとエイリアスも消える)
aws lambda delete-function --function-name hello-fn
{
"StatusCode": 204
}
--qualifier を付けるとそのバージョンだけ、付けないと関数全体が対象になります。確認の問い合わせは出ないので、関数名を見直してから実行します。
レイヤーと実行ロールは関数とは別のリソースなので、関数を消しても残ります。使わなくなったら個別に消します。
aws lambda delete-layer-version --layer-name common-lib --version-number 1
aws lambda delete-layer-version --layer-name common-lib --version-number 2
aws iam delete-role --role-name lambda-basic-role
ポリシーを付けたままのロールに delete-role を実行すると、次のメッセージで止まります。先に aws iam detach-role-policy --role-name lambda-basic-role --policy-arn ポリシーのARN で外してから、もう一度 delete-role を実行します。
An error occurred (DeleteConflict) when calling the DeleteRole operation: Cannot delete entity, must detach all policies first.
作成と更新を1本にまとめたスクリプト
「関数が無ければ作る、あれば更新する」を1つのスクリプトにまとめると、同じコマンドを繰り返し使えます。get-function の終了コードで分岐し、作成・更新のあとに wait を挟んでからバージョンを発行します。
#!/usr/bin/env bash
# 使い方: ./deploy.sh 関数名 ロールARN
set -euo pipefail
FUNCTION_NAME="$1"
ROLE_ARN="$2"
RUNTIME="python3.13"
HANDLER="lambda_function.lambda_handler"
rm -f function.zip
zip -q function.zip lambda_function.py
if aws lambda get-function --function-name "$FUNCTION_NAME" > /dev/null 2>&1; then
echo "update: $FUNCTION_NAME"
aws lambda update-function-code \
--function-name "$FUNCTION_NAME" \
--zip-file fileb://function.zip \
--query CodeSha256 --output text
aws lambda wait function-updated-v2 --function-name "$FUNCTION_NAME"
else
echo "create: $FUNCTION_NAME"
aws lambda create-function \
--function-name "$FUNCTION_NAME" \
--runtime "$RUNTIME" \
--handler "$HANDLER" \
--role "$ROLE_ARN" \
--zip-file fileb://function.zip \
--query CodeSha256 --output text
aws lambda wait function-active-v2 --function-name "$FUNCTION_NAME"
fi
VERSION=$(aws lambda publish-version \
--function-name "$FUNCTION_NAME" \
--query Version --output text)
echo "published version: $VERSION"
if aws lambda get-alias --function-name "$FUNCTION_NAME" --name prod > /dev/null 2>&1; then
aws lambda update-alias --function-name "$FUNCTION_NAME" --name prod \
--function-version "$VERSION" --query FunctionVersion --output text
else
aws lambda create-alias --function-name "$FUNCTION_NAME" --name prod \
--function-version "$VERSION" --query FunctionVersion --output text
fi
1回目(関数がまだ無い状態)の実行結果です。
$ ./deploy.sh hello-fn arn:aws:iam::123456789012:role/lambda-basic-role
create: hello-fn
LsGkp/KGBBVuXQk5MOwsdrOslcfJ/0k3NbIqOQ/wRp4=
published version: 1
1
コードを書き換えてからの2回目です。
$ ./deploy.sh hello-fn arn:aws:iam::123456789012:role/lambda-basic-role
update: hello-fn
vWe77Z0vG5OEw1XNgqpWlTBFjFcO/nM832+z6VoU00w=
published version: 2
2
1回目は create、2回目は update の経路を通り、prod エイリアスがそれぞれ 1、2 を指しました。
エラー文と原因の対応表
実行して出たメッセージと、その原因・直し方です。
| 出たメッセージ | 原因 | 直し方 |
|---|---|---|
ResourceConflictException ... CreateFunction operation: Function already exist: hello-fn |
同じ名前の関数がすでにある | 更新なら update-function-code を使う。上のスクリプトのように get-function で分岐する |
ResourceNotFoundException ... UpdateFunctionCode operation: Function not found: arn:aws:lambda:ap-northeast-1:123456789012:function:no-such-fn |
関数名の間違い、またはリージョンが違う | メッセージ中の ARN でリージョンと名前を確かめる。aws lambda list-functions で一覧する |
InvalidParameterValueException ... The role defined for the function cannot be assumed by Lambda. |
--role のロールが無い、または信頼ポリシーで lambda.amazonaws.com を許可していない |
ロールの ARN と信頼ポリシーを見直す |
aws: error: the following arguments are required: --role |
create-function の必須オプションが足りない | --role を付ける |
Error parsing parameter '--zip-file': Unable to load paramfile ... please use the fileb:// prefix |
file:// で zip を渡した |
fileb:// にする |
--zip-file must be a zip file with the fileb:// prefix. |
接頭辞なしでファイル名だけを書いた、または zip ではないファイルを渡した | fileb://function.zip の形にし、zip を作り直す |
Unable to load paramfile fileb://nothing.zip: [Errno 2] No such file or directory |
パスの先にファイルが無い | 実行しているフォルダと zip の場所を合わせる |
InvalidParameterValueException ... Error occurred while GetObject. S3 Error Code: NoSuchBucket. |
--code S3Bucket=... で渡したバケットが無い |
バケット名とリージョンを確かめる |
ConflictException ... CreateAlias operation: Alias already exists: arn:...:hello-fn:prod |
同じ名前のエイリアスがすでにある | 向き先の変更は update-alias を使う |
ResourceNotFoundException ... DeleteFunction operation: Function not found: ... |
すでに削除済み、または名前の間違い | 一覧で確かめる |
Waiter FunctionExists failed: Max attempts exceeded. |
wait が最大回数まで確認しても条件を満たさなかった | 関数名とリージョンを確かめる |
「Function not found」が出たときは、まずメッセージに含まれる ARN のリージョン部分を見るのが近道です。別のリージョンに作った関数を探していた、という場合はここで気づけます。リージョンはコマンドごとに --region ap-northeast-1 で指定できます。
よくある質問
Q. update-function-code と update-function-configuration はどう使い分けますか?
A. コード(zip の中身)を変えるのが update-function-code、タイムアウト・メモリ・環境変数・レイヤー・ランタイムなどの設定を変えるのが update-function-configuration です。両方を続けて実行するときは、間に aws lambda wait function-updated-v2 を挟みます。
Q. 環境変数を1つだけ変えたいのに、ほかの変数が消えました。
A. --environment は Variables 全体を置き換えます。get-function-configuration で今の変数を取り出し、変えたい変数を合わせた全体を渡してください。この記事の「既存の変数を残して1つ追加する手順」がそのまま使えます。
Q. レイヤーを公開し直したのに、関数の動きが変わりません。
A. 関数は番号つきの LayerVersionArn を指定して持っています。新しい番号を公開したあと、update-function-configuration の --layers で新しい ARN を渡すと切り替わります。
Q. $LATEST とバージョン番号、エイリアスは何が違いますか?
A. $LATEST は更新のたびに中身が変わる作業用の最新版、番号つきのバージョンは発行した時点の内容を固定したもの、エイリアスはバージョンに付ける名前です。呼び出す側にはエイリアスを指定しておくと、切り替えと戻しを update-alias の1コマンドで行えます。
まとめ
- 流れは「ロール作成 → zip → create-function → update-function-code / update-function-configuration」。コードと設定は別のコマンドで更新する
- zip は
fileb://で渡す。JSON などのテキストはfile:// --environmentと--layersは全体置き換え。追加するときは、今の内容を取り出して合わせた全体を渡す- 作成・更新の直後は wait を挟む(function-active-v2 / function-updated-v2)と、続くコマンドを安心して実行できる
- レイヤーは番号つきの ARN で付ける。公開し直したら関数側の指定も更新する
- publish-version で内容を固定し、エイリアスで切り替える。戻すときも update-alias で向き先を変えるだけ
- 「Function not found」はメッセージ中の ARN のリージョンを確かめる
参考・出典
- AWS Lambda デベロッパーガイド「Lambda 実行ロール」 https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html
- AWS Lambda デベロッパーガイド「Lambda 環境変数」 https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html
- AWS Lambda デベロッパーガイド「Lambda 関数の状態」 https://docs.aws.amazon.com/lambda/latest/dg/functions-states.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS CLIでLambdaを作成・更新 環境変数とレイヤー」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。