Error creating custom domain

Hello,

I am trying to add a custom domain to my otherwise working CloudFormation stack deployed using serverless framework. I am using serverless version 3.20.0. The below is working fine:

service: analytic-event-collection

provider:
  name: aws
  stage: ${opt:stage, 'staging'}
  region: ${opt:region, 'us-east-1'}
  runtime: nodejs12.x
  httpApi:
    cors: true
  iam:
    role:
      statements:
        - Effect: 'Allow'
          Action:
            - 'kinesis:PutRecord'
          Resource:
            - '*'

custom:
  # customDomain:
  #   domainName: ${self:provider.stage}-tracking.domain.com
  #   certificateName: '${self:provider.stage}-tracking.domain.com'
  #   basePath: ''
  #   stage: ${self:provider.stage}
  #   apiType: rest
  #   createRoute53Record: true
  kinesisSteamName: 'event-collection-stream-${self:provider.stage}'
  s3AnalyticsStore: 'page-view-store-${self:provider.stage}'
  s3AthenaStore: 's3-analytic-data-${self:provider.stage}'
  glueName: 'analytics-store-${self:provider.stage}'

# plugins:
#   - serverless-domain-manager

functions:
  collect:
    handler: handler.collect
    events:
      - httpApi:
          path: /collect
          method: post
    environment:
      KINESIS_STREAM_NAME: ${self:custom.kinesisSteamName}

resources:
  Resources:
    S3AnalyticsStore:
      Type: AWS::S3::Bucket
      Properties:
        BucketName:  ${self:custom.s3AnalyticsStore}

    KinesisStreamData:
      Type: AWS::Kinesis::Stream
      Properties:
        Name: ${self:custom.kinesisSteamName}
        RetentionPeriodHours: 24
        StreamModeDetails:
          StreamMode: ON_DEMAND

    FirehoseDeliveryIAMPolicy:
      Type: 'AWS::IAM::Policy'
      Properties:
        PolicyName: "EventCollectionPolicy"
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - 's3:AbortMultipartUpload'
                - 's3:GetBucketLocation'
                - 's3:GetObject'
                - 's3:ListBucket'
                - 's3:ListBucketMultipartUploads'
                - 's3:PutObject'
              Resource: 
                - !Join 
                  - ''
                  - - 'arn:aws:s3:::'
                    - !Ref S3AnalyticsStore
                - !Join 
                  - ''
                  - - 'arn:aws:s3:::'
                    - !Ref S3AnalyticsStore
                    - '/*'
            - Effect: Allow
              Action:
                - 'kinesis:DescribeStream'
                - 'kinesis:GetShardIterator'
                - 'kinesis:GetRecords'
              Resource: !GetAtt 
                - KinesisStreamData
                - Arn
        Roles:
          - !Ref FirehoseDeliveryIAMRole
      DependsOn:
        - KinesisStreamData
        - S3AnalyticsStore

    FirehoseDeliveryIAMRole:
      Type: 'AWS::IAM::Role'
      Properties:
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Sid: ''
              Effect: Allow
              Principal:
                Service: firehose.amazonaws.com
              Action: 'sts:AssumeRole'
              Condition:
                StringEquals:
                  'sts:ExternalId': !Ref 'AWS::AccountId'

    KinesisFirehoseDeliveryStream:
      Type: 'AWS::KinesisFirehose::DeliveryStream'
      Properties:
        DeliveryStreamName: !Join 
          - ''
          - - '${self:custom.kinesisSteamName}-'
            - 'deliver'
        DeliveryStreamType: KinesisStreamAsSource
        KinesisStreamSourceConfiguration:
          KinesisStreamARN: !GetAtt 
            - KinesisStreamData
            - Arn
          RoleARN: !GetAtt 
            - FirehoseDeliveryIAMRole
            - Arn
        S3DestinationConfiguration:
          BucketARN: !GetAtt 
            - S3AnalyticsStore
            - Arn
          BufferingHints:
            IntervalInSeconds: 300
            SizeInMBs: 5
          CloudWatchLoggingOptions:
            Enabled: 'false'
          CompressionFormat: GZIP
          EncryptionConfiguration:
            NoEncryptionConfig: NoEncryption
          RoleARN: !GetAtt 
            - FirehoseDeliveryIAMRole
            - Arn
      DependsOn:
        - FirehoseDeliveryIAMPolicy
        - FirehoseDeliveryIAMRole

    S3AthenaStore:
      Type: AWS::S3::Bucket
      Properties:
        BucketName:  ${self:custom.s3AthenaStore}

    AnalysisGlueDatabase:
      Type: AWS::Glue::Database
      Properties:
        CatalogId: !Ref AWS::AccountId
        DatabaseInput:
          Name:  !Join 
            - ''
            - - '${self:custom.glueName}-'
              - 'db'
          Description: "Analysis aws Glue database"
      DependsOn:
        - S3AthenaStore

    AnalyticsGlueRole:
      Type: AWS::IAM::Role
      DependsOn:
        - S3AnalyticsStore
      Properties:
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            -
              Effect: "Allow"
              Principal:
                Service:
                  - "glue.amazonaws.com"
              Action:
                - "sts:AssumeRole"
        Path: "/"
        ManagedPolicyArns:
          ['arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole']
        Policies:
          -
            PolicyName: "S3BucketAccessPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                -
                  Effect: "Allow"
                  Action: 
                    - "s3:GetObject"
                    - "s3:PutObject"
                  Resource: 
                    - !Join
                      - ''
                      - - !GetAtt S3AnalyticsStore.Arn
                        - "*"
  
    AnalyticsGlueCrawler:
      Type: AWS::Glue::Crawler
      Properties:
        Name: "AnalysisCrawler"
        Role: !GetAtt AnalyticsGlueRole.Arn
        DatabaseName: !Ref AnalysisGlueDatabase
        Targets:
          S3Targets:
            - Path: !Ref S3AnalyticsStore
        SchemaChangePolicy:
          UpdateBehavior: "LOG"
          DeleteBehavior: "LOG"
        Schedule:
          ScheduleExpression: "cron(00 0/1 * * ? *)"
        RecrawlPolicy: 
          RecrawlBehavior: CRAWL_NEW_FOLDERS_ONLY
      DependsOn:
        - AnalyticsGlueRole
        - AnalysisGlueDatabase

    AnalyticsAthenaWorkGroup:
      Type: AWS::Athena::WorkGroup
      Properties: 
        Name: ${self:service}-${self:provider.stage}-wg
        WorkGroupConfiguration: 
          ResultConfiguration:
            OutputLocation: 
              !Join
                - ''
                - - 's3://'
                  - !Ref S3AthenaStore
      DependsOn:
        - S3AthenaStore
     
  Outputs:
    AthenaDataStore:
      Description: "Athena Data Store"
      Value: !Ref S3AthenaStore
      Export:
        Name:
          Fn::Sub: "${AWS::StackName}-athena"
      
    AthenaDataStorePath:
      Description: "Athena Data store path"
      Value: !Join
        - ''
        - - 's3://'
          - !Ref S3AthenaStore

    AnalyticData:
      Description: "event data"
      Value: !Ref S3AnalyticsStore
      Export:
        Name:
          Fn::Sub: "${AWS::StackName}-data"

    AnalyticDataDB:
      Description: "Glue Database"
      Value: !Ref AnalysisGlueDatabase
      Export:
        Name:
          Fn::Sub: "${AWS::StackName}-db"

    AthenaWorkGroup: 
      Description: "Athena work group"
      Value: !Ref AnalyticsAthenaWorkGroup
      Export:
        Name:
          Fn::Sub: "${AWS::StackName}-athena-workgroup"

