【问题标题】:How can I request parameters in api gateway using cloudformation in aws and pass it down to lambda function?如何使用aws中的cloudformation请求api网关中的参数并将其传递给lambda函数?
【发布时间】:2020-05-31 06:38:14
【问题描述】:

我正在尝试使用 AWS CloudFormation 中的 API Gateway 请求参数。我想从 API 网关传递给 Lambda 函数的参数是“action”。我已经尝试了以下代码,到目前为止我遇到了错误,如下所述。有人可以帮我确定问题和可能的解决方案吗?

“指定的映射表达式无效:验证结果:警告:[],错误:[指定的映射表达式无效:Integration.request.path.action](服务:AmazonApiGateway;状态代码:400;错误代码:BadRequestException;请求ID : 037f4753-52b5-4276-979a-131a0f903e63)"

AWSTemplateFormatVersion: "2010-09-09"
Description: "API Gateway and Lambda function"

Resources:
  SampleApi:
    Type: "AWS::ApiGateway::RestApi"
    Properties:
      Name: Sample

  SampleApiMethod:
    Type: "AWS::ApiGateway::Method"
    Properties:
      AuthorizationType: "NONE"
      HttpMethod: "GET"
      RequestParameters:
        method.request.path.action: true
      RequestTemplates:
        application/yaml
      Integration:
        IntegrationHttpMethod: "POST"
        Type: "AWS_PROXY"
        RequestParameters:
          Integration.request.path.action: method.request.path.action 
        Uri: !Sub
          - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations"
          - lambdaArn: !GetAtt "SampleLambda.Arn"
        CacheKeyParameters:
          - method.request.path.action
      ResourceId: !GetAtt "SampleApi.RootResourceId"
      RestApiId: !Ref "SampleApi"

  SampleApiDeployment:
    Type: "AWS::ApiGateway::Deployment"
    DependsOn: "SampleApiMethod"
    Properties:
      RestApiId: !Ref "SampleApi"
      StageName: test

  SampleLambda:
    Type: "AWS::Lambda::Function"
    Properties:
      Code:
        ZipFile: |
            import yaml
            import boto3
            cf_client = boto3.client('cloudformation')
            cf_client.create_stack(
                StackName='your-stack',
                TemplateURL='Some URL',
                Parameters=[
                    {
                        'ParameterKey':'action',
                        'ParameterValue': 'kms:*'
                    },
                ]
            )
      Handler: "index.handler"
      Role: !GetAtt "SampleLambdaRole.Arn"
      Runtime: python3.7

  LambdaApiGatewayInvoke:
    Type: "AWS::Lambda::Permission"
    Properties:
      Action: "lambda:InvokeFunction"
      FunctionName: !GetAtt "SampleLambda.Arn"
      Principal: "apigateway.amazonaws.com"
      SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SampleApi}/*/GET/"

  SampleLambdaRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Action: ["sts:AssumeRole"]
            Effect: "Allow"
            Principal:
              Service: ["lambda.amazonaws.com"]
      Policies:
        - PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action: ["cloudwatch:*", "logs:*"]
                Effect: "Allow"
                Resource: "*"
          PolicyName: "lambdaLogPolicy"  
Outputs:
  apiGatewayInvokeURL:
    Value: !Sub 'https://Sample.execute-api.${AWS::Region}.amazonaws.com/test' 

【问题讨论】:

    标签: amazon-web-services aws-lambda yaml amazon-cloudformation


    【解决方案1】:

    根据文档,RequestParameters 的键应类似于 integration.request.<location>.<name>integration 应为小写 i。您正在使用大写字母 I。来自AWS CloudFormation docs

    使用以下模式integration.request.location.name 指定目标,其中location 是查询字符串、路径或标头,name 是有效的唯一参数名称。

    此外,您上面的模板包含一个 RequestTemplates 属性,该属性放置在错误的层次结构级别。如AWS CloudFormation docs 中所述,它必须位于Integration 下方。这是AWS::ApiGateway::Method 的正确模板:

    SampleApiMethod:
      Type: "AWS::ApiGateway::Method"
      Properties:
        AuthorizationType: "NONE"
        HttpMethod: "GET"
        RequestParameters:
          method.request.path.action: true
        Integration:
          IntegrationHttpMethod: "POST"
          Type: "AWS_PROXY"
          RequestParameters:
            integration.request.path.action: method.request.path.action
          RequestTemplates:
            "application/yaml": "<define your template here>"
          Uri: !Sub
            - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations"
            - lambdaArn: !GetAtt "SampleLambda.Arn"
          CacheKeyParameters:
            - method.request.path.action
        ResourceId: !GetAtt "SampleApi.RootResourceId"
        RestApiId: !Ref "SampleApi"
    

    有关定义请求模板的更多信息可以在developer reference中找到。

    【讨论】:

      猜你喜欢
      • 2016-03-27
      • 2021-11-03
      • 2020-04-26
      • 2016-04-10
      • 2021-03-27
      • 1970-01-01
      • 2019-04-03
      • 2017-12-25
      • 2017-12-30
      相关资源
      最近更新 更多