AWS StateMachine for Lambda,云形成语法

时间:2018-05-13 06:52:11

标签: amazon-web-services aws-lambda aws-api-gateway amazon-cloudformation state-machine

我试图想出一个包含

的CloudFormation模板
  • API网关
  • 通过API网关调用StateMachine
  • StateMachine反过来包含一个lambda函数

本质上,我尝试做的是以下

https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-api-gateway.html

然而,我不得不提出将部署此功能的云形成模板(.yaml)。到目前为止,这就是我所拥有的

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  Post:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: UserBase-fnUsers
      Handler: UsersHandler.getUsers
      Runtime: nodejs6.10
      Policies: [AmazonDynamoDBReadOnlyAccess, AmazonS3ReadOnlyAccess]
      Environment:
        Variables: 
          S3_BUCKET: UserBase-Users-bucket
          UsersTable: UserBase-Users-tblUsers
      Events:
        GetUsers:
          Type: Api
          Properties:
            Path: /UserBase/Users
            Method: post      
  Options:
    Type: AWS::Serverless::Function
    Properties:                     
      FunctionName: UserBase-fnUsers-Options
      Handler: UsersHandler.getOptions
      Runtime: nodejs6.10
      Events:
        GetOptions:
          Type: Api
          Properties:
            Path: /UserBase/Users
            Method: options                           
  UsersTable:
    Type: AWS::DynamoDB::Table
    Properties: 
      TableName: UserBase-Users-tblUsers
      AttributeDefinitions: 
        - AttributeName: Id
          AttributeType: S   
      KeySchema: 
        - AttributeName: Id
          KeyType: HASH   
      ProvisionedThroughput: 
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5       
      StreamSpecification:
        StreamViewType: KEYS_ONLY                
  StatesExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - !Sub states.${AWS::Region}.amazonaws.com
            Action: "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: StatesExecutionPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "lambda:InvokeFunction"
                Resource: "*"

  UpdateShoppingPath:
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
      DefinitionString:
        !Sub
          - |-
            {
              "Comment": "State machine to update the shopping path",
              "StartAt": "UpdatePath",
              "States": {
                "UpdatePath": {
                  "Type": "Task",
                  "Resource": "${lambdaArn}",
                  "End": true
                }
              }
            }
          - {lambdaArn: !GetAtt [ Post, Arn ]}
      RoleArn: !GetAtt [ StatesExecutionRole, Arn ]
  UserBaseUsers:
     Type: "AWS::ApiGateway::Resource"

我坚持使用最后一块,主要是关于如何将ApiGateway链接到StateMachine。在旁注中,有什么方法可以从AWS中的现有部署生成云形成模板(.yaml或json)?

1 个答案:

答案 0 :(得分:0)

我不是yaml的专家,但我使用json CloudFormation做了一些配置,据我所知,它很容易翻译。

过去我和你一样被困,here是我的帖子和我的解决方案

开始执行步骤函数需要做的是对arn:aws:apigateway:${region}:states:action/StartExecution进行HTTP发布作为json对象 [docs]传递:

{
input: __input__,
stateMachineArn: __arn__
}

简而言之,在AWS::ApiGateway::Method中,您必须将HTTP集成设置为arn:aws:apigateway:${region}:states:action/StartExecution以及构建我提到的json对象的requestTemplate。

供参考,这里是我的json cloudformation示例:

"FooRequest": {
    "DependsOn": ["FooStepMachine"],
    "Type": "AWS::ApiGateway::Method",
    "Properties": {
        "HttpMethod": "POST",
        "Integration": {
            "Type": "AWS",
            "Credentials": {
                "Fn::GetAtt": ["FooRole",
                "Arn"]
            },
            "IntegrationHttpMethod": "POST",
            "Uri": {
                "Fn::Join": ["",
                ["arn:aws:apigateway:",
                {
                    "Ref": "AWS::Region"
                },
                ":states:action/StartExecution"]]
            },
            "IntegrationResponses": [{
                "StatusCode": 200
            },
            {
                "StatusCode": 401
            }],
            "RequestTemplates": {
                "application/json": {
                    "Fn::Sub": ["{\"input\": \"$util.escapeJavaScript($input.json('$'))\",\"stateMachineArn\": \"${arn}\"}",
                    {
                        "arn": {
                            "Ref": "FooStepMachine"
                        }
                    }]
                }
            }
        }
    }
}