Skip to content

SAM Private API Gateway with custom domai name #3771

Open
@cliff-wakefield-superloop

Description

Description

It was announced in April, 2025 that SAM supports Amazon API Gateway Custom Domain Names for private REST APIs.

However, the article only links to how to do this in Cloudformation not SAM.

We have a SAM template that will setup an Amazon API Gateway for private REST APIs, but the custom domain name does not seem to work.

We have read AWS::Serverless::API so many times.

The documentation may not be as up to date as SAM because AWS::Serverless::API -> Properties -> Domain -> EndpointConfiguration doesn't mention an allowed value of PRIVATE.

It feels like we are missing a property or something but cannot determine what it is from the documentation.

We are also unable to find any examples of this specific combination of features.

Steps to reproduce

  API:
    Type: AWS::Serverless::Api
    Properties:
      AccessLogSetting:
        DestinationArn: !GetAtt APILogGroup.Arn
        Format: "$context.identity.sourceIp - $context.identity.caller - [$context.requestTime] \"$context.httpMethod $context.path $context.protocol\" $context.status $context.responseLength $context.requestId"
      Auth:
        ResourcePolicy:
          IntrinsicVpceWhitelist:
            - Fn::ImportValue:
                !Sub "${VPCEndpointCloudformationExportNamespace}-APIVPCEndpoint"
      Domain:
        CertificateArn: !Ref AcmCertificateArn
        DomainName: !Sub "${ApplicationName}-${AnexEnvironment}.${AcmCertificateDomain}"
        EndpointConfiguration: PRIVATE
        Route53:
          HostedZoneName: !Sub "${AcmCertificateDomain}."
        Policy:
          Fn::ToJsonString:
            Version: 2012-10-17
            Statement:
              - Action: 'execute-api:Invoke'
                Effect: Allow
                Principal: '*'
                Resource: 'execute-api:/*'
              - Action: 'execute-api:Invoke'
                Condition:
                  StringNotEquals:
                    'aws:SourceVpce': 
                      Fn::ImportValue:
                        !Sub "${VPCEndpointCloudformationExportNamespace}-APIVPCEndpoint"
                Effect: Deny
                Principal: '*'
                Resource: 'execute-api:/*'
        SecurityPolicy: !Ref SecurityPolicy
      EndpointConfiguration:
        Type: PRIVATE
        VpcEndpointIds:
          - Fn::ImportValue:
              !Sub "${VPCEndpointCloudformationExportNamespace}-APIVPCEndpoint"
      StageName: Prod
      TracingEnabled: 
        Fn::If:
          - TracingEnabled
          - True
          - False
      MethodSettings:
        - ResourcePath: "/*"
          DataTraceEnabled: true
          HttpMethod: "*"
          LoggingLevel: "INFO"
          MetricsEnabled: true

Observed result

When SAM deploy submits the changeset we get back the following error.

Error: Failed to create changeset for the stack: sam-app-test, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: [/Resources/RecordSetGroup0722ed42d5/Type/RecordSets/0/AliasTarget/HostedZoneId] 'null' values are not allowed in templates

SAM validate picks up a few things but it's not clear what exactly it is tellingus

[[E1031: ToJsonString validation of parameters] (Fn::ToJsonString is not supported without 'AWS::LanguageExtensions' transform) matched 83, [E3003: Required Resource properties are missing] ('HostedZoneId' is a required property) matched 83, [E3003: Required Resource properties are missing] ('DNSName' is a required property) matched 83]
Error: Linting failed. At least one linting rule was matched to the provided template.

Expected result

That the necessary resources are created

  • Custom domain name
  • API Mapping
  • Domain name access association

Additional environment details

  1. OS: MacOS
  2. SAM CLI 1.138.0
  3. AWS region: ap-southeast-2

Metadata

Metadata

Assignees

No one assigned

    Labels

    stage/needs-triageAutomatically applied to new issues and PRs, indicating they haven't been looked at.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions