Skip to content

Instantly share code, notes, and snippets.

@noherczeg
Last active April 5, 2023 22:09
Show Gist options
  • Save noherczeg/ddaf9ea800c27181fb517880412b80ce to your computer and use it in GitHub Desktop.
Save noherczeg/ddaf9ea800c27181fb517880412b80ce to your computer and use it in GitHub Desktop.

AWS S3 with Cloudflare setup for static sites

We will use "cheers.mysite.com" as an example for bucket names, but remember that BUCKET NAMES MUST MATCH WITH EVENTUAL Cloudflare DOMAIN NAMES which is true even for domain names with sub-domains!

Full Domain S3 Bucket name CF/Type CF/Name CF/Content
mysite.com mysite.com A mysite.com mysite.com.s3-website.REGION_OF_BUCKET.amazonaws.com
cheers.mysite.com cheers.mysite.com CNAME cheers cheers.mysite.com.s3-website.REGION_OF_BUCKET.amazonaws.com

S3

We will create bucket with a setup where noone will be able to reach the contents of the bucket expect Cloudflare's proxies.

  • create bucket (e.g.: cheers.mysite.com => BUCKET_NAME)
  • Properties:
    • turn on "Static Website Hosting"
    • "index document" should be "index.html"
  • Permissions:
    • Block public access:
      • turn it off because it trumps all other configuration and Cloudflare won't be able to access the bucket!
    • Bucket Policy:
    {
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::BUCKET_NAME/*",
            "Condition": {
                "NotIpAddress": {
                    "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"
                    ]
                }
            }
        },
        {
            "Sid": "AllowDeployerPut",
            "Effect": "Allow",
            "Principal": {
                "AWS": "YOUR_ARN_USER_STRING"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::BUCKET_NAME/*"
        }
    ]
}

To obtain an up-to-date list of Cloudflare ips to whitelist, you should visit: https://www.cloudflare.com/ips/

IAM

  {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:ListBucket",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::s3.norbertsson.me/*",
        "arn:aws:s3:::s3.norbertsson.me"
      ]
    }
  ]
}
  • add policy to group
  • add user to group

ENV

Obtaining AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY

The secret key can only be copied from this dialog!

Install CLI tool

https://aws.amazon.com/cli/

in Ubuntu it's sudo apt install awscli

Publish artifacts

  • export ENV variables
export AWS_ACCESS_KEY_ID=YOUR_KEY \
export AWS_SECRET_ACCESS_KEY=YOUR_KEY \
export AWS_DEFAULT_REGION=YOUR_REGION \
export AWS_DEFAULT_OUTPUT=json
  • go to project sources
  • build artifact (target folder e.g.: build)
  • publish artifact: aws s3 sync --acl public-read --delete build/ s3://BUCKET_NAME

Cloudflare

In the following example we will create a sub-domain record for mysite.com, e.g.: cheers.example.com which will map to our bucket.

  • select domain
  • go to the DNS menu
  • "Add record"
    • Type: CNAME
    • Name: cheers
    • Content: BUCKET_NAME.s3-website.REGION_OF_BUCKET.amazonaws.com
    • Proxy Status: Proxied

In certain cases it could take a few minutes for DNS records to update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment