0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Day 9:複数 Layer の統合設計(3分類で迷わない)

Posted at

こちらの記事はAWS Lambda 実践入門 Advent Calendar 2025 9日目の記事になります。

はじめに

Layer が増えるほど「どの Layer が何を提供しているか」が分からなくなる問題が必ず発生します。

  • 似た Layer が乱立する(logging / utils / common など)
  • どの関数がどの Layer バージョンを使っているか追えない
  • 破壊的変更で“関係ない Lambda”まで巻き込んで壊れる

この記事では、Layer を 3分類 することで設計を整理し、運用コストを下げる方法を紹介します。

まず押さえる:Layer の制約(設計に直結)

Layer は便利ですが、制約を知らずに増やすと詰みます。

なので「とりあえず分ける」は危険で、**分け方(設計)**が重要になります。

Layer の3分類

1. ライブラリ Layer(Third-party 専用)

サードパーティライブラリだけを入れる Layer です。
目的は「依存の再利用」と「関数デプロイの軽量化」。

例:

  • Pillow
  • PyPDF / pypdf
  • cryptography など

2. ユーティリティ Layer(共通処理・社内標準の薄いライブラリ)

自分たちが保守する共通処理をまとめる Layer です。
“関数横断の共通化”の本命ですが、破壊的変更の影響範囲が大きいので設計が重要。

例(Python の場合は /opt/python 配下に載る構造を意識):

python/
  utils/
    s3_utils.py
    pdf_utils.py

ポイント:

  • 「小さく・薄く」保つ(巨大な共通基盤にしない)
  • インターフェースを固定し、内部実装を入れ替えやすくする

3. ランタイム / フレームワーク Layer(特殊ケース)

特殊な事情がある場合にだけ使う分類です。

例:

  • 社内共通ランタイム(カスタムランタイム)
  • 監視・計測の共通仕組み(拡張、ラッパー)
  • 共通のネイティブ依存(フォント、バイナリなど)

この Layer は更新頻度を低くし、長期安定版として扱うのが基本です。

なぜ「3分類」が効くのか(設計判断が速くなる)

Layer の事故は多くが「責務が混ざる」ことで起きます。

  • ライブラリ Layerに社内 util が混ざる
  • util Layer に特定アプリ固有のロジックが混ざる
  • runtime Layer が“全部入り”になって更新不能になる

3分類にすると「それはどこに入れるべきか?」の判断が一瞬でできます。
結果として、依存関係・更新頻度・テスト方針を 分類ごとに標準化できます。

Layer バージョン戦略(SemVer を前提にすると事故が減る)

種類 更新頻度 推奨戦略 注意点
ライブラリ Layer patch/minor 更新を定期化 CVE / 互換性差分
ユーティリティ Layer 破壊的変更は major 影響範囲が広い
ランタイム Layer 長期安定版(LTS) 変更は最小・計画的に

補足(実務で効く運用ルール):

  • 破壊的変更は“新しい Layer 名”で作るのも有効(例:utils-layer-v2
    → 既存関数を段階移行でき、緊急ロールバックも容易
  • Library Layer は「入れ替え」になりがちなので、依存はできるだけ固定(ピン留め) して更新を計画化する

図解:Layer 依存モデル(推奨)

「薄い util を真ん中に置き、外側を差し替える」形が安定します。

アンチパターン(やりがち)

  • common-layer 1枚に全部入れる
    → 更新できない、影響範囲が読めない、5枚制限も圧迫
  • 用途不明な名前shared, common, misc
    → “分類”が崩れて探索コストが増える
  • util に業務ロジックを入れる
    → util の変更が即「全関数の仕様変更」になる

まとめ

  • Layer は増えるほど“整理しないと”破綻する
  • Library / Utility / Runtime の 3分類で設計判断が速くなる
  • 制約(最大 5 Layer、合計サイズ上限)を前提に組む (AWS ドキュメント)
  • 次回は Layer 自動更新の CI/CD 連携(更新検知・影響確認・段階適用)を解説

付録:Layer 命名規則テンプレ(迷ったらこれ)

Layer 名は「あとから検索して意味が分かる」ことが最優先です。
おすすめは 責務・対象ランタイム・互換性(メジャー) まで名前で表現するルールです。

推奨フォーマット

  • Library Layer

    • lib-<package>-py<major><minor>-<arch>
    • 例:lib-pillow-py312-x86_64 / lib-pypdf-py312-arm64
  • Utility Layer

    • util-<domain>-v<major>
    • 例:util-core-v1 / util-pdf-v2 / util-s3-v1
  • Runtime / Framework Layer

    • rt-<name>-v<major>-py<major><minor>-<arch>(必要な情報を乗せる)
    • 例:rt-observability-v1-py312-x86_64

命名に入れるべき要素(判断基準)

要素 いつ必要?
種別プレフィックス lib- / util- / rt- 常に
対象ランタイム py312 ライブラリ/ランタイムで特に重要
アーキテクチャ arm64 / x86_64 どちらか混在するなら必須
メジャーバージョン v2 Utility/Runtime は基本必須
ドメイン pdf / s3 / core Utility は必須(責務が見える)

アンチパターン(避けたい命名)

  • common / shared / misc のような「用途不明」名称
  • 役割が混ざる名称(lib-utils など)
  • v がない Utility(破壊的変更の逃げ道がない)

付録:Layer ごとの README 必須項目(テンプレ)

Layer は「使う側のためのプロダクト」なので、Layer 直下に README を置いて情報を固定化します。
最低限、下記を埋めれば運用が回ります。

README.md テンプレ(コピペ用)

# <LayerName>

## 1. 概要(What)
- 種別: Library / Utility / Runtime
- 目的: (何を提供する Layer か)
- 対象ランタイム: python3.12 など
- 対象アーキ: x86_64 / arm64
- 提供物の場所: /opt/python/...(例)

## 2. 提供 API(Interface)
- Public API 一覧(関数・モジュール)
  - python/utils/s3_utils.py
    - s3_utils.upload_file(...)
    - s3_utils.download_file(...)
- 破壊的変更の定義(例:引数変更、戻り値変更、例外型変更)

## 3. 互換性(Compatibility)
- 対応 Lambda Runtime: python3.12
- 互換性ポリシー: SemVer(MAJOR.MINOR.PATCH)
  - MAJOR: 破壊的変更
  - MINOR: 後方互換の機能追加
  - PATCH: バグ修正のみ
- 依存ライブラリ(Library Layer の場合は requirements の方針)
  - ピン留め有無 / 例外ルール(セキュリティ修正など)

## 4. 変更履歴(Changelog)
- v2.1.0: ...
- v2.0.0: 破壊的変更(内容 / 移行ガイドへのリンク)
- v1.9.3: ...

## 5. 更新手順(How to Release)
- ローカルでの build 方法
- テスト方法(最小テスト・互換性テスト)
- リリース手順(タグ付け/発行/ARN 更新)
- ロールバック手順(前バージョンへ戻す方法)

## 6. 利用例(How to Use)
- SAM template での Layers 指定例
- import 例(例:from utils import s3_utils)
- 典型ユースケース(1〜3個)

## 7. 利用 Lambda 一覧(Consumer)
- どの関数が使っているか(可能なら自動生成)
  - pdf-annotator
  - receipt-pdf-to-jpeg

運用のコツ:Utility / Runtime は「Consumer(利用側)一覧」を README に持つと、影響調査が一瞬で終わります。
手書きでも良いですが、CI で template.yaml を走査して自動更新できると理想です(次回の Day10 に繋がります)。

次回予告(Day10 への接続:Layer 自動更新の CI/CD)

ここまでで「Layer を分類して、命名して、README で契約(Interface)を固定する」準備ができました。
次回(Day10)では、これを前提に以下を CI/CD で自動化します。

  • Layer の最新バージョン検知(新リリースの検出)
  • Consumer(利用 Lambda)への影響範囲の自動算出
  • 段階的な適用(STAGING → PROD)
  • 破壊的変更(MAJOR)を検知して止める仕組み(ガードレール)

「Layer を増やしても壊れない運用」に進みましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?