This is a simple one but I kept getting stuck trying to figure it out. My brain was blocked on it. I’m sharing the pattern here in case you had the same problem.
All I needed was a Route 53 Hosted Zone with an alias record for an Application Load Balancer. I needed these defined in a CloudFormation template. Here’s how to do it:
--- AWSTemplateFormatVersion: '2010-09-09' Parameters: VpcId: Type: AWS::EC2::VPC::Id Subnets: Type: List<AWS::EC2::Subnet::Id> Resources: HostedZone: Type: AWS::Route53::HostedZone Properties: Name: demo-zone.internal VPCs: - VPCId: !Ref VpcId VPCRegion: !Ref 'AWS::Region' LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: IpAddressType: ipv4 Name: demo-lb Scheme: internal Subnets: !Ref Subnets LoadBalancerAlias: Type: AWS::Route53::RecordSet Properties: AliasTarget: DNSName: !GetAtt LoadBalancer.DNSName HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID HostedZoneId: !Ref HostedZone Name: friendly-name.demo-zone.internal Type: A
These were two details that got me.
First, you need a different
HostedZoneId in each of two places:
- In the
AliasTargetof the record. This is not the ID of the zone where you’re creating the record. All ALBs automatically get a DNS name. Like this:
internal-demo-lb-XXXXXXXXXX.us-west-2.elb.amazonaws.com. As far as I understand, you need the ID of the zone where that automatic record lives. AWS manages that zone, so it won’t appear anywhere in your infrastructure. You get its ID from a property on the ALB resource:
- In the root
Propertiesof the record. This is the ID of the zone where you’re creating the record.
Second, you need an A record (type), not a CNAME record.
Route 53 alias records are an AWS-specific technology, but they’re still aliases. CNAMEs are the native DNS aliases, so I expected Route 53 aliases to be an extension of that type. Nope! Aliases of ALBs are A records.
I think the detail is that aliases point directly to the IP addresses of the load balancer, there’s no chained DNS resolution like there is with CNAMEs. That makes them effectively magic A records. The magic is that AWS keeps them up to date with the dynamically changing IPs of load balancers.
Check out these related posts: