Serverless: How to share the ids of an existing API Gateway

The serverless documentation indicates how to share the ids of an API Gateway, but the technique described there seems to work only for a new deployment. (In my case, following this technique created a 2nd empty API Gateway whose ids were shared, which was, unsurprisingly, not fulfilling my needs).

Here is how to do it for an existing deployment.

Find the deployment manifest for your existing stack in CloudFormation, or generate it with serverless by running: sls package <your parameters>. Then the file is under .serverless/cloudformation-template-update-stack.json. Open it.

Look for the ApiGateway root resource definition. In my case, it’s a REST API so it can be found by searching for "Type": "AWS::ApiGateway::RestApi" (It’s probably something like AWS::ApiGateway::Http for an Http API.)

"ApiGatewayRestApi": {
  "Type": "AWS::ApiGateway::RestApi",
  "Properties": {
    "Name": "prod-api",
    "EndpointConfiguration": {
      "Types": [
        "REGIONAL"
      ]
    },
    "Policy": ""
  }
},

The value to note here is the name of the key of this blob: ApiGatewayRestApi.

We can go back to the serverless documentation and do only the Outputs portion using this reference value.

Outputs:
    apiGatewayRestApiId:
      Value:
        Ref: ApiGatewayRestApi
      Export:
        Name: MyApiGateway-restApiId
 
    apiGatewayRestApiRootResourceId:
      Value:
        Fn::GetAtt:
          - ApiGatewayRestApi
          - RootResourceId
      Export:
        Name: MyApiGateway-rootResourceId

WARNING: This approach may be fragile. If it turns out to be technically possible to change the variable name of an existing stack, a serverless update could break this configuration.

Authorizers

You can also reuse authorizers with the same technique. In the main stack, export the reference to your authorizer. You can find it by searching for "Type": "AWS::ApiGateway::Authorizer". The value you are looking for is the key of the blob. Then, in the stack where you want to reuse it, add this under routes:

functions:
  my_route:
    ...
    events:
    - http:
        ...
        authorizer:
          type: <type> # it's required, otherwise the deployment will fail
          authorizerId:
            'Fn::ImportValue': <référence à la valeur à importer>

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.