Setting Up Custom Domain for GitHub Pages with Route53
This article demonstrates how to set up a custom subdomain for GitHub Pages using AWS Route53. We'll use the AWS Community Oceania website as a practical example, showing how to configure DNS for a GitHub Pages site.
High-Level Steps
Setting up a custom domain for GitHub Pages involves:
- Create Route53 Hosted Zone - Create a hosted zone for your subdomain
- Configure DNS Records - Add A and CNAME records pointing to GitHub Pages
- Update Parent Zone - Add NS records in the parent zone to delegate the subdomain
- Configure GitHub Pages - Add the custom domain in your GitHub repository settings
Prerequisites
- You own the root domain (
aws-community-day.nz) and it's managed in Route53 - Access to the parent Route53 hosted zone
- GitHub Pages site already deployed
- Terraform configured with AWS provider
Use Case: AWS Community Oceania
AWS Community Oceania needed to set up a custom subdomain oceania.aws-community-day.nz for their GitHub Pages site. The root domain aws-community-day.nz was already managed in Route53, so we created a subdomain hosted zone and configured DNS records to point to GitHub Pages.
Terraform Implementation
Step 1: Reference the Parent Zone
First, we reference the existing parent zone using a data source:
# Parent zone data source
data "aws_route53_zone" "aws_community_day_nz" {
name = "aws-community-day.nz"
private_zone = false
}
Key points:
-
name: The domain name (without trailing dot) -
private_zone: Set tofalsefor public hosted zones - This data source retrieves the existing zone information
Step 2: Create Subdomain Hosted Zone
Create a new hosted zone for the subdomain:
# ============================================================================
# oceania.aws-community-day.nz subdomain
# ============================================================================
resource "aws_route53_zone" "oceania_aws_community_day_nz" {
name = "oceania.aws-community-day.nz"
}
What this creates:
- A new Route53 hosted zone for the subdomain
- Name servers automatically assigned by AWS
- Zone ID for referencing in other resources
Step 3: Configure DNS Records
CNAME Record for www Subdomain
resource "aws_route53_record" "oceania_www" {
zone_id = aws_route53_zone.oceania_aws_community_day_nz.zone_id
name = "www.oceania.aws-community-day.nz"
type = "CNAME"
ttl = 300
records = ["aws-user-group-nz.github.io."]
}
Configuration:
-
zone_id: References the subdomain zone we created -
name: Thewwwsubdomain -
type: CNAME record type -
ttl: Time to live (300 seconds = 5 minutes) -
records: Points to GitHub Pages domain (note the trailing dot)
A Records for Root Subdomain
resource "aws_route53_record" "oceania_root_a" {
zone_id = aws_route53_zone.oceania_aws_community_day_nz.zone_id
name = "oceania.aws-community-day.nz"
type = "A"
ttl = 300
records = [
"185.199.108.153",
"185.199.109.153",
"185.199.110.153",
"185.199.111.153"
]
}
GitHub Pages IP addresses:
These are GitHub Pages' static IP addresses. Use these same IPs for any GitHub Pages custom domain:
185.199.108.153185.199.109.153185.199.110.153185.199.111.153
Why A records:
- GitHub Pages requires A records for the root domain (apex domain)
- CNAME records cannot be used for root domains per DNS standards
- Multiple A records provide redundancy and load distribution
Step 4: Delegate Subdomain to New Zone
Add NS records in the parent zone to delegate the subdomain:
resource "aws_route53_record" "oceania_ns" {
zone_id = data.aws_route53_zone.aws_community_day_nz.zone_id
name = "oceania.aws-community-day.nz"
type = "NS"
ttl = 300
records = aws_route53_zone.oceania_aws_community_day_nz.name_servers
}
Important details:
-
zone_id: References the parent zone (not the subdomain zone) -
name: The subdomain name -
type: NS (Name Server) record type -
records: Uses the name servers from the subdomain zone we created
What this does:
- Delegates DNS resolution for
oceania.aws-community-day.nzto the new hosted zone - Allows the subdomain to have its own DNS records
- Enables independent management of the subdomain
Complete Terraform Configuration
Here's the complete configuration:
# Parent zone data source
data "aws_route53_zone" "aws_community_day_nz" {
name = "aws-community-day.nz"
private_zone = false
}
# ============================================================================
# oceania.aws-community-day.nz subdomain
# ============================================================================
resource "aws_route53_zone" "oceania_aws_community_day_nz" {
name = "oceania.aws-community-day.nz"
}
resource "aws_route53_record" "oceania_www" {
zone_id = aws_route53_zone.oceania_aws_community_day_nz.zone_id
name = "www.oceania.aws-community-day.nz"
type = "CNAME"
ttl = 300
records = ["aws-user-group-nz.github.io."]
}
resource "aws_route53_record" "oceania_root_a" {
zone_id = aws_route53_zone.oceania_aws_community_day_nz.zone_id
name = "oceania.aws-community-day.nz"
type = "A"
ttl = 300
records = [
"185.199.108.153",
"185.199.109.153",
"185.199.110.153",
"185.199.111.153"
]
}
resource "aws_route53_record" "oceania_ns" {
zone_id = data.aws_route53_zone.aws_community_day_nz.zone_id
name = "oceania.aws-community-day.nz"
type = "NS"
ttl = 300
records = aws_route53_zone.oceania_aws_community_day_nz.name_servers
}
GitHub Pages Configuration
After applying the Terraform configuration:
- Wait for DNS propagation - Can take a few minutes to several hours
- Add custom domain in GitHub - Go to repository Settings → Pages → Custom domain
-
Enter your domain -
oceania.aws-community-day.nz - Enable HTTPS - GitHub will provision a certificate via Let's Encrypt
DNS Record Summary
After configuration, you'll have:
| Record Type | Name | Value | Purpose |
|---|---|---|---|
| NS | oceania.aws-community-day.nz |
Name servers | Delegates subdomain |
| A | oceania.aws-community-day.nz |
GitHub IPs | Root domain resolution |
| CNAME | www.oceania.aws-community-day.nz |
aws-user-group-nz.github.io. |
www subdomain |
Verification
Verify DNS configuration:
# Check NS records (should show Route53 name servers)
dig NS oceania.aws-community-day.nz
# Check A records (should show GitHub IPs)
dig A oceania.aws-community-day.nz
# Check CNAME record
dig CNAME www.oceania.aws-community-day.nz
Important Notes
TTL Considerations
- Low TTL (300 seconds): Faster changes but more DNS queries
- High TTL (3600+ seconds): Fewer queries but slower propagation
- For initial setup, use low TTL; increase after verification
Trailing Dots in DNS
-
CNAME record:
aws-user-group-nz.github.io.(trailing dot = FQDN) - Without trailing dot: Treated as relative to the zone
- Always use trailing dots for external domains
GitHub Pages IP Addresses
GitHub Pages uses these static IP addresses:
185.199.108.153185.199.109.153185.199.110.153185.199.111.153
These IPs are stable and can be reused for any GitHub Pages custom domain.
Troubleshooting
DNS Not Resolving
- Check NS records: Verify NS records are correctly set in parent zone
- Wait for propagation: DNS changes can take up to 48 hours (usually much faster)
- Verify zone delegation: Ensure name servers match between zones
GitHub Pages Not Recognizing Domain
- Verify DNS records: Ensure A and CNAME records are correct
- Check GitHub settings: Domain must be added in repository settings
- Wait for certificate: HTTPS certificate provisioning can take time
Certificate Issues
- GitHub automatically provisions certificates via Let's Encrypt
- Ensure DNS is fully propagated before adding domain in GitHub
- Certificate provisioning typically takes 10-30 minutes after DNS is correct
Top comments (0)