エンジニア

2022.08.16

お盆明けたら pipenv + serverless-python-requirements のデプロイが失敗するようになった

お盆明けたら pipenv + serverless-python-requirements のデプロイが失敗するようになった

2023年7月追記

pipenv の最新版(v2023.7.9)にて、「–keep-outdated」が廃止されたため、本現象が再発生するようになった模様です。この場合、1つ前のバージョンを指定すればとりあえず回避できます。

pip install pipenv==2023.7.4

serverless-python-requirements 側のアップデートが待たれます。

以下は執筆当時の内容です。


2023年2月追記

ブログへの反映が遅くなってしまいましたが、serverless-python-requirements 6.0.0以降 では本現象は修正されています。

https://github.com/serverless/serverless-python-requirements/issues/716

もし現時点でもこの現象に悩まされている方がいた場合は、serverless-python-requirementsをアップデートしてみてください!

以下は執筆当時の内容です。


こんにちは、ハンズラボ シニアテックリードのfjwrです。

2022年のお盆休み明け、ServerlessFrameworkとGitHubActionsで構築していたPythonバックエンドのCI/CDが急に動かなくなってしまう問題が発生しました。調査の結果、原因を特定できましたので情報を共有させていただきます。

発生した現象

GitHubActions中で sls deploy コマンドの実行時、以下のエラーが発生しデプロイに失敗します。

  • node.js 16.14.0
  • serverless 3.21.0
  • serverless-python-requirements 5.4.0
$ sls deploy
Running "serverless" from node_modules

Deploying sls-example to stage dev (ap-northeast-1)

✖ Stack sls-example-dev failed to deploy (1s)
Environment: darwin, node 16.14.0, framework 3.21.0 (local) 3.7.2v (global), plugin 6.2.2, SDK 4.3.2
Credentials: Local, environment variables
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
Error: `pipenv lock --requirements --keep-outdated` Exited with code 2
    at ChildProcess.<anonymous> (/Users/fjwr/LocalProjects/sls_example/node_modules/child-process-ext/spawn.js:38:8)
    at ChildProcess.emit (node:events:520:28)
    at ChildProcess.emit (node:domain:475:12)
    at maybeClose (node:internal/child_process:1092:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5)

しかし、コードの修正は行なっておらず、ローカルでは普通にデプロイに成功します。謎です。

原因

pipenvの直近のアップデートにより廃止された pipenv lock のパラメータ(-r, –requirements)を、serverless-python-requirementsがデプロイ中で使用しているためでした。

以下の条件が重なっているときに発生します。

  • Pythonパッケージ管理に最新Ver(2022.8.15)のpipenvを使用している
  • serverless-python-requirementsを使用しており、custom.pythonRequirements.usePipenv に true が設定されている

エラーとなるserverless.ymlの例

service: sls-example
frameworkVersion: '>=3.0.0 <4.0.0'

plugins:
  - serverless-python-requirements

custom:
  defaultStage: dev
  pythonRequirements:
    usePipenv: true

package:
  patterns:
    - '!node_modules/**'
    - '!Pipfile'
    - '!Pipfile.lock'
    - '!package.json'

provider:
  name: aws
  runtime: python3.9
  stage: ${opt:stage, self:custom.defaultStage}
  region: ap-northeast-1
  environment:
    TZ: Asia/Tokyo
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - s3:Get*
            - s3:List*
          Resource:
            - '*'

functions:
  listBuckets:
    handler: list_buckets.handler

暫定対応

この現象はv2022.8.13以降のpipenvを使用した場合に発生します。前述のGitHubActions定義のファイルの中では、pipenvのバージョンを指定せず常に最新Verをインストール用設定していましたが、以下のように修正しました。

pip install pipenv==2022.8.5

CI/CDでデプロイを実行するとエラーになるが、ローカルでは正常に実行できる場合などは、おそらくローカルで利用しているpipenvのバージョンが古いためと思われます。

pipenv、またはserverless-python-requirementsが対応を行なっていただければ、この対応は不要になる想定です。すでにissueも立っています。

最後に

リリースを控えているにもかかわらず、お盆休み明けたら急にCI/CDが動作しなくなっていた時は本当に肝が冷えました。アプリを構成するパッケージは全てバージョン管理を行なっていたのですが、パッケージ管理ライブラリであるpipenvそのもののバージョン管理は行なっていなかったのが盲点でした。

日本の企業は休みでも、海外の開発コミュニティは活発に動いているあたり、面白みを感じなくもなかった一時でした。

一覧に戻る