如何使用 CloudFormation 为 API 网关 v2 websocket 连接设置 VPC

Posted

技术标签:

【中文标题】如何使用 CloudFormation 为 API 网关 v2 websocket 连接设置 VPC【英文标题】:How to set VPC for API gateway v2 websocket connection using CloudFormation 【发布时间】:2019-11-08 14:02:23 【问题描述】:

无法使用 Cloudformation 为 websocket 路由集成请求定义集成类型“VPC 链接”。

我们不使用无服务器,但使用现有的微服务来提供 websocket 功能。 这些微服务在专用网络上运行,并且只能通过 VPC 链接连接到它们运行所在的 EKS 集群。

所有与 AWS API 网关/websockets 相关的在线 Cloudformation 示例都使用无服务器集成。

我可以使用 AWS 控制台手动配置集成类型“VPC 链接”,但似乎不支持使用 Cloudformation 这样做。 或者至少根本不清楚如何实现这一点。

Cloudformation 文档还明确指出,对于 AWS::APIGatewayV2::Integration.ConnectionType,唯一可用的类型是“INTERNET”而不是“VPC_LINK”。

任何人都知道这是否可以实现,如果不能,我还有哪些其他选项可以自动执行此操作?

基础设施是使用 Terraform 设置的,由于缺乏对 API Gateway/websockets 的支持,我已经需要“回退”到 CloudFormation,但 CloudFormation 似乎还不支持所有内容。

【问题讨论】:

【参考方案1】:

恐怕我遇到了类似的问题。我无法使用 VPC 链接创建与私有 ALB(http 集成)的 API Gateway Websocket API 集成。

我可以使用 cloudFormation 成功地将 Api Gateway HTTP API 与使用 VPC 链接的内部 ALB 集成(按照 this)。

但是,即使 AWS::APIGatewayV2::Integration.ConnectionType 支持 INTERNETVPC_LINK 根据 documentation,它似乎不起作用并且云形成堆栈失败并出现此错误:

VpcLink V2 are not supported for WEBSOCKET Apis. Only Http Apis are supported. (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException

关于我如何尝试的云形成示例

websocketApiGateway:
  Type: AWS::ApiGatewayV2::Api
  Properties:
    Name: websocket-gateway
    Description: Api Gateway for websocket
    ProtocolType: WEBSOCKET
    RouteSelectionExpression: $request.body.action

connectRoute:
  Type: AWS::ApiGatewayV2::Route
  Properties:
    ApiId: !Ref websocketApiGateway
    RouteKey: $connect
    AuthorizationType: NONE
    OperationName: ConnectRoute
    RouteResponseSelectionExpression: $default
    Target: !Join
      - /
      - - integrations
        - !Ref connectIntegration

connectIntegration:
  Type: AWS::ApiGatewayV2::Integration
  Properties:
    ApiId: !Ref websocketApiGateway
    Description: Websocket $connect integration
    IntegrationType: HTTP_PROXY
    IntegrationMethod: ANY
    ConnectionType: VPC_LINK
    ConnectionId: !Ref privateLink
    IntegrationUri: # with VPC_LINK I can't use a well formed url, it's necessary to use the ALB's ARN
      Fn::ImportValue: alb-http-listener-id
    RequestParameters:
      "integration.request.header.domainName": "context.domainName"
      "integration.request.header.stage": "context.stage"
      "integration.request.header.connectionId": "context.connectionId"
    PayloadFormatVersion: 1.0

privateLink:
  Type: AWS::ApiGatewayV2::VpcLink
  Properties:
    Name: private-link
    SecurityGroupIds:
      - !Ref securityGroup
    SubnetIds:
      - !Ref privateNetworkA
      - !Ref privateNetworkB
      - !Ref privateNetworkC

如果有人有更多信息,请发布。不幸的是,缺乏支持和令人困惑的文档。

【讨论】:

【参考方案2】:

我偶然发现了同样的问题。我想我通过使用阶段变量来解决它,就像 API Gateway Web 控制台所建议的那样。所以你需要将 ConnectionID 设置为字符串$stageVariables.vpcLinkId。您需要创建一个AWS::ApiGatewayV2::Stage 资源,该资源具有一个名为vpcLinkId 的阶段变量,并包含VPC 链接的ID(您可以!Ref)。最后,IntegrationUri 需要使用附加 ALB 的 DNS 名称的http:// 设置/构造。这将让您成功创建 VPC 集成。

我仍在考虑 IntegrationType 应该是 HTTP 还是 HTTP_PROXY,以及是否需要创建请求和/或响应模板。但这是另一个问题 :-)

【讨论】:

以上是关于如何使用 CloudFormation 为 API 网关 v2 websocket 连接设置 VPC的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CloudFormation 模板更新现有 AWS API Gateway

如何使用 Cloudformation 强制重新部署我的 API 网关

如何使用 Cloudformation 将 lambda 函数附加到现有 API 网关

如何使用 cloudformation 创建私有 AWS Api 网关?

使用 CloudFormation 向 AWS websocket API 添加集成响应

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