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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?