如何使用serverless-step-functions插件中的定义调​​用AWS Step Function?

时间:2017-02-03 23:19:28

标签: node.js amazon-web-services aws-lambda serverless-framework aws-step-functions

我正在使用无服务器框架来创建我的Lambda函数和无服务器步骤函数插件来定义我的步骤函数。

是否可以使用serverless.yml文件中定义的名称直接从其中一个lambda函数调用步骤函数?

3 个答案:

答案 0 :(得分:8)

我试图解决同样的问题,这个问题和自我回答非常有帮助。但是,我想添加另一个答案,其中包含更多详细信息和一个工作示例,以帮助未来的读者。

您可能需要两件事:

1-启动状态机
2-从状态机调用一个特定函数(通常用于测试目的)

以下演示使用两种情况。

首先,我们需要配置 serverless.yml 文件来声明状态机,Lambda函数和正确的IAM权限。

service: test-state-machine

provider:
  name: aws
  runtime: nodejs4.3
  region: us-east-1
  stage: dev
  environment:
    AWS_ACCOUNT: 1234567890 # use your own AWS ACCOUNT number here

    # define the ARN of the State Machine
    STEP_FUNCTION_ARN: "arn:aws:states:${self:provider.region}:${self:provider.environment.AWS_ACCOUNT}:stateMachine:${self:service}-${self:provider.stage}-lambdaStateMachine"

    # define the ARN of function step that we want to invoke
    FUNCTION_ARN: "arn:aws:lambda:${self:provider.region}:${self:provider.environment.AWS_ACCOUNT}:function:${self:service}-${self:provider.stage}-stateMachineFirstStep"  

functions:
  # define the Lambda function that will start the State Machine
  lambdaStartStateMachine: 
    handler: handler.lambdaStartStateMachine  
    role: stateMachine # we'll define later in this file

  # define the Lambda function that will execute an arbitrary step
  lambdaInvokeSpecificFuncFromStateMachine: 
    handler: handler.lambdaInvokeSpecificFuncFromStateMachine
    role: specificFunction # we'll define later in this file

  stateMachineFirstStep:
    handler: handler.stateMachineFirstStep

# define the State Machine
stepFunctions:
  stateMachines:
    lambdaStateMachine:
      Comment: "A Hello World example"
      StartAt: firstStep
      States: 
        firstStep: 
          Type: Task
          Resource: stateMachineFirstStep
          End: true    

# define the IAM permissions of our Lambda functions
resources:
  Resources:
    stateMachine:
      Type: AWS::IAM::Role
      Properties:
        RoleName: stateMachine
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action: sts:AssumeRole
        Policies:
          - PolicyName: stateMachine
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: "Allow"
                  Action:
                    - "states:StartExecution"
                  Resource: "${self:provider.environment.STEP_FUNCTION_ARN}"
    specificFunction:
      Type: AWS::IAM::Role
      Properties:
        RoleName: specificFunction
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action: sts:AssumeRole
        Policies:
          - PolicyName: specificFunction
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: "Allow"
                  Action:
                    - "lambda:InvokeFunction"
                  Resource: "${self:provider.environment.FUNCTION_ARN}"

package:
  exclude:
    - node_modules/**
    - .serverless/**

plugins:
  - serverless-step-functions

handler.js 文件中定义Lambda函数。

const AWS = require('aws-sdk');

module.exports.lambdaStartStateMachine = (event, context, callback) => {
  const stepfunctions = new AWS.StepFunctions();
  const params = {
    stateMachineArn: process.env.STEP_FUNCTION_ARN,
    input: JSON.stringify({ "msg": "some input" })
  };

  // start a state machine
  stepfunctions.startExecution(params, (err, data) => {
    if (err) {
      callback(err, null);
      return;
    }

    const response = {
      statusCode: 200,
      body: JSON.stringify({
        message: 'started state machine',
        result: data
      })
    };

    callback(null, response);
  });
};

module.exports.lambdaInvokeSpecificFuncFromStateMachine = (event, context, callback) => {  
  const lambda = new AWS.Lambda();
  const params = {
    FunctionName: process.env.FUNCTION_ARN,
    Payload: JSON.stringify({ message: 'invoked specific function' })
  };

  // invoke a specific function of a state machine
  lambda.invoke(params, (err, data) => {
    if (err) {
      callback(err, null);
      return;
    }

    const response = {
      statusCode: 200,
      body: JSON.stringify({
        message: 'invoke specific function of a state machine',
        result: data
      })
    };

    callback(null, response);
  });
};

module.exports.stateMachineFirstStep = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'state machine first step',
      input: event
    }),
  };

  callback(null, response);
};

部署执行:

serverless deploy stepf  
serverless deploy  

使用:

测试
serverless invoke -f lambdaStartStateMachine  
serverless invoke -f lambdaInvokeSpecificFuncFromStateMachine

答案 1 :(得分:1)

使用无服务器环境变量解决:

environment:
  MYFUNCTION_ARN: "arn:aws:states:${self:provider.region}:${self:provider.environment.AWS_ACCOUNT}:stateMachine:${self:service}-${self:provider.stage}-myFunction"

在功能中:

var params = {
  stateMachineArn: process.env.MYFUNCTION_ARN
};

答案 2 :(得分:0)

现在就是你如何解决这个问题。

serverless.yml中,定义您的stepFunctions以及Outputs

# define your step functions
stepFunctions:
  stateMachines:
    myStateMachine:
      name: stateMachineSample
      events:
        - http:
            path: my-trigger
            method: GET

# make it match your step functions definition
Outputs:
    myStateMachine:
      Value:
        Ref: StateMachineSample

然后,您可以使用${self:resources.Outputs.fipeStateMachine.Value}将状态机ARN设置为环境。