How to Setup AWS S3 URLs with a Subdomain

AWS S3 is an excellent storage solution for images and other web resources like videos and audios. When using S3 you will notice that the urls contain AWS information like bucket name and region. It's very common for websites to configure their S3 bucket urls to use a subdomain. Doing so will create cleaner urls and you can use a different subdomain for different assets like images, videos, audios, etc. In this blog we will be learning how to set up AWS S3 urls with a subdomain.

Jordan Wu profile picture

Jordan Wu

4 min·Posted 

Reflection of Sunset at Dawn Image.
Reflection of Sunset at Dawn Image.
Table of Contents

Customizing Amazon S3 URLS with CNAME records

We learned how to store images in AWS S3 in a previous blog post. In the post you stored images in a S3 bucket and the images are publicly accessible using a url containing AWS information like the BUCKET_NAME and REGION in the following structure http://BUCKET_NAME.s3.REGION.amazonaws.com/[Filename].

It works however, you might use your own subdomain instead for example you might prefer https://images.example.com. For my personal taste I would use my own subdomain instead. That way the urls look like they belong to my domain instead of AWS. I'm using AWS S3 as a storage solution for my website assets and users do not have to know about it.

Any bucket with a DNS-compatible name can be referenced as follows: http://images.example.com.s3.us-east-1.amazonaws.com/mydog.jpg. By using CNAME, you can map images.example.com to an Amazon S3 hostname so that the previous URL could become http://images.example.com/mydog.jpg. It's much cleaner and you know what domain the image belongs to.

How to Associate a Hostname with an Amazon S3 Bucket

  1. Select a hostname that belongs to a domain that you control. This example uses the images subdomain of the example.com domain.
  2. Create a bucket that matches the hostname. In this example, the host and bucket names are images.example.com. The bucket name must exactly match the hostname.
  3. Create a CNAME DNS record that defines the hostname as an alias for the Amazon S3 bucket.
images.example.com CNAME images.example.com.s3.us-west-2.amazonaws.com

That's all the steps you would need to get your subdomain working with AWS S3 bucket.

How to Setup in Cloudflare

For me I'm using Cloudflare as my domain name registrar and this is where I would point the subdomain to the AWS S3 bucket.

Cloudflare CNAME DNS Record Alias to S3 Bucket
Cloudflare CNAME DNS Record Alias to S3 Bucket

I have proxied enabled as it's the recommendation for all A, AAAA, and CNAME records. After I changed my SSL/TLS setting to be Full to allow the server S3 to use the self signed certificate.

Cloudflare SSL/TLS settings
Cloudflare SSL/TLS settings

Lastly, since I'm using Next.js I would need to add my subdomain to the list of allowed domains for images. This will allow me to fetch images from the subdomain in my Next.js app.

File Imagenext.config.mjs
const nextConfig = {
  images: {
    domains: ['images.jordanwu.xyz'],
  },
}

After completing all the steps it's important to verify you are able to fetch your assets using your subdomain url for example: https://images.jordanwu.xyz/site-image.png.

Lastly, I want to only allow Cloudflare access to my AWS S3 bucket. This will allow Cloudflare to handle any security issues like ddos protection. This can be done by adding a Bucket Policy to only allow the following IP addresses, for my case both https://www.cloudflare.com/ips-v4 and https://www.cloudflare.com/ips-v6.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<your-bucket>/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "173.245.48.0/20",
                        "103.21.244.0/22",
                        "103.22.200.0/22",
                        "103.31.4.0/22",
                        "141.101.64.0/18",
                        "108.162.192.0/18",
                        "190.93.240.0/20",
                        "188.114.96.0/20",
                        "197.234.240.0/22",
                        "198.41.128.0/17",
                        "162.158.0.0/15",
                        "104.16.0.0/12",
                        "172.64.0.0/13",
                        "131.0.72.0/22",
                        "2400:cb00::/32",
                        "2606:4700::/32",
                        "2803:f800::/32",
                        "2405:b500::/32",
                        "2405:8100::/32",
                        "2a06:98c0::/29",
                        "2c0f:f248::/32"
                    ]
                }
            }
        }
    ]
}

About the Author

Jordan Wu profile picture
Jordan is a full stack engineer with years of experience working at startups. He enjoys learning about software development and building something people want. What makes him happy is music. He is passionate about finding music and is an aspiring DJ. He wants to create his own music and in the process of finding is own sound.
Email icon image
Stay up to date

Get notified when I publish something new, and unsubscribe at any time.