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 10:Lambda Layer の ARN 更新を CI/CD で自動化する(SAM へ安全に注入)

Posted at

こちらの記事は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_workspacelayer_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
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?