Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpApi circular dependency between RouteSettings and Route #2479

Open
brcarp opened this issue Aug 26, 2022 · 7 comments
Open

HttpApi circular dependency between RouteSettings and Route #2479

brcarp opened this issue Aug 26, 2022 · 7 comments

Comments

@brcarp
Copy link

brcarp commented Aug 26, 2022

Description:

When creating HTTP API and Stage resources for the first time using AWS::Serverless::HttpApi, adding RouteSettings will fail for routes that you may be creating at the same time. (You cannot create the Route resource ahead of time because it needs to belong to the API that you are creating.) The circular dependency can be resolved by first creating the HttpApi along with a defined Route resource, and then doing a subsequent update to add RouteSettings that will match it to existing routes, but this is inefficient and not a golden path.

Steps to reproduce:

Example template snippet:

Resources:

  TestHttpApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      FailOnWarnings: true
      StageName: 'test'
      RouteSettings:
        'GET /path':
          ThrottlingBurstLimit: 100
          ThrottlingRateLimit: 100

  TestRoute:
    Type: AWS::ApiGatewayV2::Route
    Properties:
      ApiId: !Ref TestHttpApi
      RouteKey: 'GET /path'
      Target: !Join
        - /
        - - integrations
          - !Ref TestIntegration

  TestIntegration:
    Type: AWS::ApiGatewayV2::Integration
    Properties:
      ApiId: !Ref TestHttpApi
      # [...]

Observed result:

The AWS::ApiGatewayV2::Stage resource results in a CREATE_FAILED in CloudFormation with the following error:

Unable to find Route by key GET /path within the provided RouteSettings (Service: AmazonApiGatewayV2; Status Code: 404; Error Code: NotFoundException; Request ID: x-x-x-x-x; Proxy: null))

Expected result:

The expectation is that the SAM deploy can create the API, Stage and Route together in a single deployment, resolving the circular dependency of the Route needing to exist before the Stage's RouteSettings can be applied.

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: Amazon Linux
  2. If using SAM CLI, sam --version: FROM public.ecr.aws/sam/build-nodejs14.x:latest (should be 1.55.0)
  3. AWS region: us-east-1
@brcarp brcarp added stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. type/bug labels Aug 26, 2022
@brcarp
Copy link
Author

brcarp commented Aug 26, 2022

Some additional thoughts regarding the desired behavior here:

  1. It would be nice if all the Route settings (like Target) could be included in the RouteSettings property, so that it didn't need to be specified as a separate resource
  2. Barring (1.) above, I had the thought of whether the RouteKey in the RouteSettings could be retrieved by Fn::GetAtt (with arguments TestRoute, RouteKey), but as far as I can tell, you cannot use intrinsic functions for the name in a name-value pairing (inside RouteSettingsMap or anywhere else for that matter). It seemed like it would be a nice little trick to not have to write out the route key in multiple places, and to be able to use the route's property by reference, but at the end of the day that is all a workaround for (1.) above anyway.

If all of the route's properties could be provided in the RouteSettings of the HttpApi, then you'd only need to specify the route key in one place. In such an enhancement to the SAM specification, the included settings would need to be divided up into the route creation and the stage creation, but it would be much cleaner for the template. As it stands, there needs to be multiple deploys and careful coordination, both among the resources and between the deployments, to get the route settings applied properly.

@jfuss
Copy link
Contributor

jfuss commented Aug 26, 2022

@brcarp AWS::Serverless::Api and AWS::Serverless::HttpApi should not be used with the "raw" ApiGateway resources. Api Gateway will accept this but can lead to unexpected behavior.

What happens if you switch to specifying this through OpenApi? This should fix the circular dependencies and the nondeterministic behavior of ApiGateway.

@jfuss jfuss removed the stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. label Aug 26, 2022
@jfuss jfuss self-assigned this Aug 26, 2022
@brcarp
Copy link
Author

brcarp commented Aug 26, 2022

@brcarp AWS::Serverless::Api and AWS::Serverless::HttpApi should not be used with the "raw" ApiGateway resources. Api Gateway will accept this but can lead to unexpected behavior.

@jfuss is that documented anywhere? I didn't know that was considered unsupported behavior.

What happens if you switch to specifying this through OpenApi? This should fix the circular dependencies and the nondeterministic behavior of ApiGateway.

I actually had a LOT of difficulty trying to set up an HTTP proxy integration with a VPC Link using OpenApi. If you have any working examples of that to share, I'd be interested to see them. In my experimentation, I could not get this to work with VPC Links and a proxy path variable (/{proxy+} => "overwrite:path": "/base-path/${request.path.proxy}").

@jfuss
Copy link
Contributor

jfuss commented Aug 26, 2022

is that documented anywhere? I didn't know that was considered unsupported behavior.

@brcarp This has come up before in the repo. Here is a previous response: #1971 (comment) I would have to check/search if Api Gateway updated their docs. At the very least, we should have it on our docs as well. I either can't find it or needs to be added. Will take that up internally.

If you have any working examples of that to share,

I do not off hand. I would have to create one myself. Have you looked at https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-api-with-vpclink-using-swagger.html? Seems like what you are looking for but not totally sure.

@brcarp
Copy link
Author

brcarp commented Aug 26, 2022

If you have any working examples of that to share,

I do not off hand. I would have to create one myself. Have you looked at https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-api-with-vpclink-using-swagger.html? Seems like what you are looking for but not totally sure.

@jfuss Yeah that's useful for the VPC Link, but I think my actual issue was with using {proxy+} as a path parameter for creating a proxy with path overwrite. I couldn't find any documentation on that at all. It's not clear to me whether that's part of the OpenAPI spec or whether transforming API requests and responses with a proxy integration was specific to AWS and not configurable with OpenAPI.

I was unable to get that aspect of it to work properly, but it may be because I was experimenting in the dark without any relevant documentation.

@brcarp
Copy link
Author

brcarp commented Aug 26, 2022

For what it's worth, I recall trying to follow the model in the article Set up a proxy resource with Lambda proxy integration and Set up HTTP integrations in API Gateway, but finding that it did not work correctly for HTTP_PROXY type (vs. AWS_PROXY type for a Lambda) in an HTTP API (vs. a REST API).

@brcarp
Copy link
Author

brcarp commented Aug 26, 2022

It's possible that I just didn't iterate on it enough, but my recollection is that I just wasn't able to get it to work. If it has been proven out, it would be nice to add an OpenAPI example to Working with HTTP proxy integrations for HTTP APIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants