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 |
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:
- Block public access:
{
"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/
- create deployer user: https://console.aws.amazon.com/iam/home#/users
- create a group for the user, e.g.: "Publisher"
- create custom policy which only contains access for deployment https://console.aws.amazon.com/iam/home#/policies
{
"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
- go to: https://console.aws.amazon.com/iam/home#/users
- select user
- go to "Security credentials" tab
- click "Create access key"
The secret key can only be copied from this dialog!
in Ubuntu it's
sudo apt install awscli
- 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
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