I am creating custom domain for api gateway using yaml. Here is my sample yaml.
TestAppApi:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref ApiStageName
EndpointConfiguration: REGIONAL
TracingEnabled: TRUE
MethodSettings:
- LoggingLevel: INFO
ResourcePath: "/*" # allows for logging on any resource
HttpMethod: "*" # allows for logging on any method
DataTraceEnabled: TRUE
DomainName:
Type: AWS::ApiGateway::DomainName
Properties:
RegionalCertificateArn: !Ref Certificate
DomainName: !Ref ApiDomain
SecurityPolicy: TLS_1_2
EndpointConfiguration:
Types:
- REGIONAL
UrlMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- TestAppApiStage
- DomainName
Properties:
DomainName:
!Ref ApiDomain
RestApiId:
Ref: TestAppApi
Stage: !Ref ApiStageName
Domain:
Type: AWS::Route53::RecordSetGroup
DependsOn:
- TestAppApi
- UrlMapping
- DomainName
Properties:
HostedZoneId: !Ref ApiDomainHostedZoneId
RecordSets:
- Name: !Ref ApiDomain
Type: A
AliasTarget:
DNSName: !GetAtt DomainName.RegionalDomainName
HostedZoneId: !GetAtt DomainName.RegionalHostedZoneId
I am passing ApiDomain as parameter and it works as expected when my ApiDomain is 'dev.test.com.au' where test.com.au is my registered domain. But if I change my ApiDomain to something like 'dev-$env:USERNAME.test.com.au' and then I get the following error.
Invalid domain name identifier specified(Service:AmazonApiGateway;Status Code: 404;
Error Code: NotFoundException;Request ID: fbf8ce40-cce0-4a0f-9714-c649d35a3ee4; Proxy: null)
Apparently this error has something to do with the dependency issue according to this thread https://github.com/aws/serverless-application-model/issues/192# but it works with one name but not the other. And anyways I have added all the dependencies and still invalid domain name identifier error.
Any help will be appreciated!
Don't have capital letters in your domain name people. My ApiDomain parameter has capital letters. Domain name creation automatically converts it to lower letters. But baseurlmapping is left to find ApiDomain with capital letter and hence the issue. Needed to read documentation more clearly but anyhow posting it here in case somebody experiences this silly issue.
Related
I've been having some trouble setting up my a custom domain for my websocket API Gateway in AWS. I keep getting certificate errors. I have a certificate setup already, and some cloud formation scripts. That look right. Everything deploys correctly, but I keep getting this error about certificates.
$ wscat -c ws.example.com
error: Hostname/IP does not match certificate's altnames: Host: ws.example.com. is not in the cert's altnames: DNS:*.execute-api.us-east-1.amazonaws.com
I checked the certificate it's returning, and the serial number does not match the certificate I've created in ACM.
Here's my CloudFormation script:
WebsocketApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: !Sub ${Environment}-ips-ws-api
ProtocolType: WEBSOCKET
RouteSelectionExpression: $request.body.action
ApiKeySelectionExpression: $request.header.x-api-key
WebsocketStage:
Type: AWS::ApiGatewayV2::Stage
Properties:
ApiId: !Ref WebsocketApi
Description: Websocket Api Stage
StageName: base
AutoDeploy: true
WebsocketDomainName:
Type: AWS::ApiGatewayV2::DomainName
Properties:
DomainName: !Ref WebsocketDomain
DomainNameConfigurations:
- CertificateArn: !Ref WebsocketCertificateArn
SecurityPolicy: TLS_1_2
EndpointType: REGIONAL
WebsocketDomainMapping:
Type: AWS::ApiGatewayV2::ApiMapping
Properties:
ApiId: !Ref WebsocketApi
ApiMappingKey: base
DomainName: !Ref WebsocketDomainName
Stage: !Ref WebsocketStage
WebsocketDnsRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZoneId
Name: !Ref WebsocketDomain
Type: CNAME
AliasTarget:
DNSName: !GetAtt WebsocketDomainName.RegionalDomainName
EvaluateTargetHealth: false
HostedZoneId: !GetAtt WebsocketDomainName.RegionalHostedZoneId
Let me know if there's I'm missing some infromation.
Any help would be appreciated, been wracking my brain over this for a while.
Are you missing the protocal when using wscat ? You should use it like :
wscat -c wss://socketserve.example.com
I am trying to use CloudFormation to deploy API Gateway with VPC Link and NLB. The Goal is to proxy pass all requests to the NLB:
NLB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Type: "network"
IpAddressType: "ipv4"
Name: !Ref NLBName
Scheme: "internal"
# LoadBalancerAttributes:
# - LoadBalancerAttribute
Subnets:
- !Ref NLBSubnetApNortheast1a
- !Ref NLBSubnetApNortheast1c
- !Ref NLBSubnetApNortheast1d
... other code ...
ApiProxyMethod:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref ApiGatewayRestApi
ResourceId: !Ref ApiProxyResource
AuthorizationType: COGNITO_USER_POOLS
AuthorizerId: !Ref ApiAuthorizer
HttpMethod: ANY
OperationName: "ProxyAllRequests"
Integration:
ConnectionType: VPC_LINK
ConnectionId: !Ref ApiGatewayVpcLink
IntegrationHttpMethod: ANY
# PassthroughBehavior: String
Type: "HTTP" # Member must satisfy enum value set: [HTTP, AWS_PROXY, HTTP_PROXY, AWS]
Uri: !Sub
- 'http://${DNSName}/{proxy}'
- DNSName: !GetAtt NLB.DNSName
# DNSName: The DNS name for the load balancer. For example, my-load-balancer-424835706.us-west-2.elb.amazonaws.com
And when I try to run this, I get this error:
Error Detail:
1 validation error detected: Value 'Invalid method setting path:
null/null/logging/dataTrace. Must be one of: [/deploymentId,
/description, /cacheClusterEnabled, /cacheClusterSize,
/clientCertificateId, /accessLogSettings,
/accessLogSettings/destinationArn, /accessLogSettings/format,
/{resourcePath}/{httpMethod}/metrics/enabled,
/{resourcePath}/{httpMethod}/logging/dataTrace,
/{resourcePath}/{httpMethod}/logging/loglevel,
/{resourcePath}/{httpMethod}/throttling/burstLimit/{resourcePath}/{ht
tpMethod}/throttling/rateLimit/{resourcePath}/{httpMethod}/caching/t
tlInSeconds, /{resourcePath}/{httpMethod}/caching/enabled,
/{resourcePath}/{httpMethod}/caching/dataEncrypted, /{resourcePath}/{httpMethod}/caching/requireAuthorizationForCacheControl,
/{resourcePath}/{httpMethod}/caching/unauthorizedCacheControlHeaderStrategy, /*/*/metrics/enabled, /*/*/logging/dataTrace,
/*/*/logging/loglevel, /*/*/throttling/burstLimit
/*/*/throttling/rateLimit /*/*/caching/ttlInSeconds,
/*/*/caching/enabled, /*/*/caching/dataEncrypted,
/*/*/caching/requireAuthorizationForCacheControl,
/*/*/caching/unauthorizedCacheControlHeaderStrategy,
/variables/{variable_name}, /tracingEnabled] (Service: ApiGateway,
Status Code: 400, Request ID: 748f725f-fa59-4885-9058-9d4d17722d5e,
Extended Request ID: null)' at 'statusMessage' failed to satisfy
constraint: Member must have length less than or equal to 1024
I was able to located the source of the error to be AWS::ApiGateway::Method, and it seems that the Uri is not right.
When I change the Uri to be "http://NLB-myapp-internal-beta-123.elb.ap-northeast-1.amazonaws.com/{proxy}", things work just fine.
I tried to search for the error message, but there is no clue.
what could be the cause? What does the error message mean?
I think it just should be:
Type: HTTP_PROXY
Uri: !Sub "http://${NLB.DNSName}"
You don't need any {proxy} there.
ORIGINAL QUESTIONS: How to get RegionalDomainName out of a AWS APIGateway DomainName in SAM Cloud-formation
EDIT: I changed the question to hopefully get more traffic to this answer as it answers several questions not just my original one.
I am getting the following error when I try and deploy my stack:
resource DomainName does not support attribute type regionalDomainName in Fn::GetAtt
My yml file looks like the following:
PublicApi:
Type: AWS::Serverless::Api
Properties:
Name: PublicApi
...
EndpointConfiguration: REGIONAL
DomainName:
Type: AWS::ApiGateway::DomainName
Properties:
RegionalCertificateArn: "arn:aws:acm:${Region}:XXXXXXXXXXX:certificate/XXXXXXXXXXXXX"
DomainName: !Sub ${Stage}.${name}
EndpointConfiguration:
Types:
- REGIONAL
myDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId : Z1UJRXOUMOOFQ8
Name: !Sub ${Stage}.${name}
AliasTarget:
HostedZoneId: Z1UJRXOUMOOFQ8
DNSName: !GetAtt DomainName.regionalDomainName
Type: A
UrlMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- PublicApi
Properties:
DomainName: !Ref DomainName
RestApiId: !Ref PublicApi
Stage: !Ref Stage
The following is from the DomainName documentation:
"RegionalDomainName
The domain name associated with the regional endpoint for this custom domain name. You set up this association by adding a DNS record that points the custom domain name to this regional domain name."
I am confused as to what I need to do to make this DomainName Regional.
I have also been getting the following Errors in different iterations, that I thought this should fix:
"Cannot import certificates for EDGE while REGIONAL is active."
Any help on this front would be much appreciated!
I found from several different forums different solutions to different problems and finally came up with a working model. I hope this helps someone out in the future.
PublicApi:
Type: AWS::Serverless::Api
Properties:
Name: PublicApi
StageName: ApiStage
...
EndpointConfiguration: REGIONAL
DomainName:
Type: AWS::ApiGateway::DomainName
Properties:
RegionalCertificateArn: "arn:aws:acm:u${Region}:XXXXXXXX:certificate/XXXXXXXX"
DomainName: stage.example.com
SecurityPolicy: TLS_1_2
EndpointConfiguration:
Types:
- REGIONAL
LambdaDNS:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName:
Ref: example.com.
RecordSets:
- Name:
Fn::Sub: stage.example.com.
Type: A
AliasTarget:
HostedZoneId: Z1UJRXOUMOOFQ8
DNSName:
Fn::GetAtt:
- DomainName
- RegionalDomainName
UrlMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- PublicApi
- PublicApiStage
Properties:
DomainName:
Ref: DomainName
RestApiId:
Ref: PublicApi
Stage: ApiStage
The key bit for me ended up being the DependsOn in the BasePathMapping.
I am trying to use Route53 and Custom Domains to link a URL I have and the API gateway that is a Lambda Proxy underneath it.
This is what I have so far in my SAM file:
MyApiCertificate:
Type: 'AWS::CertificateManager::Certificate'
Properties:
DomainName: example.com
MyApiDomainName:
Type: 'AWS::ApiGateway::DomainName'
Properties:
RegionalCertificateArn: !Ref MyApiCertificate
DomainName: example.com
MyApiBasePathMapping:
Type: 'AWS::ApiGateway::BasePathMapping'
Properties:
RestApiId: !Ref PublicApi
DomainName: !Ref MyApiDomainName
BasePath: /
Stage: stage
MyApiRoute53RecordSetGroup:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: example.com
RecordSets:
- Name: example.com
Type: A
AliasTarget:
EvaluateTargetHealth: false
HostedZoneId: !GetAtt MyApiDomainName.DistributionHostedZoneId
DNSName: !GetAtt MyApiDomainName.DistributionDomainName
I would like to make this of type CNAME and have the URL be stage.example.com
The following Code does not work.
MyApiCertificate:
Type: 'AWS::CertificateManager::Certificate'
Properties:
DomainName: example.com
MyApiDomainName:
Type: 'AWS::ApiGateway::DomainName'
Properties:
RegionalCertificateArn: !Ref MyApiCertificate
DomainName: example.com
MyApiBasePathMapping:
Type: 'AWS::ApiGateway::BasePathMapping'
Properties:
RestApiId: !Ref PublicApi
DomainName: !Ref MyApiDomainName
BasePath: /
Stage: stage
MyApiRoute53RecordSetGroup:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: example.com
RecordSets:
- Name: stage.example.com
Type: CNAME
AliasTarget:
EvaluateTargetHealth: false
HostedZoneId: !GetAtt MyApiDomainName.DistributionHostedZoneId
DNSName: !GetAtt MyApiDomainName.DistributionDomainName
I am getting this error: Cannot import certificates for REGIONAL while EDGE is active. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: XXXXXXXXXXXXXXXXXXXXXXXX)
Although nothing I have is an EDGE Api Gateway and Nothing has the name I want (Stage.example.com)
Any help on this issue would be appreciated!
I came across the same error using Terraform, and the issue was that I was specifying regional_certificate_arn rather than certificate_arn. API Gateway defaults to edge-optimized, which means you're specifying a RegionalCertificateArn with an edge-optimized API here - try using CertificateArn instead.
I am using Serverless to create a WebSocket API with AWS. I have added the following additional CloudFormation resources inside the serverless.yml file:
Resources:
ApiGatewayDomain:
Type: AWS::ApiGatewayV2::DomainName
Properties:
DomainName: ${opt:id}.example.com
DomainNameConfigurations:
- EndpointType: REGIONAL
CertificateArn: arn:aws:acm:eu-central-1:<REDACTED>:certificate/<REDACTED>
ApiGatewayBasePathMapping:
Type: AWS::ApiGatewayV2::ApiMapping
Properties:
DomainName: # ${opt:id}.example.com
Ref: ApiGatewayDomain
ApiId:
Ref: "WebsocketsApi"
Stage: ${opt:stage, 'dev'}
DependsOn:
- WebsocketsDeployment${sls:instanceId}
- WebsocketsDeploymentStage
Route53RecordSet:
Type: AWS::Route53::RecordSet
Properties:
Type: A
HostedZoneId: <REDACTED>
Name:
Ref: ApiGatewayDomain
AliasTarget:
DNSName: # <REDACTED>.execute-api.eu-central-1.amazonaws.com.
Fn::Join:
- ""
-
- Fn::GetAtt: [ApiGatewayDomain, RegionalDomainName]
- "."
HostedZoneId: # Z1U9ULNL0V5AJ3
Fn::GetAtt: [ApiGatewayDomain, RegionalHostedZoneId]
DependsOn:
- ApiGatewayDomain
I want to achieve, that the deployment of a stack registers a custom api gateway domain (works), sets up the path mapping (works) and adds a Route53RecordSet (only works with concrete values).
I cannot figure out what I am doing wrong and always get an internal error from Route53. If I comment out the Fn::Join and Fn::GetAtt blocks for DNSName and HostedZoneId and use concrete values, everything works as expected. Am I missing something or is this simply an error with CloudFormation and Route53?