What's the normal/usual serverless framework way of using UsagePlan & ApiKey

How are people setting up Usage Plans

Background: We’ve pretty quickly hit the “Usage plans per API key” default limit of 10. I’m trying to understand if we’ve hit the limit because we’re doing something atypical, or if there’s a better way to control how different Consumers (Public/Partner/Private) can have usage of our API’s managed (rate limiting, quotas etc), and understand if there’s assumptions serverless makes about ApiKeys and usage plans.

  • AWS docs imply that the way they expect Usage plan’s to be used is that you would have a single UsagePlan across multiple “stages”.
  • The current support in serverless for both Usage Plans and API keys seems to assume that they will be created and managed by each individual service, is that correct?

We currently setup a usage plan in each service referencing the PUBLIC_API_KEY_ID of an existing ApiKey:

  ServiceUsagePlan:
    Type: "AWS::ApiGateway::UsagePlan"
    DependsOn: pathmapping
    Properties:
      UsagePlanName: ${self:custom.env.SERVICE_INSTANCE_NAME}
      ApiStages:
        - ApiId:
            Ref: ApiGatewayRestApi
          Stage: ${self:custom.env.STAGE}

  ServiceUsagePlanKey:
    Type: "AWS::ApiGateway::UsagePlanKey"
    DependsOn: ServiceUsagePlan
    Properties :
      # Depending on which stage, will reference ID of PubProd, PubStaging or PubDev
      KeyId: ${self:custom.env.PUBLIC_API_KEY_ID}
      KeyType: API_KEY
      UsagePlanId:
        Ref: ServiceUsagePlan

Currently

If we need to expose API’s to different consuming partners we need to have multiple usage plans in each instance of a service, as mentioned in this issue

Across mutliple services this broadly ends up looking like this:

This isn’t terrible but there’s a couple of frustrating things with it:

  • Because the usage plans in each service get assigned shared API Keys, the number of services directly corresponds to how quickly you hit the “Usage plans per API key” limit (10 services means you hit the default limit).
    • We could make each service also own it’s API keys but then we wouldn’t be able to give a single Api Key to a partner or have the public cloudfront adding the PubProd key to the x-api-header (Allowing us to use throttling or quotas).
  • Managing a specific partners usage of different API’s is done across many UsagePlans, spread across many services.

Ideally

I have a feeling I know that the answer is that Cloudformation doesn’t support it, but What I think would be ideal is if we could make each instance of a service associate itself with a shared UsagePlan. In a similar way to what we’re currently doing with the API Keys, but as far as I can tell there’s no equivalent of AWS::ApiGateway::UsagePlanKey (something like a AWS::ApiGateway::UsagePlanStage association).

It’d look something like this Imgur: The magic of the Internet (I can’t embed more than one image here)

This would be nice because

  • For a Partner’s UsagePlan we could configure throttling across all of our API’s from a single usage plan.
  • Could still set throttling for each Associated API stage in the UsagePlan by using “Method Throttling”.

Great write up and description of your issue. So you’re right about the shared usage plans. There is a limit of 10 Usage Plans per API Key, but I’m not aware of a limit to the number of stages that can be associated with a Usage Plan.

I have a use case for a client that is similar in that they share an API key across multiple services. But we use a single Usage Plan associated with multiple services/stages and then just associate the API Key with that Usage Plan. I’m not sure of the CloudFormation support, but we use the API directly to create and associate keys instead of relying on the Serverless Framework to do it.

1 Like