If I uncomment the custom domain part, it errs with:

Error:
Error: Unable to setup base domain mappings for 'staging-tracking.domain.com':
Failed to find CloudFormation resources for 'staging-tracking.domain.com':
Failed to find a stack analytic-event-collection-staging

I am using: serverless-domain-manager@6.0.1. What am I doing wrong?

Thank you

I did more digging. First, create_domain works fine. When I did:

$ SLS_DEBUG=* sls create_domain --verbose
Running "serverless" from node_modules
'staging-tracking.seatmonger.com' does not exist.
Searching for a certificate with the 'staging-tracking.seatmonger.com' domain
Selecting cert with ARN=arn:aws:acm:us-east-1:{AccountId}:certificate/cb844038-...-...-...-21990ef9261d with future expiry (2023-08-10T23:59:59.000Z)
Custom domain 'staging-tracking.domain.com' was created.
                 New domains may take up to 40 minutes to be initialized.
Creating/updating route53 record for 'staging-tracking.domain.com'.

However, when I try to deploy changeset for the entire stack, still errs as before.

Also tried using the new domain, and it does not work.

HTTP/2 403 
content-type: application/json
content-length: 23
date: Wed, 20 Jul 2022 13:19:20 GMT
x-amzn-requestid: d546a71c-....-....-....-67c107a295dc
x-amzn-errortype: ForbiddenException
x-amz-apigw-id: Vk.........Q=
x-cache: Error from cloudfront
via: 1.1 e....8.cloudfront.net (CloudFront)
x-amz-cf-pop: MIA3-C2
x-amz-cf-id: ob....0g==

What is going on?

I’m having this exact same issue with a custom domain for a serverless deploy that worked before adding the custom domain. My serverless.yml looks identical to this, except for my specific values.

Any ideas where the error is?

The one thing I can add is I did poke around inside AWS Cloudformation and noticed that the cloudfront distribution that is an output for the stack (And also for the A and AAAA records that were created for my custom domain by running SLS_DEBUG=* sls create_domain --verbose) is not listed when I go to my global view of all cloudfront distributions for my account.

Why would my root user not be able to see a cloudfront distribution that was created by this serverless stack using the same account?