[英]Does AWS API Gateway private integration with ALB works with ALB https listener
[英]Rewrite destination path in Api Gateway websocket API private http integration with ALB
我有一個帶有 ECS 集群的私有子網,其中沒有公共 IP 地址的服務在應用程序負載均衡器后面運行。
Application Load Balancer 也是私有的。
我有一個 API 網關,通過 HTTP 使用 VPC 鏈接與該 ALB(請參閱此)集成。
我所有的微服務都像這樣工作得很好。
But now I need to add support for websockets and I need to create an API Gateway with protocol type WEBSOCKET, that has routes with HTTP integation, so that the websocket routes $connect
, $disconnect
, sendmessage
are transformed into HTTP requests.
我遇到的問題是,為了使用私有集成,我必須指定 ALB 的 Arn,並且我不能指定 URL(請參閱此)。 關於IntegrationUri
:
對於 HTTP API 私有集成,指定應用程序負載均衡器偵聽器、網絡負載均衡器偵聽器或 AWS Cloud Map 服務的 ARN。 如果您指定 AWS 雲 Map 服務的 ARN,則 API 網關使用 DiscoverInstances 來識別資源。 您可以使用查詢參數來定位特定資源。 要了解更多信息,請參閱 DiscoverInstances。 對於私有集成,所有資源必須歸同一個 AWS 賬戶所有。
因此,在 IntegrationUri 中,無需指定諸如https://mypublicdomain.com/My.Service/connect
的內容,我可以輕松地將服務路徑添加為 URL 的一部分,而是被迫添加應用程序負載均衡器 ARN, arn:aws:myalb...
因此我不能使用 URL 路徑來讓 websocket 路由與 ALB 后面的特定服務集成。
換句話說,如何將 API 網關上的 websocket 路由與私有 ALB 后面的特定服務相關聯?
PS:我曾想過使用一些帶有路徑模式條件的偵聽器規則,這些規則可以抓取所有流向 ALB 根/
到所需服務的流量,但這遠非理想,因為我想基於更明顯的東西進行路由。
CloudFormation 示例:
Resources:
websocketApiGateway:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: websocket-gateway
Description: Api Gateway for websocket
ProtocolType: WEBSOCKET
DisableExecuteApiEndpoint: false
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: POST
IntegrationUri: # I cannot use something like https://mypublicdomain.com/My.Service/connect
Fn::ImportValue: !Sub my-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
connectRouteResponse:
Type: AWS::ApiGatewayV2::RouteResponse
Properties:
ApiId: !Ref websocketApiGateway
RouteId: !Ref connectRoute
RouteResponseKey: $default
UPDATE 1: Just after writing the question I thought.. If I can't route based on URI, maybe I can route at the ALB http listener based on some http header that I can set in the websocket's api gateway integration. 所以我會保留它作為一種解決方法,以防我找不到重寫 url 路徑的方法
UPDATE 2: This question is similar, but the answer is not detail enough Rewrite destination path in api gateway integration request
我並沒有真正解決它,但我有一個解決方法。
在 API 網關級別 websockets 請求被轉換為 HTTP 請求返回到 API 網關。 不理想,因為最好在內部將 http 請求發送到集成,但它可以工作並且希望它不會增加太多延遲,因為目標是相同的 api 網關。 我還添加了一些請求標頭,允許我在 web 應用程序級別提取最初位於 websocket 消息中的所需信息。
listenerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref targetGroup
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- !Sub
- ${servicePath}*
- servicePath: !FindInMap [microservice, settings, path]
ListenerArn:
Fn::ImportValue: !Sub ${prefix}-alb-http-listener-id
Priority: 2
現在在 api 網關我有我的 websocket 路由。 像這樣的東西
wsCommandRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref wsApiGateway
RouteKey: command
AuthorizationType: NONE
OperationName: CommandRoute
RouteResponseSelectionExpression: $default
Target: !Join
- /
- - integrations
- !Ref wsCommandIntegration
wsCommandIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref wsApiGateway
Description: Websocket command integration
IntegrationType: HTTP_PROXY
IntegrationMethod: POST
IntegrationUri:
!Sub
- https://${domainName}${websocketServicePath}/ws/commands
- domainName: !FindInMap [gateways, api, domainName]
websocketServicePath:
Fn::ImportValue: !Sub ${prefix}-websocket-service-path
RequestParameters:
"integration.request.header.domainName": "context.domainName"
"integration.request.header.stage": "context.stage"
"integration.request.header.connectionId": "context.connectionId"
PayloadFormatVersion: 1.0
wsCommandRouteResponse:
Type: AWS::ApiGatewayV2::RouteResponse
Properties:
ApiId: !Ref wsApiGateway
RouteId: !Ref wsCommandRoute
RouteResponseKey: $default
如果有人有更好的方法,我很樂意將其標記為有效答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.