Deploy a Static WordPress using AWS & Cloudflare, Part 2: Downloading Your Static WordPress & Deploying to AWS S3

Hosting a WordPress site can be insecure and expensive. Making it static is a great way to optimize these downfalls, and hosting it in S3 can reduce costs even more and allow for more fine-grained security configurations.

The steps below will walk you through how to generate static files from your WordPress site and host them in a new and configured AWS S3 bucket for a custom domain.

This is Part 2 in a series about creating a static WordPress site deployed using AWS S3 and Cloudflare:

Part 1 – Building a WordPress in Docker

Part 2 – Converting a WordPress to a Static Site and Deploying to AWS S3

Part 3 – Connecting Your S3 Bucket to Cloudflare


Downloading your Static Files

  1. Navigate to Plugins > Add New > Search Simply Static > Click Install > Click Activate. Once the plugin is activated, navigate to Simply Static in the side panel and select Settings.
  2. Under the General tab, make sure Use relative URLs is checked and the Delivery Method is set to ZIP Archive. Then click Save.
  3. Navigate to Simply Static > Generate and click Generate. Assuming the process completes successfully, there should be a message that says you can download your site as a .zip file. Click this link. You will need this later to upload to your AWS S3 bucket.

Configuring Your S3 Bucket

  1. Sign in to AWS. Navigate to S3 and create a new bucket. Give it the name of your domain. I named mine gillianlemke.com.
  2. There are a few steps to go through before your bucket is created. You can change any of this later in the bucket configurations.
    • Click through Step 2: Configure options. Nothing special is needed here right now.
    • Step 3: Set permissions is important. Uncheck all of these. In order for your site to be publicly accessible, the bucket needs lower security than you’d want otherwise.
    • In Step 4, just review your bucket and then click Create.
  3. Next, you’ll need to create the bucket policy. AWS has this handy-dandy policy generator. Below, you can see how I filled out mine. (If you don’t want to use the generator, there are pretty good examples on the AWS docs as well.)
    • Type of policy: S3 Bucket Policy
    • Effect: Allow
    • Principal: *
    • AWS Service: Amazon S3 (this is auto-populated depending on the type of policy)
    • Actions: only GetObject
    • AmazonResourceName (ARN): this is dependent on your domain name but will have the same format, for example: arn:aws:s3:::gillianlemke.com/*
    • You should add a condition. I only want to give Cloudflare access to my S3 bucket, so I made a condition that only allows Cloudflare IPs. All Cloudflare IP Ranges can be accessed here.
      • Condition: IpAddress
      • Key: aws:SourceIp
      • Value: make a comma-separated list using the IPs (including the ranges) from the Cloudflare link above. (Personally, I found the generator hard to use in this step, so you might want to add these after you’ve generated the file.)
  4. Here is my finished product. I did not use the generator, so yours may look slightly different depending on how you got your solution.

    
    {
        "Version": "2012-10-17",
        "Id": "S3PolicyId1",
        "Statement": [
            {
                "Sid": "IPAllow",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::gillianlemke.com/*",
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": [
                            "103.21.244.0/22",
                            "103.22.200.0/22",
                            "103.31.4.0/22",
                            "104.16.0.0/12",
                            "108.162.192.0/18",
                            "131.0.72.0/22",
                            "141.101.64.0/18",
                            "162.158.0.0/15",
                            "172.64.0.0/13",
                            "173.245.48.0/20",
                            "188.114.96.0/20",
                            "190.93.240.0/20",
                            "197.234.240.0/22",
                            "198.41.128.0/17",
                            "2400:cb00::/32",
                            "2405:b500::/32",
                            "2606:4700::/32",
                            "2803:f800::/32",
                            "2c0f:f248::/32",
                            "2a06:98c0::/29"
                        ]
                    }
                }
            }
        ]
    }
      
  5. Just to be safe, you’ll also want to add a CORS configuration with one rule allowing all GET requests access to your domain, which in this case is https://gillianlemke.com.
  6. 
    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://gillianlemke.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    </CORSConfiguration>
      
  7. The last thing you might want to do is make an S3 bucket that points to the www prefixed version of your domain. AWS has a very handy way to do this.
    • Create a new S3 bucket and name it the www version of your site, example: www.gillianlemke.com. (Don’t do any fancy configurations, just click create from Step 1.)
    • After you’ve created the bucket, navigate into the bucket, and go to the Properties tab.
    • Click Static Website Hosting and check Redirect requests. Type in the name of your main bucket where you made all your configurations, for example gillianlemke.com, and set the protocol to https.
  8. In your main bucket, don’t forget to upload your website files that you downloaded at the beginning of the tutorial. To do that, click on your bucket, click upload, and drag and drop all of your WordPress files.
  9. You’re almost there! Now that you’ve set up your S3 bucket, we just have to configure Cloudflare, and then you’ll have a static WordPress site running on AWS!