こちらの記事はAWS Lambda 実践入門 Advent Calendar 2025 10日目の記事になります。
“最新追従” の注意点(本番はそのまま最新にしない)
CI/CD が自動で最新 Layer ARN を取れるのは便利ですが、本番環境で「常に最新」をそのまま使う設計は危険です。
- Layer の更新が破壊的変更だった場合、アプリ側の変更なしで本番が壊れる
- “誰がいつ上げた Layer を使ったか” が曖昧になり、障害調査が難しくなる
そのため現場では、次のように使い分けることが多いです。
- dev/staging:最新追従(動作確認の速度優先)
- prod:固定(ピン留め)(承認済みバージョンのみ適用)
この「環境で戦略を変える」方針は、Day11 の OIDC を使った安全なデプロイ と相性が良いです。
AWS CLI:取得を堅牢にする(リージョン・空配列対策)
list-layer-versions はリージョン依存なので、CI では明示しておくと事故が減ります。
LAYER_NAME="aws-s3-utils-layer"
REGION="ap-northeast-1"
LAYER_ARN=$(aws lambda list-layer-versions \
--layer-name "${LAYER_NAME}" \
--region "${REGION}" \
--query 'LayerVersions[0].LayerVersionArn' \
--output text)
if [ -z "${LAYER_ARN}" ] || [ "${LAYER_ARN}" = "None" ]; then
echo "ERROR: Layer ARN not found. name=${LAYER_NAME} region=${REGION}"
exit 1
fi
echo "Latest Layer ARN: ${LAYER_ARN}"
CircleCI 実装例(BASH_ENV への注入を“ジョブ間”でも使える形に)
同一ジョブ内だけなら $BASH_ENV で十分ですが、ジョブを分ける場合は workspace / artifacts で受け渡しするのが定石です。
方式A:同一ジョブで完結(シンプル)
echo "export AwsS3UtilsLayerArn=${LAYER_ARN}" >> "$BASH_ENV"
source "$BASH_ENV"
方式B:ARN をファイル化して引き回す(現場で強い)
echo -n "${LAYER_ARN}" > layer_arn.txt
SAM 側:Parameter と template.yaml の形を明確にする
Parameters:
AwsS3UtilsLayerArn:
Type: String
Description: ARN of aws-s3-utils-layer (with version)
Resources:
PdfFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.12
CodeUri: src/
Handler: app.lambda_handler
Layers:
- !Ref AwsS3UtilsLayerArn
そしてデプロイ時に注入:
sam deploy \
--parameter-overrides AwsS3UtilsLayerArn="${LAYER_ARN}"
実務TIP:本番は “最新” ではなく “承認済み” を使う
本番の事故を避ける典型パターンは次のどちらかです。
- prod は固定の LayerVersionArn をリポジトリにコミット(変更が差分としてレビュー可能)
- 承認済み ARN を SSM Parameter Store 等に置き、CI がそこを参照(承認フローを作れる)
「CI が勝手に最新を選ぶ」のではなく、“選ばれたものを安全に注入する” に寄せると運用品質が上がります。
図解:Layer 自動更新フロー(dev/staging と prod を分ける)
まとめ
- Layer 更新は CI/CD に統合すべき(手動は事故要因)
- ただし本番は “常に最新” ではなく、承認済みバージョン運用が基本
- 次回(Day11)は OIDC により長期キーなしで安全に AWS へデプロイし、CI/CD のセキュリティを完成させる
付録:workspace で Layer ARN を受け渡す CircleCI 完全版サンプル
ポイント
-
resolve_layerジョブで 最新 LayerVersionArn を取得してファイル化 -
persist_to_workspaceでlayer_arn.txtを workspace に載せる -
deployジョブでattach_workspaceして 同じ ARN を参照 - “同一ジョブ内の
$BASH_ENV” ではなく、ジョブ間の受け渡しができる
.circleci/config.yml(サンプル)
version: 2.1
workflows:
version: 2
build_test_deploy:
jobs:
- test
- resolve_layer:
requires:
- test
- deploy:
requires:
- resolve_layer
jobs:
test:
docker:
- image: public.ecr.aws/lambda/python:3.12
steps:
- checkout
- run:
name: Install tools (example)
command: |
python -m pip install --upgrade pip
pip install -r src/requirements.txt
- run:
name: Run tests (example)
command: |
# pytest 等に置き換えてください
python -c "print('ok')"
resolve_layer:
docker:
- image: public.ecr.aws/lambda/python:3.12
environment:
LAYER_NAME: aws-s3-utils-layer
AWS_REGION: ap-northeast-1
steps:
- checkout
- run:
name: Install AWS CLI (if needed)
command: |
python -m pip install --upgrade pip
pip install awscli
- run:
name: Resolve latest Layer ARN and persist to workspace
command: |
set -euo pipefail
echo "Resolving latest Layer ARN..."
LAYER_ARN=$(aws lambda list-layer-versions \
--layer-name "${LAYER_NAME}" \
--region "${AWS_REGION}" \
--query 'LayerVersions[0].LayerVersionArn' \
--output text)
if [ -z "${LAYER_ARN}" ] || [ "${LAYER_ARN}" = "None" ]; then
echo "ERROR: Layer ARN not found. name=${LAYER_NAME} region=${AWS_REGION}"
exit 1
fi
mkdir -p workspace
echo -n "${LAYER_ARN}" > workspace/layer_arn.txt
echo "Latest Layer ARN: ${LAYER_ARN}"
echo "Saved to workspace/layer_arn.txt"
- persist_to_workspace:
root: workspace
paths:
- layer_arn.txt
deploy:
# Day11 で OIDC にするなら、ここを aws-cli + OIDC 前提の executor に寄せる想定
docker:
- image: public.ecr.aws/lambda/python:3.12
environment:
AWS_REGION: ap-northeast-1
steps:
- checkout
- attach_workspace:
at: /tmp/workspace
- run:
name: Install tools (AWS CLI / SAM)
command: |
python -m pip install --upgrade pip
pip install awscli aws-sam-cli
- run:
name: Read Layer ARN from workspace
command: |
set -euo pipefail
LAYER_ARN="$(cat /tmp/workspace/layer_arn.txt)"
if [ -z "${LAYER_ARN}" ]; then
echo "ERROR: /tmp/workspace/layer_arn.txt is empty"
exit 1
fi
echo "Using Layer ARN: ${LAYER_ARN}"
echo "export AwsS3UtilsLayerArn=${LAYER_ARN}" >> "${BASH_ENV}"
- run:
name: sam build
command: |
sam build
- run:
name: sam deploy with Layer ARN injection
command: |
source "${BASH_ENV}"
sam deploy \
--region "${AWS_REGION}" \
--capabilities CAPABILITY_IAM \
--no-confirm-changeset \
--no-fail-on-empty-changeset \
--parameter-overrides AwsS3UtilsLayerArn="${AwsS3UtilsLayerArn}"
付録:運用でよく効く小ネタ(短く追記するならここ)
-
ログに残す:
echo "Using Layer ARN: ${LAYER_ARN}"は障害調査の一次情報になります -
prod は固定運用にする場合:
resolve_layerを “最新取得” ではなく “承認済み ARN を読む” に差し替えるだけで運用が安定します(例:SSM Parameter Store / リポジトリ内のapproved_layer_arn.txt)