回答

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 
}; 
7

我試圖解決同樣的問題,這個問題和自我的答案是非常有益的。但是,我想添加更多的答案,提供更多的細節和實例來幫助未來的讀者。


還有,你可能需要兩件事情:

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 
0

這裏是你如何解決這個問題現在。

在你serverless.yml,定義stepFunctionsOutputs

# 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}的環境。

相關問題