LambdaのCodeArtifactUserPendingExceptionのメモ

# 背景・目的

先日、Step Functionsから起動しているLambdaでCodeArtifactUserPendingExceptionが発生したので忘れないようにメモします。

今回、利用していたLambdaは、コンテナイメージを使用していましたが、それが関係しているようです。

# まとめ

- Lambdaでは下記のステータスがある
    - Pending
    - Active
    - Failed
    - Inactive
- コンテナイメージなど使用しているLambdaの場合、数週間起動しないと、Inactiveになる
- Inactive状態の場合、初回の呼び出しではエラーになる（CodeArtifactUserPendingExceptionが発生）
- 定期的にステータスを確認し、Inactiveの場合は、invokeを実行するのが良さそう

# 概要

## Function lifecycle

下記の記事を基に整理します。

https://docs.aws.amazon.com/lambda/latest/dg/images-create.html

> After you upload a new or updated container image, Lambda optimizes the image before the function can process invocations. The optimization process can take a few seconds. The function remains in the Pending state until the process completes, when the state transitions to Active. You can't invoke the function until it reaches the Active state.

- 新規 or 更新されたコンテナイメージをアップロードすると、Lambdaは処理可能なように、事前にイメージを最適化する
- 最適化プロセスには数秒かかることがある
- 関数は、プロセスが完了して状態がアクティブに遷移するまでに保留状態になる
- 関数がアクティブになるまで呼び出せない

> If a function is not invoked for multiple weeks, Lambda reclaims its optimized version, and the function transitions to the Inactive state. To reactivate the function, you must invoke it. Lambda rejects the first invocation and the function enters the Pending state until Lambda re-optimizes the image. The function then returns to the Active state.

- 関数が数週間呼び出されない場合、関数は最適化されたバージョンを再利用し、Inactive状態に移行する
- 再アクティブにするには、関数を呼び出す必要がある
    - Lambdaは最初の呼び出しをRejectし、再度最適化するまではPendingになる
    - その後、アクティブ状態に戻る

> Lambda periodically fetches the associated container image from the Amazon ECR repository. If the corresponding container image no longer exists on Amazon ECR or permissions are revoked, the function enters the Failed state, and Lambda returns a failure for any function invocations.

- Lambdaは、ECから関連するコンテナイメージを定期的に取得する
- 対応するコンテナイメージがECRにない場合、またはアクセス許可が取り消された場合に、FailedになりLambdaは失敗を繰り返す

> You can use the Lambda API to get information about a function's state. For more information, see Lambda function states.

## Lambda function states
下記の記事を基に整理します。

https://docs.aws.amazon.com/lambda/latest/dg/functions-states.html

> Lambda includes a State field in the function configuration for all functions to indicate when your function is ready to invoke. State provides information about the current status of the function, including whether you can successfully invoke the function. Function states do not change the behavior of function invocations or how your function runs the code.


Lambdaは、すべての関数の関数設定にStateフィールドが含まれている


> Function states include:

> - Pending – After Lambda creates the function, it sets the state to pending. While in pending state, Lambda attempts to create or configure resources for the function, such as VPC or EFS resources. Lambda does not invoke a function during pending state. Any invocations or other API actions that operate on the function will fail.

- Lambdaが関数を作成したあと、Pendingになる
- Pendingの間、LambdaはVPCやEFSなど関数のリソースを作成または設定しようとする。Lambdaは保留状態の間は関数を呼び出さない
- 関数を操作する呼び出しやその他の API アクションはすべて失敗する

> - Active – Your function transitions to active state after Lambda completes resource configuration and provisioning. Functions can only be successfully invoked while active.

- Lambda がリソースの設定とプロビジョニングを完了すると、関数はアクティブ状態に移行する
- 関数はアクティブな間のみ正常に呼び出すことができる

> - Failed – Indicates that resource configuration or provisioning encountered an error.

- リソース構成またはプロビジョニングでエラーが発生したことを示す

> - Inactive – A function becomes inactive when it has been idle long enough for Lambda to reclaim the external resources that were configured for it. When you try to invoke a function that is inactive, the invocation fails and Lambda sets the function to pending state until the function resources are recreated. If Lambda fails to recreate the resources, the function returns to the inactive state. If your function is stuck in the inactive state, refer to the function's StatusCode and StatusCodeReason attributes for further troubleshooting. You may need to resolve any errors and redeploy your function to restore it to the active state.

- 関数は、Lambda がその関数用に設定された外部リソースを再利用できるほど十分に長い時間アイドル状態になると、非アクティブになる
- Inactiveな関数を呼び出そうとすると、呼び出しは失敗し、リソースが再作成されるまで、Lambdaは関数をPendingにする
- Lambda がリソースの再作成に失敗した場合、関数はInactiveに戻る
- 関数が非アクティブ状態のままになっている場合は、関数の StatusCode 属性と StatusCodeReason 属性を参照して、さらにトラブルシューティングを行う
- エラーを解決し、関数を再デプロイしてアクティブな状態に戻す必要がある

## Step functions not able to handle lambda in unready state

AWS repostにも下記の記載がありました。

https://repost.aws/questions/QU3tC5KVQAR32y_ia1kOEsLA/step-functions-not-able-to-handle-lambda-in-unready-state

> If a lambda version is deployed or, a lambda is unused for a longer period of time (e.g. a week) then in either case the lambda will initially not be in a state whereby it can be immediately invoked.

- Lambda バージョンがデプロイされている場合、または Lambda が長期間 (例: 1 週間) 使用されていない場合に、Lambdaはすぐに呼び出せない

> Using a step function flow that invokes a lambda when the lambda is in this state is not gracefully handled. Even with error state handling in place to allow for retry / back-off retry the stepfunction flow will immeidately fail with an error similar to:

- Lambdaがこの状態のときに、Step Funcitonsでフローを実行すると適切に処理されない 

- どうやら、リトライ＆バックオフを入れてもエラーがハンドリングが適切にできないようなことが書かれている

```json
{
  "Cause": "ERROR: Lambda is initializing your function. It will be ready to invoke shortly. (Service: Lambda, Status Code: 409, Request ID: 0000-0000-0000-000-00000000)",
  "Error": "Lambda.AWSLambdaException"
}
```

## 対処方法
下記を基に整理します。

https://docs.aws.amazon.com/lambda/latest/dg/functions-states.html

> If you are using SDK-based automation workflows or calling Lambda’s service APIs directly, ensure that you check a function's state before invocation to verify that it is active. You can do this with the Lambda API action GetFunction, or by configuring a waiter using the AWS SDK for Java 2.0.

- 関数がアクティブなことを確認する

    ```bash
    aws lambda get-function --function-name my-function --query 'Configuration.[State, LastUpdateStatus]'
    ```

- 上記の結果が、Active、Successful **ではない場合** に一度、Invokeを呼んでおくのがよさそうです


# 考察
今回、少しハマったLambdaのエラー（CodeArtifactUserPendingException）について、考えられる原因を整理してみました。
今後、再現テストができたら本資料を更新しようと思います。


# 参考

https://techtekt.persol-career.co.jp/entry/tech/220602_01

https://repost.aws/questions/QU3tC5KVQAR32y_ia1kOEsLA/step-functions-not-able-to-handle-lambda-in-unready-state

https://medium.com/@lamwm00/lambda-is-not-always-ready-when-you-need-it-454f3a59eee2

https://docs.aws.amazon.com/lambda/latest/dg/functions-states.html

https://docs.aws.amazon.com/lambda/latest/api/API_FunctionConfiguration.html#lambda-Type-FunctionConfiguration-State