serverless/serverless

Usage of "apiKeys" can cause "Resource ApiGatewayRestApi does not exist for stack" when removing a stack

Open

#7.922 geöffnet am 8. Juli 2020

Auf GitHub ansehen
 (13 Kommentare) (6 Reaktionen) (0 zugewiesene Personen)JavaScript (46.915 Stars) (5.734 Forks)batch import
bugcat/aws-event-api-gatewayhelp wanted

Beschreibung

This is somewhat related to issue #4282 which has been closed for some time. However the problem does still exist for at least one specific use case related to the usage of apiKeys in combination with an existing apiGateway created e.g. in another serverless project.

Assume a "core" project, which only purpose is to create stateful resources like databases, s3 buckets and a common api gateway for different other micro service projects. That core project will (at least in our case) have no functions. The serverless.yml for the core project could look like this:

service: core

provider:
  name: aws

resources:
  - Resources:
     ApiGatewayRestApi:
       Type: AWS::ApiGateway::RestApi
       Properties:
         Name: some-api-gateway
  - Outputs:
      ApiGatewayRestApiId:
        Value: !Ref ApiGatewayRestApi
      ApiGatewayRestApiRootResourceId:
        Value: !GetAtt ApiGatewayRestApi.RootResourceId  

Then, in one of your other (micro-service) project you would want to add some http functions with apiKey protection. Since you want to reuse the same rest api gate way you will refer to the existing one created in the core project.

The micro-service project serverless.yml file would look something like:

service: service-a

provider:
  name: aws
  apiGateway:
    restApiId: ${cf:my-core-stack.ApiGatewayRestApiId}
    restApiRootResourceId: ${cf:my-core-stack.ApiGatewayRestApiRootResourceId}
  apiKeys:
    - my-api-key

functions:
  handler: src/xxx
  events:
    - http:
          path: xxx
          method: get
          private: true

Whenever you deploy service-a it will link your http function with the RestApiGateway previously created in the core project.

But now, when you try to remove the project service-a it will throw the famous exception:

➜ sls remove
Serverless: Removing usage plan association...

  Serverless Error ---------------------------------------

  Resource ApiGatewayRestApi does not exist for stack xxx

The error is not completely wrong in the sense that it does indeed not find ApiGatewayRestApi in this current project because it is created in the core and only referenced here. And thus, when the ApiGatewayRestApi is referenced the removal flow for the api should be done differently!

Currently, the only known workaround is to temporarily comment out the provider.apiKeys parameter and perform the remove again.

Alternative Solution?

I initially tried to create an api key in the core project (since that's where I create the ApiGatewayRestApi). But since there aren't any http functions, the framework doesn't create the api keys. Maybe this could be an alternative solution, as this way I wouldn't need to specify an api key in the service-a project.

Installed version

Framework Core: 1.74.1
Plugin: 3.6.14
SDK: 2.3.1
Components: 2.31.6

Contributor Guide