How to link custom domain name to multi region api gateway? - amazon-web-services

I have created a hosted zone resource via cloudformation. Now i want to create an api gateway via same template in two regions, say us-east-1 and us-west-1 .
customDomain:
Type: AWS::Route53::HostedZone
Properties:
Name: 'example.com'
I understand , i will have to create ssl certificate in both regions. so i have created another stack below. but how do i link , my example.com to api gateway on both the regions.
the error i'm getting now , if i deploy the stack below to second region is - create failed for Mycustomdomainconfig => "The domain name you provided already exists. (service: ApiGateway, ...Status Code 400...
Resources:
MyCertificate:
Type: "AWS::CertificateManager::Certificate"
Properties:
DomainName: example.com
ValidationMethod: DNS
DomainValidationOptions:
- DomainName: 'example.com'
HostedZoneId: 'abcde'
Myrecord:
Type: AWS::Route53::RecordSet
Properties:
Region: !Ref aws_region
SetIdentifier: !Sub "endpoint-${aws_region}"
HostedZoneId: 'abcde'
Name: 'example.com'
Type: A
AliasTarget:
DNSname: !GetAtt Mycustomdomainconfig.RegionalDomainName
HostedZoneId: !GetAtt Mycustomdomainconfig.RegionalHostedZoneId
Mycustomdomainconfig:
Type: AWS::ApiGateway::DomainName
Properties:
RegionalCertificationArn: !Ref MyCertificate
DomainName: 'example.com'
...
MyApiMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
DomainName: !Ref Mycustomdomainconfig
RestApiId: !Ref MyApi
...
MyApi:
Type: AWS::Serverless::Api
Properties:
....

Related

Certificate errors when using a custom domain for an AWS websocket API Gateway (using CloudFormation)

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

How to set up Custom Domain names with Route53 in AWS SAM Cloud-Formation

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.

Creating a CNAME AWS RecordSet/Custom Domain connection to an API in SAM

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.

CloudFormation fails with Route53 RecordSet and ApiGatewayV2 Domain

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?

AWS cfn resource creation failed for recordset

I wanted to deploy a static website using cloudformation but I am having issues creating the record set. The stack creation was successful until the hosted zone in resource section. I'm not sure why there is an issue creating the record set for a hosted zone.
Error: The following resource(s) failed to create: [RecordSet].
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Assuming that you already have a Hosted Zone registered with Amazon Route 53, this Cfn template is to create a static site'
# Metadata:
# 'AWS::CloudFormation::Interface':
# ParameterGroups:
# - Label:
# default: 'HostedZone name'
# Parameters:
# - HostedZoneName
Parameters:
HostedZoneName:
Description: "The DNS name of an existing Amazon Route 53 hosted zone"
Type: String
AllowedPattern: "(?!-)[a-zA-Z0-9-.]{1,63}(?<!-)"
Default: "thecloudcrew.net"
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicRead
BucketName: !Ref HostedZoneName
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
LoggingConfiguration:
DestinationBucketName: !Ref S3LoggingBucket
LogFilePrefix: logs
WWWS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub
- www.${domain}
- { domain: !Ref HostedZoneName}
WebsiteConfiguration:
RedirectAllRequestsTo:
HostName: !Ref HostedZoneName
S3LoggingBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub
- ${domain}.logs
- { domain: !Ref HostedZoneName}
AccessControl: LogDeliveryWrite
HostedZone:
Type: "AWS::Route53::HostedZone"
Properties:
HostedZoneConfig:
Comment: "My Hosted zone for thecloudcrew.net"
HostedZoneTags:
-
Key: Name
Value: thecloudcrew
Name: !Ref HostedZoneName
RecordSet: #FIXME
Type: "AWS::Route53::RecordSet"
Properties:
AliasTarget:
DNSName: s3-website.us-east-2.amazonaws.com
HostedZoneId: Z2O1EMRO9K5GLX
Comment: "RecordSet for static website"
HostedZoneId: !Ref HostedZone #TODO
Name: !Ref HostedZone
Type: A
#Region: 'us-east-2'
# SetIdentifier: String
# TTL: String
# Weight: Integer
You're missing the Type: A property, you have to replace HosteZoneName by HostedZoneId. Also, remove Region it has no use in Route53 which is global.