8.2
CNAME vs Alias
Why the zone apex cannot be a CNAME, what Alias does instead, and its valid targets.
16 min Reading + animations
Tip: tap or hover any dotted-underlined term to see what it means.
By the end of this lesson you will be able to
- Explain why AWS resources such as load balancers give you a hostname instead of fixed IP addresses, and what that means for your DNS records.
- Explain, from the DNS standard, why the zone apex (
example.com) can never be a CNAME. - Describe what an Alias record is, how Route 53 answers it, and how it differs from a CNAME in type, TTL, cost and health.
- List the AWS resources an Alias can point to, the conditions each one needs, and the targets it cannot point to (EC2 DNS names, RDS endpoints).
- Choose the right record for any name and target: Alias, A with an Elastic IP, or CNAME, and answer the guaranteed exam question in seconds.
#Why this question is guaranteed in the exam
The owner’s notes put it bluntly: one question on CNAME vs Alias is practically guaranteed. It shows up on its own and, even more often, hidden inside a question about load balancers or CloudFront. The idea behind it is short, so learn it properly once.
#AWS gives you a name, not an address
When you create an Application Load Balancer (lesson 6.3), AWS does not hand you an IP address. It gives you a DNS name such as:
my-alb-1234.us-east-1.elb.amazonaws.com
CloudFront gives you d111111abcdef8.cloudfront.net, API Gateway gives you …execute-api.us-east-1.amazonaws.com, an S3 website gives you …s3-website-us-east-1.amazonaws.com. The reason is the same every time: the IP addresses behind these services belong to AWS and change. A load balancer adds nodes when traffic grows, removes them when it falls, and replaces nodes that fail. Each new node has a new address. AWS keeps the name pointing at whatever addresses are current, with a short TTL (60 seconds for a load balancer), and promises nothing about the addresses themselves.
Your users, though, want to type your name: example.com or app.example.com. So in your hosted zone you need a record that says “this name of mine means that AWS name”. DNS has a standard record for that, the CNAME, and Route 53 adds its own, the Alias. Which one works depends on where the name sits.
#CNAME: a pointer to another name
A CNAME (canonical name) record maps one hostname to another hostname, not to an address. The DNS lesson covers it in general; here is what matters on AWS.
- When a resolver asks for
www.example.comand finds a CNAME, the answer is “this name is reallymy-alb-1234…elb.amazonaws.com”. The resolver then has to look up that second name to get the IPs. On a cold cache that is an extra round trip. - The target can be any hostname on the internet: an AWS name,
blog.example.netat a blogging company, a SaaS shop. Route 53 does not have to host the target. - A CNAME redirects every query type for the name (A, AAAA, MX, TXT…), because it says the whole name lives elsewhere.
- You choose its TTL, and Route 53 charges for CNAME queries (about $0.40 per million in a public hosted zone). If the CNAME points to another record that is also in Route 53, each lookup is billed as two queries: the CNAME, then the record it points to.
#Why the zone apex cannot be a CNAME
The zone apex (also called the root domain or naked domain) is the name of the hosted zone itself: example.com in the example.com zone. Two rules collide there:
- A CNAME must stand alone. The DNS standard (RFC 1034, section 3.6.2) says that if a name has a CNAME record, it may have no other records. That follows from what a CNAME means: “everything about this name is somewhere else”. A resolver that finds a CNAME follows it for every question, so any other record at the same name would be unreachable and contradictory.
- The apex is never empty. Every zone has an SOA record (the zone’s settings) and NS records (its name servers) at the apex. Route 53 creates both the moment you create the hosted zone, and you cannot delete them. Most zones also have MX (mail) and TXT (verification, SPF) records there.
So a CNAME at the apex would have to share the name with SOA and NS, which the standard forbids. If a DNS server allowed it anyway, a question for the MX or NS records of example.com would be redirected to the load balancer’s name, and mail and delegation would break. Route 53 simply refuses: you cannot create a CNAME whose name is the same as the hosted zone. The same “stands alone” rule is why a www CNAME cannot also have a TXT record next to it.
What the zone apex accepts
Try to add records to example.com and watch Route 53 accept or reject them. The table shows the records that already exist at that name.
Scenario
Records at example.com
| Name | Type | Value |
|---|---|---|
| example.com | NS | ns-1.awsdns-01.org … |
| example.com | SOA | ns-1.awsdns-01.org … |
| example.com | MX | 10 mail.example.com |
Every hosted zone is born with an NS record and an SOA record at its apex; here an MX record for mail sits there too. You ask for a CNAME at example.com pointing to the ALB.
#Alias: Route 53 answers for the target
An Alias record is a Route 53-specific extension to DNS. You create a record of a normal type, almost always A (IPv4) or AAAA (IPv6), switch on “Alias”, and choose an AWS resource as the target instead of typing an IP address.
When a query arrives, Route 53 itself looks up the target’s current addresses inside AWS and answers with plain A or AAAA records. The resolver never learns that an Alias exists:
- No extra lookup. The client receives IP addresses in the first answer, not another name to resolve.
digshows only A lines; the Alias flag is visible only in the Route 53 console or API (list-resource-record-sets). - It works at the apex. To the outside world it is an A record, so it can sit next to SOA, NS, MX and TXT. This is the main reason it exists.
- It follows the target automatically. When the load balancer’s IPs change, Route 53 starts answering with the new ones. Nobody edits a record.
- You cannot set its TTL. For an AWS resource, Route 53 uses the resource’s own TTL (60 seconds for a load balancer). For an Alias to another record, it uses that record’s TTL.
- Queries are free when the target is an AWS resource (load balancer, CloudFront, API Gateway, S3 website, and the rest of the list below). A CNAME to the same load balancer is charged.
- Evaluate Target Health. An Alias can inherit the health of its target. With failover, weighted, latency and other non-simple policies, Route 53 stops returning a target that is unhealthy, without a separate Route 53 health check.
- Name and type must match. Route 53 answers an Alias only when the query’s name and type match. An A Alias does not answer AAAA questions, so for IPv6 you create a second Alias of type AAAA.
CNAMEAlias
- Standard DNS, every DNS provider has it.
- Maps a name to any other hostname, AWS or not.
- Not allowed at the zone apex; cannot share its name with any other record.
- Resolver must make a second lookup for the target name.
- You set the TTL.
- Route 53 charges for queries.
- No health awareness of its own.
- Route 53-only extension.
- Maps a name to selected AWS resources or another record in the same hosted zone.
- Works at the apex and on subdomains; coexists with other records.
- Route 53 answers with the IP addresses directly (type A/AAAA).
- TTL comes from the target; you cannot set it.
- Free for AWS resource targets.
- Evaluate Target Health built in.
CNAME lookup vs Alias answer
Follow one query through the resolver. With a CNAME, Route 53 hands back another name and the resolver must look that up too; with an Alias, Route 53 looks up the target itself and answers with IP addresses.
Scenario
www.example.com is a CNAME to the ALB’s DNS name.
The browser needs an IP address for www.example.com and asks its resolver. The full chain (root, TLD, authoritative) is in the DNS lesson; here we start where Route 53 is asked.
Self-checkQuestion
The hosted zone example.com already has NS, SOA and MX records at the apex. Which of these can you add at the name example.com?
#Alias follows the load balancer
This is the property that makes Alias the default for AWS resources. Watch the load balancer replace a node: the Alias picks up the new address within one TTL, while a hand-made A record keeps pointing at an address that is gone. The last scenario shows Evaluate Target Health sending users to a backup when every target behind the load balancer fails.
When the load balancer’s IPs change
AWS replaces and scales load balancer nodes, and their IP addresses change. Compare an Alias, which follows the change, with an A record someone hard-coded to an old IP. The last scenario shows Evaluate Target Health.
Scenario
example.com is an Alias to the ALB. Users ask Route 53 and receive the two node addresses, cached for the ALB’s 60-second TTL.
#What an Alias can point to
The notes list six targets; the slides add two more; the current Route 53 documentation lists these:
| Alias target | Record type | What must be true |
|---|---|---|
| Elastic Load Balancing: ALB, NLB, CLB | A, and AAAA for a dual-stack load balancer | Nothing special; from another account, type its DNS name (the console adds dualstack.) |
| CloudFront distribution | A, and AAAA if IPv6 is on | The distribution lists the record name as an alternate domain name; public hosted zone only; Evaluate Target Health not available |
| API Gateway (regional or edge-optimised API) | A | A custom domain name with the record’s name exists in API Gateway |
| Elastic Beanstalk environment | A | The environment’s domain includes the Region (all environments since early 2016); older ones need a CNAME |
| S3 bucket configured as a static website | A | Bucket name equals the record name (example.com needs a bucket called example.com) and website hosting is on |
| VPC interface endpoint | A | Usually in a private hosted zone, to give an endpoint a friendly name |
| Global Accelerator accelerator | A (AAAA for dual-stack) | Works across accounts by DNS name |
| Another record in the same hosted zone | Same type as the target record (any type except NS and SOA) | Same hosted zone only; at the apex the target cannot be a CNAME |
| App Runner service, AppSync domain name, OpenSearch Service custom domain | A (OpenSearch also AAAA) | The record name matches the service’s custom domain |
The last row and the VPC interface endpoints are not in the notes; App Runner, AppSync and OpenSearch are not on the slides either. They are real Alias targets today but rarely asked in the exam. CloudFront, Global Accelerator, API Gateway, S3 websites and VPC endpoints each get their own chapter later; for now it is enough to know that each one gives you an AWS hostname, which is exactly the situation Alias was built for.
#What an Alias cannot point to
- An EC2 instance or its DNS name (
ec2-203-0-113-25.compute-1.amazonaws.com). There is no Alias for EC2. For one instance, attach an Elastic IP (lesson 3.6) and create a normal A record with it; for several instances, put a load balancer in front and Alias to the load balancer. - An RDS endpoint (
mydb.abc123.us-east-1.rds.amazonaws.com). Use a CNAME on a subdomain such asdb.example.com, usually in a private hosted zone. On failover RDS points the endpoint name at the new primary (lesson 7.1), so the CNAME keeps working. - Anything outside AWS, and records in a different hosted zone. Those need a CNAME (on a subdomain).
#Choosing the record: the decision rule
Is the target an IP address you control?
One EC2 instance with an Elastic IP, an NLB’s static IPs for an allowlist, an on-premises server: create an A (or AAAA) record with that address. You set the TTL; queries are charged.
Is the target an AWS resource on the Alias list?
Load balancer, CloudFront, API Gateway, Beanstalk, S3 website, VPC interface endpoint, Global Accelerator, App Runner, AppSync, OpenSearch: create an Alias A record (plus Alias AAAA for IPv6). This works at the apex and on subdomains, is free, and follows IP changes. Even on a subdomain where a CNAME would work, the Alias is the better choice.
Is the target another record in the same hosted zone?
Create an Alias of the same type as that record, for example
example.comAlias →www.example.comwhenwwwis itself an A or Alias A record.Otherwise, it is a hostname you cannot Alias
RDS endpoint, a non-regional old Beanstalk name, a SaaS or another provider’s hostname, a record in another zone: create a CNAME, and only on a subdomain. If it must be the apex, put CloudFront in front (Alias to CloudFront), use static IPs the provider guarantees (A record), or redirect
example.comtowww.example.comand CNAMEwww.
Try every combination yourself:
Which record should I create?
Pick the name you are creating and what it should point to. The card shows the record Route 53 needs, why, its TTL, its query cost and what must be true first.
Record name
Points to
Create
Alias record, type A (plus AAAA for IPv6)
At the apex only an Alias can point to an AWS hostname: a CNAME is not allowed next to the NS and SOA records. Route 53 looks up the target itself and answers with its current IPs.
| Name | Type | Value |
|---|---|---|
| example.com | A (Alias) | my-alb-1234.us-east-1.elb.amazonaws.com |
- TTL
- Not settable: Route 53 uses the target’s own TTL (60 s for a load balancer).
- Query cost
- Free: Route 53 does not charge for Alias queries to AWS resources.
- Check first
- Add a second Alias of type AAAA if the load balancer is dual-stack. Turn on Evaluate Target Health when the record has an alternative (failover, weighted, latency).
#What goes wrong
| Symptom | Cause | Fix |
|---|---|---|
The console or API rejects a CNAME for example.com | CNAME at the zone apex | Alias A (and AAAA) to the AWS resource |
A TXT or MX record cannot be added to www.example.com | www is a CNAME, which must stand alone | Turn www into an Alias A record, then add the TXT |
| Part of the users get timeouts weeks after go-live | An A record holds the load balancer’s old IPs | Alias to the load balancer |
| The S3 bucket does not appear in the Alias target list | Bucket name differs from the record name, or website hosting is off | Bucket named exactly like the record, static website hosting on (or CloudFront in front) |
| The CloudFront distribution does not appear, or returns 403 for your name | The record name is not an alternate domain name of the distribution, or the zone is private | Add the alternate domain name; use a public hosted zone |
| IPv6 users only ever reach you over IPv4 | Only an A Alias exists | Add an AAAA Alias to the same dual-stack target |
The apex Alias to www.example.com is rejected | www is a CNAME, so the Alias would be an apex CNAME | Alias the apex directly to the resource, or make www an Alias A |
| Failover never happens although the ALB’s targets are all down | Evaluate Target Health is off, or the record uses simple routing | Use a failover (or other) policy with Evaluate Target Health on |
| The DNS bill is higher than expected | CNAMEs to load balancers or chained CNAMEs, billed per query (twice for a Route 53 target) | Replace with Alias records |
#In system design
- Apex plus www. A typical public site has
example.comas an Alias A/AAAA to CloudFront (or an ALB) andwww.example.comeither as another Alias to the same target or as an Alias to the apex record. Both are free and follow the target. - Exam questions mix chapters. The notes’ closing advice: Route 53 questions are often combined with load balancers and CloudFront. Whenever the answer options include a load balancer or a distribution and a domain, check the record type first: Alias for the apex, never a CNAME there, never copied IPs.
- Static IPs and Alias are not opposites. When a partner must allowlist fixed addresses, use an NLB with Elastic IPs or Global Accelerator for the addresses, and still point your domain at it with an Alias.
- Multi-account setups. A load balancer or distribution in another account does not appear in the console’s Alias list, but you can type its DNS name (and Route 53 still answers for it). An Alias cannot reach a record in another hosted zone; use a CNAME for that.
- Databases stay on CNAMEs. Give applications a stable name such as
db.internal.example.comas a CNAME to the RDS endpoint in a private hosted zone; swapping the database later means changing one CNAME, not every application’s configuration.
#Try it yourself
Find the load balancer’s DNS name and its own hosted zone ID (an Alias needs both):
aws elbv2 describe-load-balancers --names my-alb \
--query 'LoadBalancers[0].[DNSName,CanonicalHostedZoneId]'
Create (or update) an Alias A record at the apex. The HostedZoneId inside AliasTarget is the load balancer’s zone ID from the command above, not your own zone’s ID. Notice there is no TTL field:
cat > alias.json <<'EOF'
{
"Comment": "apex Alias to the ALB",
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z35SXDOTRQ7X7K",
"DNSName": "dualstack.my-alb-1234.us-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}
EOF
aws route53 change-resource-record-sets --hosted-zone-id Z0123456789EXAMPLE --change-batch file://alias.json
Now try the forbidden one, a CNAME at the apex. Route 53 rejects the whole change batch with an InvalidChangeBatch error:
aws route53 change-resource-record-sets --hosted-zone-id Z0123456789EXAMPLE --change-batch '{
"Changes": [{ "Action": "CREATE", "ResourceRecordSet": {
"Name": "example.com", "Type": "CNAME", "TTL": 300,
"ResourceRecords": [{ "Value": "my-alb-1234.us-east-1.elb.amazonaws.com" }] } }] }'
Compare what resolvers see for an Alias and for a CNAME:
dig +noall +answer example.com A # only A lines, TTL counting down from 60
dig +noall +answer www.example.com A # a CNAME line, then the ALB's A lines
nslookup -type=AAAA example.com # empty unless you also created an AAAA Alias
See the Alias flag that dig never shows, and ask Route 53 directly what it would answer:
aws route53 list-resource-record-sets --hosted-zone-id Z0123456789EXAMPLE \
--query "ResourceRecordSets[?Name=='example.com.']"
aws route53 test-dns-answer --hosted-zone-id Z0123456789EXAMPLE \
--record-name example.com --record-type A
The fixed hosted zone IDs you will meet most: CloudFront is always Z2FDTNDATAQYW2, Global Accelerator Z2BJ6XQ5FK7U4H; load balancers, S3 websites and Beanstalk have one ID per Region (the ALB example above is the us-east-1 value).
#Summary
Key takeaways
- AWS resources (load balancers, CloudFront, API Gateway, S3 websites…) give you a DNS name because their IP addresses change. Never copy those IPs into an A record.
- CNAME: name → any other hostname, AWS or not; extra lookup; you set the TTL; charged; must stand alone, so it is never allowed at the zone apex, which always holds SOA and NS.
- Alias: Route 53-only; type A/AAAA (or the same type as a target record in the same zone); Route 53 resolves the target itself and answers with IPs; works at the apex; no TTL to set (uses the target’s, 60 s for a load balancer); free for AWS resources; Evaluate Target Health; answers only matching types, so add AAAA for IPv6.
- Alias targets: ELB (ALB/NLB/CLB), CloudFront, API Gateway, Elastic Beanstalk, S3 website (bucket name = record name), VPC interface endpoints, Global Accelerator, another record in the same hosted zone, plus App Runner, AppSync and OpenSearch Service.
- Not Alias targets: EC2 DNS names (use an A record with an Elastic IP), RDS endpoints (use a CNAME on a subdomain), anything outside AWS or in another zone (CNAME on a subdomain).
- Exam reflex: root domain → ALB / CloudFront / S3 website → Alias. Always.
Answer on your own first, then read the explanation, even when you got it right.
Self-checkQuestion
Why does an Application Load Balancer give you a DNS name such as my-alb-1234.us-east-1.elb.amazonaws.com instead of fixed IP addresses?
Self-checkQuestion
Why can a CNAME record never be created at the zone apex example.com?
Self-checkQuestion
Which statement about a CNAME record in Route 53 is true?
Self-checkQuestion
example.com is an Alias A record pointing to an ALB. What does dig example.com A show?
Self-checkQuestion
What TTL does an Alias record pointing to an Application Load Balancer have?
Self-checkQuestion
Which two of these can be the target of a Route 53 Alias record?
Choose 2
Self-checkQuestion
A company’s root domain mycompany.com must send users to an Application Load Balancer. Which record should the solutions architect create?
Self-checkQuestion
An application must reach its RDS for MySQL database as db.example.com. Which record is correct?
Self-checkQuestion
A small site runs on a single EC2 instance. The domain example.com must keep working after the instance is stopped and started. What is the simplest stable setup?
Self-checkQuestion
A static website is in the S3 bucket company-website-prod with website hosting enabled. When creating an Alias for example.com, the bucket does not appear in the target list. What is the fix?
Self-checkQuestion
www.example.com is a CNAME to app.example.com, an A record in the same Route 53 public hosted zone. It receives 50 million queries a month, and standard queries cost $0.40 per million. What do these lookups cost per month?
Self-checkQuestion
Which two statements about Alias records compared with CNAME records are true?
Choose 2
Self-checkQuestion
example.com has two failover Alias records: the primary targets an ALB with Evaluate Target Health set to Yes, the secondary targets an S3 static website. Every EC2 target behind the ALB fails its health check. What happens?
Self-checkQuestion
For which Alias target can Evaluate Target Health NOT be set to Yes?
Self-checkQuestion
www.example.com is a CNAME to an ALB. An engineer tries to create example.com as an Alias to the record www.example.com and Route 53 rejects it. Why?
Self-checkQuestion
example.com has an Alias A record to a dual-stack ALB. IPv6-only test clients cannot resolve it, and IPv6-capable phones always connect over IPv4. What should be done?
Self-checkQuestion
A CloudFront distribution has IPv6 enabled and serves www.example.com. Which records should be created?
Self-checkQuestion
A team wants to create an Alias to a CloudFront distribution in the private hosted zone corp.internal. What happens?
Self-checkQuestion
Can an Alias record in the hosted zone example.com point to a record in the hosted zone example.net?
Self-checkQuestion
An Elastic Beanstalk environment created in 2015 has the domain myapp.elasticbeanstalk.com, without a Region in it. How can app.example.com point to it?
Self-checkQuestion
An online shop runs on a SaaS platform that gives the hostname shops.example.net and no static IPs. The company wants the bare domain example.com to open the shop. What works with Route 53?
Self-checkQuestion
A colleague says an Alias is just a CNAME that Route 53 allows at the apex. Which correction is most accurate?
Self-checkQuestion
Which two of these can NOT be targets of an Alias record?
Choose 2
Self-checkQuestion
example.com was an A record with 198.51.100.10, an address an engineer copied from dig on the ALB’s name. After several weeks some users get timeouts. What is the most likely cause and fix?
Self-checkQuestion
An Alias record targets another record in the same hosted zone. Which record types can it have?
Self-checkQuestion
example.com is an Alias to www.example.com, and www.example.com is an Alias A record to an ALB. How are queries for example.com billed?
Self-checkQuestion
To create an Alias for app.example.com that targets a CloudFront distribution, which two conditions must be met?
Choose 2
Self-checkQuestion
Which of these is NOT a reason to prefer an Alias over a CNAME for www.example.com pointing to an ALB?
Self-checkQuestion
A resolver cached the Alias answer for example.com at 11:59:30 (TTL 60 seconds, from the ALB). AWS replaces an ALB node at 12:00:00. Until when, at the latest, can that resolver still hand out the old address?
Self-checkQuestion
The root domain mycompany.com must serve both IPv4 and IPv6 clients through a dual-stack ALB. Which two records should be created?
Choose 2