【问题标题】:AWS CloudFormation. Calling synchronously Step Function from API Gateway v1AWS CloudFormation。从 API Gateway v1 同步调用 Step Function
【发布时间】:2021-05-16 19:34:13
【问题描述】:

我正在尝试通过 API Gateway 同步执行 AWS Step Function。问题是,对于 API Gateway V1,我必须使用 OpenAPI 语法(即 swagger)来指定 integrationSubtype 参数,但有些东西不起作用。这是我正在使用的 CloudFormation 模板:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "restApiName": {
            "Type": "String",
            "Default": "stepApi"
        }
    },
    "Resources": {
        "MyStepFunction": {
            "Type": "AWS::StepFunctions::StateMachine",
            "Properties": {
                "StateMachineName": "HelloWorld-StateMachine",
                "StateMachineType": "EXPRESS",
                "DefinitionString": "{\"Comment\": \"A Hello World example of the Amazon States Language using Pass states\", \"StartAt\": \"Hello\", \"States\": {\"Hello\": { \"Type\": \"Pass\", \"Result\": \"Hello\", \"Next\": \"World\" }, \"World\": { \"Type\": \"Pass\", \"Result\": \"World\", \"End\": true } } }",
                "RoleArn": {
                    "Fn::GetAtt": [
                        "StepFunctionRole",
                        "Arn"
                    ]
                }
            }
        },
        "StepFuncGateway": {
            "Type": "AWS::ApiGateway::RestApi",
            "Properties": {
                "Name": {
                    "Ref": "restApiName"
                },
                "Body": {
                    "openapi": "3.0.1",
                    "info": {
                        "title": "processFormExample",
                        "version": "2020-11-06 15:32:29UTC"
                    },
                    "paths": {
                        "/step": {
                            "post": { 
                                "responses": {
                                    "200": {
                                      "description": "Pet updated.",
                                      "content": {
                                        "application/json": {},
                                        "application/xml": {}
                                      }
                                    },
                                    "405": {
                                        "description": "Method Not Allowed",
                                        "content": {
                                            "application/json": {},
                                            "application/xml": {}
                                        }
                                    }
                                },
                                "parameters": [
                                ],
                                "x-amazon-apigateway-integration": {
                                    "integrationSubtype": "StepFunctions-StartSyncExecution",
                                    "credentials": {
                                        "Fn::GetAtt": [
                                            "APIGatewayRole", 
                                            "Arn"
                                        ]
                                    },
                                    "RequestTemplates": {
                                        "application/json": {
                                            "Fn::Join": [
                                                "",
                                                [
                                                    "#set( $body = $util.escapeJavaScript($input.json('$')) ) \n\n{\"input\": \"$body\",\"name\": \"$context.requestId\",\"stateMachineArn\":\"",
                                                    {
                                                        "Ref": "MyStepFunction"
                                                    },
                                                    "\"}"
                                                ]
                                            ]
                                        }
                                    },
                                    "httpMethod": "POST",
                                    "payloadFormatVersion": "1.0",
                                    "passthroughBehavior": "NEVER",
                                    "type": "AWS_PROXY",
                                    "connectionType": "INTERNET"
                                }
                            }
                        }
                    },
                    "x-amazon-apigateway-cors": {
                        "allowMethods": [
                            "*"
                        ],
                        "maxAge": 0,
                        "allowCredentials": false,
                        "allowOrigins": [
                            "*"
                        ]
                    }
                }
            },
            "DependsOn": [
                "APIGatewayRole",
                "MyStepFunction"
            ]
        },
        "APIGatewayRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "apigateway.amazonaws.com"
                                ]
                            },
                            "Action": "sts:AssumeRole"
                        }
                    ]
                },
                "Path": "/",
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs",
                    "arn:aws:iam::aws:policy/AWSStepFunctionsFullAccess"
                ]
            }
        },
        "StepFunctionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Sid": "",
                            "Effect": "Allow",
                            "Principal": {
                                "Service": "states.amazonaws.com"
                            },
                            "Action": "sts:AssumeRole"
                        }
                    ]
                },
                "Path": "/",
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/service-role/AWSLambdaRole"
                ]
            }
        }
    },
    "Outputs": {
        "HelloWorldApi": {
            "Description": "Sync WF API endpoint",
            "Value": {
                "Fn::Sub": "https://${StepFuncGateway}.execute-api.${AWS::Region}.amazonaws.com/step"
            }
        }
    }
}

我看到的错误如下:

导入期间发现错误:无法将集成放在“POST”上 路径“/step”处的资源:指定的集成 URI 无效(服务: 亚马逊API网关;状态码:400;错误代码:BadRequestException; 请求ID:0c74acf9-147f-4561-9f4f-e457096c5533;代理:空)

我没有想法。请帮我解决它。

更新:

我必须将以下代码添加到 x-amazon-apigateway-integration 部分并将类型更改为 AWS

"uri": {
    "Fn::Join": [
        "",
        [
            "arn:aws:apigateway:",
            {
                "Ref": "AWS::Region"
            },
            ":states:action/StartSyncExecution"
        ]
    ]
},

我必须修复的另一件事是RequestTemplates,它应该以小写r 开头。在提到更改后,堆栈已正确部署,但现在我要解决节流问题。

【问题讨论】:

    标签: amazon-cloudformation aws-api-gateway aws-step-functions


    【解决方案1】:

    x-amazon-apigateway-integration 缺少 uri 属性。

    Amazon Developer Guide,URI属性定义为:

    后端的端点 URI。对于 aws 类型的集成, 这是一个 ARN 值。对于 HTTP 集成,这是 HTTP 端点,包括 https 或 http 方案。

    例如:

    "x-amazon-apigateway-integration": {
        "type": "AWS_PROXY",
        "httpMethod": "POST",
        "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets",
        "payloadFormatVersion": 1.0,
        "otherPropterties": "go here"
    }
    

    Amazon 提供有关 URI 定义 here 的其他信息。 (复制方便)

    对于 HTTP 或 HTTP_PROXY 集成,对于标准集成(其中 connectionType 不是 VPC_LINK)或私有集成(其中 connectionType 是 VPC_LINK),URI 必须是根据 RFC-3986 规范的完整编码的 HTTP(S) URL .对于私有 HTTP 集成,URI 不用于路由。

    对于 AWS 或 AWS_PROXY 集成,URI 的格式为 arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}。这里,{Region} 是 API 网关区域(例如,us-east-1); {service} 是集成 AWS 服务的名称(例如 s3); {subdomain} 是特定 AWS 服务支持的指定子域,用于快速查找主机名。 action 可用于基于 AWS 服务操作的 API,使用 Action={name}&{p1}={v1}&p2={v2}... 查询字符串。随后的{service_api} 指的是受支持的操作{name} 以及任何必需的输入参数。或者,路径可用于基于 AWS 服务路径的 API。随后的 service_api 指的是 AWS 服务资源的路径,包括集成 AWS 服务的区域(如果适用)。例如,为了与GetObject的S3 API集成,uri可以是arn:aws:apigateway:us-west-2:s3:action/GetObject&Bucket={bucket}&Key={key}arn:aws:apigateway:us-west-2:s3:path/{bucket}/{key}

    【讨论】:

    • 我尝试按以下格式添加它:"Uri": { "Fn::Join": ["", [ "arn:aws:apigateway:", { "Ref": "AWS::Region" }, ":states:action/StartSyncExecution" ] ] },,但效果不佳。能否请您指向我可以阅读有关 URI 格式的资源?
    • 在答案中添加了其他信息。
    猜你喜欢
    • 2017-08-12
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2020-03-30
    • 1970-01-01
    相关资源
    最近更新 更多