継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

SSM Automation で使う Lambda の処理が突如失敗した事象の対処

タダです.

以前の記事で NAT Gateway の自動作成と削除を SSM Automation で自動化したのですが,2021/10/22 に突如失敗したので,調べて対処した結果をまとめていきます.

sadayoshi-tada.hatenablog.com

事象の詳細

AWS-UpdateCloudFormationStack を CloudWatch Events で定期実行していたところ,CloudFormation で下記の引用文が表示されるようになりました.python2.7は新規作成の Lambda でサポートされなくなって python3.9が推奨というメッセージです.

Resource handler returned message: "The runtime parameter of python2.7 is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (python3.9) while creating or updating functions.

AWS-UpdateCloudFormationStack の3つのステップのうち createDocumentStack が失敗していたので,詳細を見てみるとこのステップで使っている CloudFormation テンプレートで Runtime: python2.7が指定されたため今回のエラーが発生したということがわかりました.

CloudFormation テンプレート詳細

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  LambdaName: {Description: 'The lambda function name', Type: String}
  LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda
      created by Automation to perform the action on your behalf', Type: String}
Resources:
  UpdateCFLambda:
    Properties:
      Code: {ZipFile: \"import boto3\
\
\
def handler(event, context):\
\\tcf = boto3.client(\\\"\\
          cloudformation\\\")\
\
\\tcf.update_stack(\
\\t\\tStackName=event[\\\"StackName\\\"\\
          ],\
\\t\\tTemplateURL=event[\\\"TemplateUrl\\\"],\
\\t\\tCapabilities=[\\\"CAPABILITY_IAM\\\"\\
          ]\
\\t)\
\"}
      FunctionName: {Ref: LambdaName}
      Handler: index.handler
      MemorySize: 128
      Role: {Ref: LambdaRoleArn}
      Runtime: python2.7
      Timeout: 60
    Type: AWS::Lambda::Function

事象への対応

公式の Automation ドキュメントを使っていたもののサポート外の python 2.7 なので,個別の Automation ドキュメントを作って Python のバージョンを python3.9 に変更しました.Lambda のコードも Python 2系から3系にしても問題ない内容だと思ったので,バージョンの変更だけしてその他の内容は公式の Automation の内容をコピペしています.この設定をし直して再度定期実行を流したところ,問題なく動作するようになりました.

個別の Automation ドキュメント詳細

{
  "schemaVersion": "0.3",
  "assumeRole": "{{AutomationAssumeRole}}",
  "description": "Update Cloud Formation Stack using cloud formation template from a S3 bucket.",
  "parameters": {
    "StackNameOrId": {
      "type": "String",
      "description": "(Required) Name or Unique ID of the CloudFormation stack to be updated"
    },
    "TemplateUrl": {
      "type": "String",
      "description": "(Required) S3 bucket location of updated CloudFormation Template (e.g. https://s3.amazonaws.com/example/updated.template)"
    },
    "LambdaAssumeRole": {
      "type": "String",
      "description": "(Required) The ARN of the role assumed by lambda"
    },
    "AutomationAssumeRole": {
      "default": "",
      "type": "String",
      "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. "
    }
  },
  "mainSteps": [
    {
      "action": "aws:createStack",
      "inputs": {
        "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}",
        "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\nParameters:\n  LambdaName: {Description: 'The lambda function name\n\n      ', Type: String}\n  LambdaRoleArn: {Default: '', Description: 'The ARN of the role that allows Lambda\n      created by Automation to perform the action on your behalf\n\n      ', Type: String}\nResources:\n  UpdateCFLambda:\n    Properties:\n      Code: {ZipFile: \"import boto3\\n\\n\\ndef handler(event, context):\\n\\tcf = boto3.client(\\\"\\\n          cloudformation\\\")\\n\\n\\tcf.update_stack(\\n\\t\\tStackName=event[\\\"StackName\\\"\\\n          ],\\n\\t\\tTemplateURL=event[\\\"TemplateUrl\\\"],\\n\\t\\tCapabilities=[\\\"CAPABILITY_IAM\\\"\\\n          ]\\n\\t)\\n\"}\n      FunctionName: {Ref: LambdaName}\n      Handler: index.handler\n      MemorySize: 128\n      Role: {Ref: LambdaRoleArn}\n      Runtime: python3.9\n      Timeout: 60\n    Type: AWS::Lambda::Function\n",
        "Parameters": [
          {
            "ParameterValue": "{{LambdaAssumeRole}}",
            "ParameterKey": "LambdaRoleArn"
          },
          {
            "ParameterValue": "UpdateCFTemplate-{{automation:EXECUTION_ID}}",
            "ParameterKey": "LambdaName"
          }
        ],
        "Capabilities": [
          "CAPABILITY_IAM"
        ]
      },
      "name": "createDocumentStack"
    },
    {
      "action": "aws:invokeLambdaFunction",
      "inputs": {
        "FunctionName": "UpdateCFTemplate-{{automation:EXECUTION_ID}}",
        "Payload": "{\"StackName\": \"{{StackNameOrId}}\", \"TemplateUrl\": \"{{TemplateUrl}}\"}"
      },
      "name": "updateCloudFormationTemplate"
    },
    {
      "action": "aws:deleteStack",
      "inputs": {
        "StackName": "UpdateCFTemplateStack{{automation:EXECUTION_ID}}"
      },
      "name": "deleteCloudFormationTemplate"
    }
  ]
}

関連情報

docs.aws.amazon.com

まとめ

SSM Automation の中で使っている Lambda の Python バージョンがサポート外になって定期処理が失敗した事象と対応の簡単なまとめでした.自分は Automation で使っている言語バージョンまでしっかり確認できてなくて痛い目を見たんですが,同じ事象に遭遇した人や今後使おうと思っている時の参考になれば嬉しいです.