- Go ahead and create a new CloudFormation template. We'll add some Parameters for the items we've mentioned previously:
Parameters:
DomainName:
Description: Your domain name (example.org)
Type: String
LoadBalancerDNSNameRegionA:
Description: The DNS name of your ELB in region A
Type: String
LoadBalancerHostedZoneRegionA:
Description: The Hosted Zone ID of your ELB in region A
Type: String
LoadBalancerDNSNameRegionB:
Description: The DNS name of your ELB in region B
Type: String
LoadBalancerHostedZoneRegionB:
Description: The Hosted Zone ID of your ELB in region B
Type: String
- The first Resource we want is the HostedZone resource for our domain name. Add it to your template as follows:
Resources:
DNSHostedZone:
Type: AWS::Route53::HostedZone
Properties:
Name: !Ref DomainName
- In order to have failover happen automatically, we're going to need to set up some health checks. We want health checks on the ELBs in both regions:
RegionAHealthCheck:
Type: AWS::Route53::HealthCheck
Properties:
HealthCheckConfig:
FailureThreshold: 3
FullyQualifiedDomainName: !Ref LoadBalancerDNSNameRegionA
Port: 80
RequestInterval: 30
ResourcePath: "/"
Type: HTTP
HealthCheckTags:
- { Key: Name, Value: Region A Health Check }
RegionBHealthCheck:
Type: AWS::Route53::HealthCheck
Properties:
HealthCheckConfig:
FailureThreshold: 3
FullyQualifiedDomainName: !Ref LoadBalancerDNSNameRegionB
Port: 80
RequestInterval: 30
ResourcePath: "/"
Type: HTTP
HealthCheckTags:
- { Key: Name, Value: Region B Health Check }
- We're now going to create four record sets for your domain:
- a.<your-domain>-PRIMARY
- b.<your-domain>-PRIMARY
- a.<your-domain>-SECONDARY (failover to b)
- b.<your-domain>-SECONDARY (failover to a)
- These records correspond to ELB A and ELB B (or site A and B, if that term makes more sense to you), and they will allow each region to fail over to the other if the health check fails.
- Let's start with the primary records for both ELBs:
RegionAPrimary:
Type: AWS::Route53::RecordSet
Properties:
Name: !Join [ ., [ a, Ref: DomainName ] ]
Type: A
HostedZoneId: !Ref DNSHostedZone
AliasTarget:
HostedZoneId: !Ref LoadBalancerHostedZoneRegionA
DNSName: !Ref LoadBalancerDNSNameRegionA
Failover: PRIMARY
SetIdentifier: primary-region-a
HealthCheckId: !Ref RegionAHealthCheck
RegionBPrimary:
Type: AWS::Route53::RecordSet
Properties:
Name: !Join [ ., [ b, Ref: DomainName ] ]
Type: A
HostedZoneId: !Ref DNSHostedZone
AliasTarget:
HostedZoneId: !Ref LoadBalancerHostedZoneRegionB
DNSName: !Ref LoadBalancerDNSNameRegionB
Failover: PRIMARY
SetIdentifier: primary-region-b
HealthCheckId: !Ref RegionBHealthCheck
- Now add the secondary (failover) records:
RegionAFailover:
Type: AWS::Route53::RecordSet
Properties:
Name: !Join [ ., [ a, Ref: DomainName ] ]
Type: A
HostedZoneId: !Ref DNSHostedZone
AliasTarget:
HostedZoneId: !Ref LoadBalancerHostedZoneRegionB
DNSName: !Ref LoadBalancerDNSNameRegionB
Failover: SECONDARY
SetIdentifier: secondary-region-a
RegionBFailover:
Type: AWS::Route53::RecordSet
Properties:
Name: !Join [ ., [ b, Ref: DomainName ] ]
Type: A
HostedZoneId: !Ref DNSHostedZone
AliasTarget:
HostedZoneId: !Ref LoadBalancerHostedZoneRegionA
DNSName: !Ref LoadBalancerDNSNameRegionA
Failover: SECONDARY
SetIdentifier: secondary-region-b
- Now we're going to add the root/apex record for our domain. For the purposes of this recipe, we're going to send requests originating from North America to region/ELB A, and requests from the rest of the world to region/ELB B:
NorthAmericaGeolocation:
Type: AWS::Route53::RecordSet
Properties:
Name: !Ref DomainName
Type: A
HostedZoneId: !Ref DNSHostedZone
AliasTarget:
HostedZoneId: !Ref DNSHostedZone
DNSName: !Join [ ., [ a, Ref: DomainName ] ]
GeoLocation:
ContinentCode: NA # North America
SetIdentifier: geolocation-region-a
RestOfWorldGeolocation:
Type: AWS::Route53::RecordSet
Properties:
Name: !Ref DomainName
Type: A
HostedZoneId: !Ref DNSHostedZone
AliasTarget:
HostedZoneId: !Ref DNSHostedZone
DNSName: !Join [ ., [ b, Ref: DomainName ] ]
GeoLocation:
CountryCode: "*" # Rest of world
SetIdentifier: geolocation-region-b
- That's it! You can now run this CloudFormation template in the AWS web console or via the CLI, as follows:
aws cloudformation create-stack \
--stack-name geolocation-failover \
--template-body file://07-routing-based-on-location.yaml \
--parameters \
ParameterKey=DomainName,ParameterValue=gitrepository.com \
ParameterKey=LoadBalancerDNSNameRegionA,ParameterValue=<elb-a> \
ParameterKey=LoadBalancerHostedZoneRegionA, \
ParameterValue=<elb-zoneid-a> \
ParameterKey=LoadBalancerDNSNameRegionB,ParameterValue=<elb-b> \
ParameterKey=LoadBalancerHostedZoneRegionB, \
ParameterValue=<elb-zoneid-b>