Terraform配置AWS API Gateway v2集成报错:无效选择表达式
问题分析与解决
错误原因
你遇到的问题核心是对API Gateway v2与Step Functions的AWS_PROXY集成中request_parameters.Input参数的语法规则理解有误:
- 当使用
AWS_PROXY集成类型(子类型为StepFunctions-StartSyncExecution)时,Input参数的值会被API Gateway当作**映射表达式(API Gateway特定语法)**解析,而非静态JSON字符串。 - 你用Terraform的
jsonencode({"body":"$request.body"})生成的结果是"{\"body\":\"$request.body\"}",其中$request.body被包裹在双引号中,变成了静态字符串字面量。API Gateway会尝试把整个{"body":"$request.body"}当作选择表达式解析,这完全不符合语法规范,因此触发"Invalid source"错误。
正确配置方式
直接构造符合API Gateway映射语法的字符串作为Input的值,确保$request.body作为裸表达式存在(不被引号包裹)——因为$request.body本身就会返回请求体的JSON内容。
方案1:直接构造简单JSON结构
resource "aws_apigatewayv2_integration" "stepfunctions_sync" { api_id = aws_apigatewayv2_api.example.id integration_type = "AWS_PROXY" integration_subtype = "StepFunctions-StartSyncExecution" credentials_arn = aws_iam_role.apigw_stepfunctions.arn request_parameters = { "Input" = "{\"body\": $request.body}" "StateMachineArn" = aws_sfn_state_machine.example.arn } }
方案2:用工具函数处理特殊字符
如果请求体包含特殊字符,用$util.escapeJavaScript()避免解析异常:
request_parameters = { "Input" = "{\"body\": $util.escapeJavaScript($request.body)}" }
方案3:传递完整请求体
如果不需要包装body字段,直接传递整个请求体:
request_parameters = { "Input" = "$input.json('$')" }
方案4:用Heredoc提升可读性
对于复杂结构,Terraform的Heredoc格式更清晰:
request_parameters = { "Input" = <<EOF {"body": $request.body, "requestPath": "$request.path"} EOF }
关键注意事项
- 不要用Terraform的
jsonencode处理包含$开头的API Gateway映射表达式的内容,否则会把表达式转义成静态字符串,导致API Gateway无法解析。 - API Gateway的映射表达式中,
$request.body返回的是请求体的原始JSON(不带引号),因此直接嵌入JSON结构即可,无需额外引号包裹。
内容的提问来源于stack exchange,提问作者Kishieel
相关产品推荐
相关产品推荐

