2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Lambda 関数のランタイムを一気に更新する

Last updated at Posted at 2024-04-26

こんにちは
沢山の AWS Lambda 関数のランタイムを更新する必要が出てきたので、今回はその内容についてお伝えします。

大前提
基本的にマイナーバージョンアップであれば後方互換性があるので、問題は出にくいかもしれません。
しかし、問題が出て困るような環境(例:本番環境、利用者が多いなど)では、本仕組みを使わずに、動作確認してから個別に更新することをお勧めします。

ことの発端

わたしが管理している AWS ルートユーザーのメールアドレスに、以下のようなメールが届きました。

image.png

2024 年 10 月 14 日で Python3.8 のサポートが終了になるので、それまでに更新対応してくださいね!というものです。

このアカウントは、 Python3.8 時代にたくさんの AWS Lambda 関数を開発し運用しているのでポチポチやるのも一苦労です。

image.png
※Python3.8 な Lambda 関数の一部

定期的にこういった更新対応が必要になるのはわかっているので、極力省力化できるようにAWS Lambda と AWS StepFunctions を用いて実装しました。

AWS Lambda の実装

IAM Role に必要なアクション許可

最低限、以下のアクションを許可すればよいです。
サンプルコードから改造する場合は、それに見合ったアクション許可を付与してください。

  • lambda:ListFunctions
  • lambda:UpdateFunctionConfiguration
  • logs:CreateLogGroup
  • logs:CreateLogStream
  • logs:PutLogEvents

サンプルコード

後述の AWS StepFunctions から入力パラメータを送信してもらうので、event コンテキストの current キーと target キーを受けられるようにしています。
また、AWS StepFunctions に向けて、どの AWS Lambda 関数を更新したのかといった情報やエラー時のトレースを送れるようにもしてあります。

エラーハンドリングは最低限なので、必要に応じて適宜追加してください。

lambdaRuntimeUpdate.py
import traceback
import logging
import boto3

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    if event:
        if 'current' in event:
            current=event['current'].lower()
        else:
            return {"Message": "current が存在しないか、現在のランタイムが指定されていません"}
        if 'target' in event:
            target=event['target'].lower()
        else:
            return {"Message": "target が存在しないか、新しいランタイムが指定されていません"}
    else:
        return {"Message": "StepFunctionsから次のように入力してください。{\"current\": <現在のランタイム>, \"target\": <新しいランタイム>}"}
    
    targetFunctions=[]
    
    client=boto3.client('lambda')
    paginator = client.get_paginator('list_functions')

    for lambdafunctions in paginator.paginate():
        for lambdafunction in lambdafunctions['Functions']:
            if current == lambdafunction['Runtime']:
                try:
                    targetFunctions.append(lambdafunction['FunctionName'])
                    client.update_function_configuration(
                        FunctionName=lambdafunction['FunctionName'],
                        Runtime=target
                    )
                except:
                    logger.error(traceback.format_exc())
                    return {"Message": traceback.format_exc()}
    return {
        "CurrentRuntime": current,
        "TargetRuntime": target,
        "TargetFunctions": targetFunctions
    }

AWS StepFunctions のステートマシンの実装

今回は手動実行なので至極簡単に Lambda:Invoke 1つのみです。

image.png

なぜ、わざわざ AWS StepFunctions 用いるのかの答えは、パラメータを入れやすくするのと今後、AWS Health からの通知を契機に自動化したいとなったときにも対応しやすくするためです。

ステートマシンのサンプルコード

LambdaRuntimeUpdateStateMachine.json
{
  "Comment": "A description of my state machine",
  "StartAt": "LambdaRuntimeUpdate",
  "States": {
    "LambdaRuntimeUpdate": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "OutputPath": "$.Payload",
      "Parameters": {
        "Payload.$": "$",
        "FunctionName": "arn:aws:lambda:ap-northeast-1:<AWS AccountId>:function:lambdaRuntimeUpdate:$LATEST"
      },
      "Retry": [
        {
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException",
            "Lambda.TooManyRequestsException"
          ],
          "IntervalSeconds": 1,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ],
      "End": true
    }
  }
}

IAM Role について、このステートマシンを初回保存する際に自動的に作成されるもので問題ありません。

動かしてみよう

AWS Lambda 関数と AWS StepFunctions のステートマシンが作成できたら、ステートマシンから実際に更新します。
image.png
画像の様にjson形式のパラメータを入力値として設定します。

入力例
{
    "current": "現在のランタイム",
    "target": "更新先のランタイム"
}

実行し、特に問題がなければ、以下の様にステートマシンの実行の入力と出力に表示されます。
image.png

AWS Lambda の関数の画面でも以下の通り更新されていることが確認できました。
image.png

まとめ

退屈なことは Python にやらせよう というタイトルの書籍をご存知でしょうか?
自作 RPA 本の草分け的存在として大ヒットしました。
冒頭お伝えした通り、ランタイムを変えてしまうことで影響が出て困るような場合は、本記事でお伝えした内容は使いづらいのです。
しかし、全部が全部そういった関数ではないかもしれません。Lambda 関数にはタグを付与することができます。そのタグが付いている場合は処理をスキップし、対象外にした旨を出力してあげて、それ以外は更新してしまう。そうすることで作業工数の低減につながるのではと考えます。
よき、Cloud Operation Life を~

ーーー
記載されている会社名、製品名、サービス名、ロゴ等は各社の商標または登録商標です。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?