Как вызвать функцию AWS Step, используя определения в плагине serverless-step-functions?

Я использую Serverless Framework для создания своих лямбда-функций и плагин serverless-step-functions для определения моих пошаговых функций.

Можно ли вызвать пошаговую функцию непосредственно из одной из лямбда-функций, используя имя, определенное в файле serverless.yml?




Ответы (3)


Я пытался решить ту же проблему, и этот вопрос и самостоятельный ответ мне очень помогли. Однако я хочу добавить еще один ответ с более подробной информацией и рабочим примером, чтобы помочь будущим читателям.


Вам могут понадобиться две вещи:

1- Запуск конечного автомата
2- Вызов одной конкретной функции из конечного автомата (обычно в целях тестирования)

В следующей демонстрации используются оба случая.

Во-первых, нам нужно настроить файл serverless.yml для объявления конечного автомата, лямбда-функций и правильных разрешений 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.

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
person Zanon    schedule 12.02.2017

Решено с использованием бессерверных переменных среды:

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
};
person melqui    schedule 11.02.2017

Вот как вы это решаете сейчас.

В вашем 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

Затем вы можете установить свой конечный автомат ARN как среду, используя ${self:resources.Outputs.fipeStateMachine.Value}.

person bazaglia    schedule 06.11.2017