Definition
- CNAME record – a DNS record that maps one domain name to another; the resolver does a second lookup to get the actual IP, and DNS rules forbid a CNAME at the zone apex.
- Route 53 alias record – an AWS-specific extension that maps a name directly to an AWS resource's IP addresses inside Route 53; allowed at the zone apex, free for AWS resource queries, and tracks changing IPs automatically.
- Zone apex – the naked domain like
bank.example.comwith no subdomain prefix (nowww). - Supported alias targets – ALB, NLB, CloudFront, S3 website endpoint, API Gateway, and another Route 53 record in the same zone.
Imagine bank.example.com is the public name of National Bank of India. A CNAME is like telling a customer "to reach the internet banking desk, first call the central directory, and they will give you another number to call, and only then will you reach a counter." It is an extra hop. An alias record is like the directory knowing the actual counter numbers directly, so when Rajesh asks for internet banking it gives him the real numbers in one step, and if the bank adds or removes counters, the directory is updated automatically.
Understanding the Concepts
Why can't you use a fixed IP for an ALB?
An Application Load Balancer does not give you a fixed IP address; it gives you a DNS name like my-alb-123456.ap-south-1.elb.amazonaws.com, and the IP addresses behind that name change over time as AWS scales the load balancer. So you must map your friendly domain to that DNS name, not to an IP.
// ALB provides a DNS name, not a static IP
package com.bank.infrastructure;
public class AlbDnsExplainer {
private static final String ALB_DNS = "my-alb-123456.ap-south-1.elb.amazonaws.com";
public static void main(String[] args) {
System.out.println("ALB DNS name: " + ALB_DNS);
System.out.println("IPs behind this name CHANGE as AWS scales the ALB.");
System.out.println("You must point your domain to this name, not to an IP.");
}
}
What is a CNAME record and what are its limits?
A CNAME record tells DNS that www.bank.example.com is an alias for the ALB's DNS name. When a client resolves www.bank.example.com, the resolver gets the CNAME, then does a second resolution to finally get an IP. This works, but it has two limits. First, DNS rules forbid a CNAME at the zone apex, so you cannot put a CNAME on the naked bank.example.com. Second, the extra resolution step adds latency and may incur charges.
// CNAME record concept
package com.bank.infrastructure;
public class CnameRecordExample {
// CNAME: name -> another name (extra lookup needed)
private static final String NAME = "www.bank.example.com";
private static final String TARGET = "my-alb-123456.ap-south-1.elb.amazonaws.com";
public static void main(String[] args) {
System.out.println("CNAME: " + NAME + " -> " + TARGET);
System.out.println("Client must resolve TARGET to get the IP (extra step)");
System.out.println("Cannot be placed at zone apex (bank.example.com)");
}
}
What is a Route 53 alias record?
With a Route 53 alias record, you choose the record type A (or AAAA for IPv6) and set the alias target to the load balancer. Route 53 internally resolves the alias to the load balancer's current IP addresses and returns A records directly to the client, so there is no second lookup visible to the client.
// Alias record concept
package com.bank.infrastructure;
public class AliasRecordExample {
// Alias: name -> AWS resource's IPs directly (one step)
private static final String NAME = "bank.example.com"; // apex OK!
private static final String TARGET = "ALB:my-alb-123456";
public static void main(String[] args) {
System.out.println("Alias A record: " + NAME + " -> " + TARGET);
System.out.println("Route 53 resolves internally to ALB's current IPs.");
System.out.println("Client receives A records in ONE step.");
System.out.println("Allowed at zone apex: YES");
System.out.println("Query charge for AWS targets: FREE");
}
}
Why prefer an alias record for AWS resources?
Three reasons. First, alias records are allowed at the zone apex, so you can map the clean naked bank.example.com straight to the load balancer, which you cannot do with a CNAME. Second, alias queries to AWS resources are not charged, saving DNS query costs. Third, if the load balancer's IPs change, Route 53 keeps the alias in sync automatically because it knows the resource, not a frozen address.
| Feature | CNAME | Route 53 Alias |
|---|---|---|
| Zone apex | Not allowed | Allowed |
| Resolution steps | Two (name then IP) | One (direct IP) |
| Auto-tracks IPs | No (frozen name) | Yes (resource-aware) |
| Query charge | Standard DNS | Free for AWS targets |
| Works outside R53 | Yes | No (R53 only) |
// Comparison summary
package com.bank.infrastructure;
public class CnameVsAliasComparison {
public static void main(String[] args) {
System.out.println("CNAME:");
System.out.println(" + Works with any DNS provider");
System.out.println(" - Cannot sit at zone apex");
System.out.println(" - Extra resolution step");
System.out.println(" - Standard query charges");
System.out.println();
System.out.println("Alias:");
System.out.println(" + Allowed at zone apex");
System.out.println(" + One-step resolution");
System.out.println(" + Free queries for AWS targets");
System.out.println(" + Auto-tracks changing IPs");
System.out.println(" - Only works inside Route 53");
}
}
What are the supported alias targets?
Alias records only work within Route 53 and only to specific AWS targets: Application Load Balancer, Network Load Balancer, CloudFront distribution, S3 website endpoint, API Gateway, Elastic Beanstalk environment, and another Route 53 record in the same hosted zone. You cannot alias to an arbitrary external hostname.
// Supported alias targets
package com.bank.infrastructure;
import java.util.List;
public class AliasTargets {
public static final List<String> SUPPORTED = List.of(
"Application Load Balancer (ALB)",
"Network Load Balancer (NLB)",
"CloudFront distribution",
"S3 website endpoint",
"API Gateway",
"Elastic Beanstalk environment",
"Another Route 53 record in the same zone"
);
public static void main(String[] args) {
System.out.println("Supported alias targets:");
SUPPORTED.forEach(t -> System.out.println(" - " + t));
}
}
What if DNS is hosted outside Route 53?
If your DNS is hosted outside Route 53, you are forced to use a CNAME on a subdomain like www.bank.example.com because you cannot create alias records elsewhere. This is a common reason teams migrate their DNS into Route 53 -- to get apex domain support and free alias queries for AWS resources.
// When DNS is outside Route 53
package com.bank.infrastructure;
public class ExternalDnsLimitation {
public static void main(String[] args) {
System.out.println("DNS outside Route 53:");
System.out.println(" - Cannot use alias records");
System.out.println(" - Must use CNAME on a subdomain (www.bank.example.com)");
System.out.println(" - Cannot map the naked domain to an ALB");
System.out.println();
System.out.println("Solution: migrate DNS to Route 53 for alias support.");
}
}
What are common mistakes?
The first mistake is trying to hardcode an ALB IP address in a DNS A record -- the IPs change and your domain breaks. The second mistake is putting a CNAME at the zone apex, which violates DNS rules and causes unpredictable resolution failures. The third mistake is not realizing that alias records are free for AWS targets and continuing to use CNAMEs unnecessarily.
// Common mistakes
package com.bank.infrastructure;
public class DnsMappingMistakes {
public static void main(String[] args) {
System.out.println("WRONG: A record with hardcoded ALB IP");
System.out.println(" IPs change as AWS scales the ALB -> domain breaks");
System.out.println();
System.out.println("WRONG: CNAME at zone apex (bank.example.com)");
System.out.println(" Violates DNS RFC -> unpredictable failures");
System.out.println();
System.out.println("CORRECT: Route 53 alias A record at apex");
System.out.println(" Maps to ALB, tracks IPs, free queries, apex OK");
}
}
What should a senior engineer know?
A senior engineer knows that alias records are not just a convenience but a cost and reliability optimization. Route 53 does not charge for alias queries to AWS resources, while CNAME queries are billed. For a high-traffic banking application receiving millions of DNS queries per day, this difference is significant.
Senior engineers also understand the health check integration. When you create an alias record pointing to an ALB, Route 53 can use the ALB's health status to route traffic away from unhealthy targets automatically, which is critical for multi-region failover in banking disaster recovery.
Another senior concern is the difference between alias records and CNAME flattening offered by third-party DNS providers like Cloudflare. Both solve the zone apex problem, but alias records are native to Route 53 and tightly integrated with AWS health checks. CNAME flattening is a DNS provider trick that resolves the CNAME at the authoritative level before returning an A record to the client.
package com.bank.aws;
public class AliasSeniorKnowledge {
public static void main(String[] args) {
// Cost: alias queries to AWS resources are free
// CNAME queries are billed at standard Route 53 rates
long dailyQueries = 5_000_000L;
double cnameRate = 0.40 / 1_000_000; // per query
double monthlyCost = dailyQueries * 30 * cnameRate;
System.out.println("Monthly DNS cost with CNAME: $" + monthlyCost);
System.out.println("Monthly DNS cost with Alias: $0.00");
}
}
Monthly DNS cost with CNAME: $60.0
Monthly DNS cost with Alias: $0.00
Visual Overview
CNAME vs Alias Record Resolution
CNAME (two steps, subdomain only):
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Client │───→│ DNS Resolver │───→│ bank.example │
│ resolves │ │ │ │ .com NS │
│ www.bank. │ │ Step 1: get CNAME │ │ │
│ example.com │ │ www → alb-123.elb │ │ Returns: │
│ │ │ │ │ CNAME record │
│ │ │ Step 2: resolve │ └──────────────┘
│ │ │ alb-123.elb.com │
│ │ │ → 52.10.1.100 │ Extra lookup!
│ │ │ │ Cannot be at
└─────────────┘ └──────────────────┘ zone apex!
Alias (one step, apex allowed):
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Client │───→│ Route 53 │───→│ Route 53 │
│ resolves │ │ │ │ knows ALB │
│ bank. │ │ Alias → ALB │ │ resource │
│ example.com │ │ Resolves INTERNALLY│ │ │
│ (apex!) │ │ to current IPs │ │ Returns: │
│ │ │ │ │ A record(s) │
│ │ │ Returns A records │ │ directly │
└─────────────┘ └──────────────────┘ └──────────────┘
One step! Free! Auto-tracks IP changes!
Key Takeaway
To point a domain at an AWS load balancer I create a DNS record in Route 53, and I have two options: a CNAME record or a Route 53 alias record. A load balancer does not give me a fixed IP; it gives me a long DNS name whose underlying IPs change as AWS scales it, so I must map my friendly domain to the resource, never to a hardcoded IP.
A CNAME record maps a name to another name. It works for a subdomain like www, but it has two drawbacks. First, DNS rules forbid a CNAME at the zone apex, so I cannot map the naked bank.example.com with a CNAME. Second, the client has to do a second DNS lookup to turn the target name into an IP, which adds a resolution step.
A Route 53 alias record is an AWS-specific extension that maps the name straight to the AWS resource. Route 53 resolves it internally to the load balancer's current IP addresses and hands the client A records directly in one step. I prefer it for three reasons: it is allowed at the zone apex so I can use the clean naked domain, alias queries to AWS resources are free, and it automatically tracks the load balancer's changing IPs.
At National Bank of India I wanted customers to reach internet banking at the clean bank.example.com with no www, behind an Application Load Balancer. A CNAME cannot sit at that apex, so I used a Route 53 alias A record. That gave customers the naked domain, saved the extra lookup, and meant that when AWS changed the load balancer's IPs our DNS resolved correctly with no manual change.
Remember one sentence: use a Route 53 alias record instead of a CNAME to map a domain to an AWS load balancer, because it works at the zone apex, resolves in one step, is free, and tracks changing IPs automatically.
---