如何使用AWS CloudFormation在AWS API Gateway集成中指定一个舞台变量?

时间:2019-07-04 06:50:36

标签: amazon-web-services amazon-cloudformation aws-api-gateway

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

例如我有一个名为adminLogin的舞台变量,
adminLogin的值将为-
dev_adminLogin,当API网关的阶段为dev
stage_adminLogin,当API网关的阶段为stage

API网关的资源集成请求-
enter image description here

阶段变量映射-
enter image description here

CloudFormation模板代码段-

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']]

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

1 个答案:

答案 0 :(得分: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