Cannot access ApiGatewayRestApi in resources

I’m trying to deploy CloudFront together with my function to have the CDN capabilities in front of my API. I do this by adding Cloudfront as a resource to my serverless.yml, and referencing the Origin via the API Gateway Domain:

frameworkVersion: '3'

provider:
  name: aws

resources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Origins:
            - Id: ApiGateway
              DomainName:
                Fn::Join:
                  - "."
                  - - Ref: ApiGatewayRestApi
                    - execute-api
                    - Ref: AWS::Region
                    - amazonaws.com
     ...

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /
          method: get

The problem is that Ref: ApiGatewayRestApi doesn’t work. All I get is an error:

The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template

If I hardcode the ID, the deployment works. How can I access the API Gateway ID within the resources? AFAIK the variable is defined here Serverless Framework - AWS Lambda Guide - AWS Infrastructure Resources and should be available, right?

Hey there. This page in the docs does not directly answer your question but may be what you need to get you in the right direction: Serverless Framework - AWS Lambda Events - API Gateway

Thanks for the hint!

I tried to define the API Gateway as a resource and link it to the provider.apiGateway, but the result is that CloudFront links to the API Gatway I defined in resources and the serverless function still has it’s own API Gateway. How can I make serverless uses also the API Gateway that I defined in resoucers?

service: learning-caching-headers
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs12.x
  apiGateway:
    restApiId:
      'Fn::ImportValue': MyApiGateway-restApiId
    restApiRootResourceId:
      'Fn::ImportValue': MyApiGateway-rootResourceId

resources:
  Resources:
    MyApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: ApiGatewayRestApiName
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Origins:
            - Id: ApiGateway
              DomainName:
                Fn::Join:
                  - "."
                  - - Ref: MyApiGatewayRestApi
                    - execute-api
                    - Ref: AWS::Region
                    - amazonaws.com
         ...
  Outputs:
    apiGatewayRestApiId:
      Value:
        Ref: MyApiGatewayRestApi
      Export:
        Name: MyApiGateway-restApiId
    apiGatewayRestApiRootResourceId:
      Value:
        Fn::GetAtt:
          - MyApiGatewayRestApi
          - RootResourceId
      Export:
        Name: MyApiGateway-rootResourceId

functions:
  hello:
    handler: handler.hello
    memorySize: 128
    events:
      - httpApi:
          path: /
          method: get

Also, why can’t I just reference to the API ID that is generated by serverless? My serverless.yml feels quite complicated.

I got the error! I was using the new HTTP API instead of the REST API. Changing httpApi to http in my function declaration made it work.

service: learning-caching-headers
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs12.x

resources:
  Description: "CloudFormation template for ${self:service}"
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Origins:
            - Id: ApiGateway
              DomainName:
                Fn::Join:
                  - "."
                  - - Ref: ApiGatewayRestApi
                    - execute-api
                    - Ref: AWS::Region
                    - amazonaws.com
    ...

functions:
  hello:
    handler: handler.hello
    memorySize: 128
    events:
      - http:
          path: /
          method: GET

One last question: Is it possible to also reference the httpApi ID in the Cloudformation resource? I tried Ref: AWS::ApiGatewayV2::Api but it didn’t work. I also couldn’t find any reference here Serverless Framework - AWS Lambda Guide - AWS Infrastructure Resources

Also got the HTTP API reference resolved.

resources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Origins:
            - Id: ApiGateway
              DomainName:
                Fn::Join:
                  - "."
                  - - Ref: HttpApi
                    - execute-api
                    - Ref: AWS::Region
                    - Ref: AWS::URLSuffix

functions:
  hello:
    handler: handler.hello
    memorySize: 128
    events:
      - httpApi:
          path: /
          method: GET