如何使用 AWS CloudFormation 在 AWS API Gateway 集成中指定阶段变量?

Posted

技术标签:

【中文标题】如何使用 AWS CloudFormation 在 AWS API Gateway 集成中指定阶段变量?【英文标题】:How to specify a Stage variable in AWS API Gateway integration using AWS CloudFormation? 【发布时间】:2019-11-14 20:27:15 【问题描述】:

我正在尝试构建 AWS CloudFormation 模板来创建 API 网关。 当我手动创建 API 网关时,我使用阶段变量将不同的 AWS 函数用于不同的阶段。

例如。我有一个名为 adminLogin 的阶段变量, 当 API 网关的阶段为 dev 时,adminLogin 的值为 -dev_adminLoginstage_adminLogin API 网关的阶段为 stage 时的值

API Gateway 的资源整合请求 -

阶段变量映射 -

CloudFormation 模板 sn-p -

test:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: 'test'
      Body:
        swagger: "2.0"
        info:
          version: "2019-04-11T02:29:18Z"
          title: "Test"
        basePath: !Ref "testEnv"
        schemes:
          - "https"
        paths:
          /admin/login:
            post:
              consumes:
                - "application/json"
              produces:
                - "application/json"
              responses:
                '200':
                  description: "200 response"
                  schema:
                    $ref: "#/definitions/Empty"
              x-amazon-apigateway-integration:
                #uri: !Sub "arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$stageVariables.adminLogin/invocations"
                uri: !Join [
                    '', [
                      'arn:',
                      'aws:',
                      'apigateway:',
                      !Ref "AWS::Region",
                      ':lambda:',
                      'path/2015-03-31/functions/',
                      '$stageVariables.adminLogin',
                      '/invocations'
                    ]
                  ]
                responses:
                  default:
                    statusCode: "200"
                passthroughBehavior: "when_no_templates"
                httpMethod: "POST"
                contentHandling: "CONVERT_TO_TEXT"
                type: "aws_proxy"

我在运行 cloudformation 模板时收到以下错误 -

Errors found during import: Unable to put integration on 'POST' for resource at path '/admin/login': Invalid lambda function 
(Service: AmazonApiGateway; 
Status Code: 400; 
Error Code: BadRequestException; 

问题肯定出在uri 属性上, 我都试过了 -

uri: !Sub "arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$stageVariables.adminLogin/invocations"

uri: !Join ['', ['arn:','aws:','apigateway:',!Ref "AWS::Region",':lambda:','path/2015-03-31/functions/','$!stageVariables.adminLogin','/invocations']]

参考 -

    https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apitgateway-method-integration.html#cfn-apigateway-method-integration-uri https://docs.aws.amazon.com/apigateway/latest/developerguide/amazon-api-gateway-using-stage-variables.html

【问题讨论】:

【参考方案1】:

应使用 Lambda ARN(不仅仅是 Lambda 函数名称)提及 Lambda 函数

例如:

uri: "arn:aws:apigateway:REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:REGION:ACCOUNTID:function:dev_adminLogin/invocations"

如下将其放在 cloudformation 中应该可以工作

uri: !Join
      - ''
      - - 'arn:aws:apigateway:'
        - !Ref "AWS::Region"
        - ':lambda:path/2015-03-31/functions/arn:aws:lambda:'
        - !Ref "AWS::Region"
        - ':'
        - !Ref "AWS::AccountId"
        - ':function:$stageVariables.adminLogin/invocations'

还要记得添加 lambda 权限(dev_adminLogin 和 stage_adminLogin),否则 apigateway 将无法调用 lambda 并会收到 5XX 错误

使用 CLI:

aws lambda add-permission  --function-name "arn:aws:lambda:REGION:ACCOUNTID:function:dev_adminLogin"    --source-arn "arn:aws:execute-api:REGION:ACCOUNTID:API_ID/*/POST/admin/login"    --principal apigateway.amazonaws.com    --statement-id stmt1    --action lambda:InvokeFunction

aws lambda add-permission  --function-name "arn:aws:lambda:REGION:ACCOUNTID:function:stage_adminLogin"    --source-arn "arn:aws:execute-api:REGION:ACCOUNTID:API_ID/*/POST/admin/login"    --principal apigateway.amazonaws.com    --statement-id stmt2    --action lambda:InvokeFunction

参考:https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html

【讨论】:

以上是关于如何使用 AWS CloudFormation 在 AWS API Gateway 集成中指定阶段变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 aws cloudformation 模板在 aws cognito 用户池中设置所需属性?

如何在存储桶名称中使用变量 AWS Cloudformation

AWS::CloudFormation::Init 它是如何工作的?

如何使用 cloudformation 在 AWS cognito 上设置验证属性?

如何使用 AWS CloudFormation 在 AWS API Gateway 集成中指定阶段变量?

如何使用 AWS CloudFormation 创建 Amazon VPC?