DEV Community

John  Ajera
John Ajera

Posted on

Setting Up Custom Domain for GitHub Pages with Route53

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:

  1. Create Route53 Hosted Zone - Create a hosted zone for your subdomain
  2. Configure DNS Records - Add A and CNAME records pointing to GitHub Pages
  3. Update Parent Zone - Add NS records in the parent zone to delegate the subdomain
  4. 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
}
Enter fullscreen mode Exit fullscreen mode

Key points:

  • name: The domain name (without trailing dot)
  • private_zone: Set to false for 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"
}
Enter fullscreen mode Exit fullscreen mode

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."]
}
Enter fullscreen mode Exit fullscreen mode

Configuration:

  • zone_id: References the subdomain zone we created
  • name: The www subdomain
  • 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"
  ]
}
Enter fullscreen mode Exit fullscreen mode

GitHub Pages IP addresses:

These are GitHub Pages' static IP addresses. Use these same IPs for any GitHub Pages custom domain:

  • 185.199.108.153
  • 185.199.109.153
  • 185.199.110.153
  • 185.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
}
Enter fullscreen mode Exit fullscreen mode

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.nz to 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
}
Enter fullscreen mode Exit fullscreen mode

GitHub Pages Configuration

After applying the Terraform configuration:

  1. Wait for DNS propagation - Can take a few minutes to several hours
  2. Add custom domain in GitHub - Go to repository Settings → Pages → Custom domain
  3. Enter your domain - oceania.aws-community-day.nz
  4. 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
Enter fullscreen mode Exit fullscreen mode

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.153
  • 185.199.109.153
  • 185.199.110.153
  • 185.199.111.153

These IPs are stable and can be reused for any GitHub Pages custom domain.


Troubleshooting

DNS Not Resolving

  1. Check NS records: Verify NS records are correctly set in parent zone
  2. Wait for propagation: DNS changes can take up to 48 hours (usually much faster)
  3. Verify zone delegation: Ensure name servers match between zones

GitHub Pages Not Recognizing Domain

  1. Verify DNS records: Ensure A and CNAME records are correct
  2. Check GitHub settings: Domain must be added in repository settings
  3. 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)