【问题标题】:Pass and use input (parameters) to a lambda task from a step function将输入(参数)从阶跃函数传递并使用到 lambda 任务
【发布时间】:2019-06-18 21:01:12
【问题描述】:

我有一个启动 lambda 的简单步进函数,我正在寻找一种将参数(事件/上下文)传递给多个后续任务的方法。我的步进函数如下所示:

{
  "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
  "StartAt": "HelloWorld",
  "States": {
    "HelloWorld": {
      "Type": "Task",
      "Parameters": {
        "TableName": "table_example"
      },
      "Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync",
      "End": true
    }
  }
}

在用 Python 编写的 lambda 中,我使用了一个简单的处理程序:

def lambda_handler(event, context):
    #...

事件和上下文如下所示(检查日志):

START 请求 ID:f58140b8-9f04-47d7-9285-510b0357b4c2 版本:$LATEST

我找不到将参数传递给此 lambda 并在脚本中使用它们的方法。本质上,我想要做的是运行相同的 lambda,传递几个不同的值作为参数。

谁能指出我正确的方向?

【问题讨论】:

  • 您发布的日志中的行只是 Lambda 启动时的“标准标记”,而不是 eventcontext 对象。您的步进功能看起来不错。检查event 参数的内容(你可以只print(event) 并检查日志),你应该看到TableName 出现在那里。

标签: python amazon-web-services aws-lambda aws-step-functions


【解决方案1】:

显然,当 Resource 设置为 lambda ARN(例如 "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync")时,我遇到了这个问题,您不能使用 Parameters 来指定输入,而是传递 step 函数的状态(可能是您的状态函数的输入,如果之前没有步骤)。

要通过参数传递函数输入,您可以将资源指定为"arn:aws:states:::lambda:invoke",并在参数部分提供您的FunctionName

{
    "StartAt": "HelloWorld",
    "States": {
        "HelloWorld": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "Parameters": {
                "FunctionName": "YOUR_FUNCTION_NAME",
                "Payload": {
                    "SOMEPAYLOAD": "YOUR PAYLOAD"
                }
            },
            "End": true
        }
    }
}

您可以在此处找到调用 Lambda 函数的文档:https://docs.aws.amazon.com/step-functions/latest/dg/connect-lambda.html

您也可以潜在地使用 inputPath,或者也可以从您的步进函数状态函数中获取元素:https://docs.aws.amazon.com/step-functions/latest/dg/input-output-inputpath-params.html

【讨论】:

  • 即使这个解决方案来自文档,我也测试过它并且不起作用。或者至少控制台没有向我显示传入的参数,并且该步骤的输出带有响应数据的附加包装器。
【解决方案2】:

就像 Milan 在他的 comment 中提到的那样,您可以将数据从 Step Function State 传递给 Lambda 函数。

在 Lambda 函数中,您需要阅读 event 的内容。

import json

def lambda_handler(event, context):
    TableName = event['TableName']

【讨论】:

  • 嘿,你好像对我的回答投了反对票。如果您能评论哪一部分是错误的或它是如何无用的,我将不胜感激。使用海报显示没有参数传递给 lambda 的阶梯函数,所以我正在回答如何在阶梯函数中实际将参数传递给 lambda。
  • 您好 Farid,当然,OP 的阶跃函数逻辑是正确的,只需阅读 lambda_handler 中的 event var。你的回答对我不起作用;无法以这种方式调用 Lambda(确切的错误消息已被我忽略)。
【解决方案3】:

根据你说的:“寻找一种传递参数的方法 (事件/上下文)到几个后续任务中的每一个”我假设 您想将非静态值传递给 lambda。

两种方式通过状态机传递参数。通过InputPathParameters。差异请看here

如果您没有要传递给 lambda 的任何静态值,我会执行以下操作。将所有参数以 json 格式传递给 step 函数。

为状态机输入 JSON

{
    "foo": 123,
    "bar": ["a", "b", "c"],
    "car": {
        "cdr": true
    }
    "TableName": "table_example"
}

在 step 函数中,您使用 "InputPath": "$" 将整个 JSON 显式传递给 lambda,但隐式传递的第一步除外。有关$ 路径语法的更多信息,请查看here。您还需要处理任务结果,multiple approaches 之一使用ResultPath。在大多数情况下,最安全的解决方案是将任务结果保存在特殊变量 "ResultPath": "$.taskresult"

{
  "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
  "StartAt": "HelloWorld",
  "States": {
    "HelloWorld": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync",
      "Next": "HelloWorld2"
    },
    "HelloWorld2": {
      "Type": "Task",
      "InputPath": "$",
      "ResultPath": "$.taskresult"
      "Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync_2",
      "End": true
    }
  }
}

在 lambda 中成为事件变量,可以作为 python 字典访问

def lambda_handler(event, context):
    table_example = event["TableName"]
    a = event["bar"][0]
    cdr_value = event["car"]["cdr"]
    # taskresult will not exist as event key 
    # only on lambda triggered by first state
    # in the rest of subsequent states
    # it will hold a task result of last executed state
    taskresult = event["taskresult"]

通过这种方法,您可以使用多个步进函数和不同的 lambda,并且通过 移动 lambda 中的所有逻辑,仍然可以保持它们简洁。 此外,它更容易调试,因为所有事件变量在所有 lambda 中都是相同的,因此通过简单的print(event),您可以看到整个状态机所需的所有参数以及可能出现的问题。

【讨论】:

  • 您好,谢谢您的解释,我还是有点困惑,这是我的问题:stackoverflow.com/questions/66463859/… 你能看看吗?非常感谢。
  • 令人困惑的部分是我们如何将 JSON 有效负载传递给 stepfunction?它没有显示在状态机定义中的任何地方......
  • 是的,他确实忽略了,但是helloworld2的JSON输入需要从helloworld1输出。
【解决方案4】:

由于某种原因,在Resource 中直接指定lambda function ARN 不起作用。

以下解决方法纯粹是使用 ASL 定义,您只需在使用参数之前创建一个 Pass 步骤,其输出将用作下一步的输入(您的步骤 HelloWorld 使用 lambda 调用):

{
  "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
  "StartAt": "HelloParams",
  "States": {
    "HelloParams": {
      "Type": "Pass",
      "Parameters": {
        "TableName": "table_example"
      },
      "Next": "HelloWorld"
    },
    "HelloWorld": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync",
      "End": true
    }
  }
}

另一个响应中有一个解决方法,它告诉您使用 lambda 函数进行上一步,但对于简单的情况不需要它。还可以映射上下文值,例如当前时间戳:

"HelloParams": {
  "Type": "Pass",
  "Parameters": {
    "TableName": "table_example",
    "Now": "$$.State.EnteredTime"
  },
  "Next": "HelloWorld"
}, 

此外,InputPathResultPath 可用于防止覆盖之前步骤中的值。例如:

{
  "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
  "StartAt": "HelloParams",
  "States": {
    "HelloParams": {
      "Type": "Pass",
      "Parameters": {
        "TableName": "table_example"
      },
      "ResultPath": "$.hello_prms",
      "Next": "HelloWorld"
    },
    "HelloWorld": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync",
      "InputPath": "$.hello_prms",
      "ResultPath": "$.hello_result",
      "End": true
    }
  }
}

这会将参数保存在hello_prms 中(以便您可以在其他步骤中重用它们)并将执行结果保存在hello_result 中,而无需之前步骤中的值(以防您添加它们)。

【讨论】:

    猜你喜欢
    • 2020-12-11
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2022-07-07
    • 2016-03-12
    • 2018-05-21
    • 2022-01-25
    相关资源
    最近更新 更多