Converted with medium-to-markdown@0.0.3
Linda Cai

Jun 16

·5 min read

Migrate a Flask site from EC2 to S3 + CloudFront, in 7 easy steps

This compelling diagram was made by my friend Siddhant Moholanobish

This work took about 2 hours total, and saves me $14 a month!

My latest personal site was done in Flask around 2014. I had kept it running on EC2, which was free for just about a year but then started costing over $14 a month (and this is one of the smallest possible instances). In comparison, my S3 costs are only a few cents a month.

Summary of “before”:

Other than costing much more money, there are other disadvantages of this setup:

Table of Contents

Step 1: Make your site static

My own personal site written in Python/Flask was pretty easy to migrate, since it didn’t have any direct database communication, or really anything substantial that was done on the server side, except generating the content upon startup. It had Flask templates that were fed different variables, and only a few routes, making it a perfect candidate for Frozen-Flask. Just paste their 5 or so lines of code into a “freeze.py” file (or, use any other valid name) and run python freeze.py .

You may need to edit your original code until you’re able to run freeze.py without errors. For example, I had a “MimetypeMismatchWarning” which made the website not work, so I added an “html” extension to a few @app.route annotation parameters. Overall, this step took me about 10 minutes.

Step 2: Upload your site to S3

Okay, now you will need to make sure you have an AWS account, and access to it. You can use local credentials with the aws command line tool (installation instructions here). You also need to have a bucket. If you don’t, make one.

Running freeze.py (see above), by default, puts everything into the build directory (with an index.html and all of the other files/directories needed for the site), so we will upload from build (or a directory of your choice).

aws s3 sync build s3://mycontentsite.biz

Step 3: Make a CloudFront Distribution and Origin

Follow the instructions on step 2 under “Using a REST API endpoint as the origin, with access restricted by an OAI”: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/

Note that for the above instructions:

Main “Distributions” page has “Create Distribution” buttonThe OAI from the CloudFront distribution’s origin should match what’s in the S3 bucket policy (the blurred part)

Now, navigate to the CloudFront domain in order to check that the site is accessible and looks good. E.g. https://d2zkx5nignyw0a.cloudfront.net/

The actual work to set up a distribution and origin took about 10 minutes, but it took over 20 minutes to figure out that I was missing a CloudFront Behavior (the knowledge which came from @bax1billion).

Step 4: Enable SSL

This will basically allow “https://” to precede your domain, so that browsers don’t mark your site as “insecure”. This is important if you expect that users will be inputting information on your site.

This step may take a few hours to complete in the background, but only a minute of active work.

Navigate to Certificate Manager, and follow Step 3 on the same page as above (https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/). Note that the docs don’t seem to mention Certificate Manager. It took a minute to “Request” the certificate, but a few hours before the Status became “Issued”. Make sure that your Route 53 hosted zone has a CNAME record, which should have been created when you clicked on the button to do so, when requesting the Certificate.

Certificate Manager home pageCertificate Manager will add a CNAME record matching your certificate (see blurred line). Make sure to click on the button for doing this, when requesting your certificate. This image is from the Route 53 hosted zone.

Step 5: Add the Alternate Domain Name to CloudFront Distribution

This 5 minute step is documented on https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-cloudfront-distribution.html

Go back to your CloudFront distribution and click on “Edit” next to Settings. Add an alternate domain name for your domain whose certificate you just requested (the spelling must match that in both Route 53 and the SSL certificate). Right below that field in the “Custom SSL certificate” dropdown, select the matching certificate. Make sure the name matches exactly!

Distribution Settings (Edit button)

Step 6: Edit DNS “A” record in Route 53

This takes no more than 15 minutes even if you don’t do DNS stuff regularly. Follow steps 4 through 7 in https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-cloudfront-distribution.html

Your A and AAAA records should now have the “Alias” option turned on, which creates a dropdown that includes your CloudFront distribution, which should be selected in those two records.This is an example “A” record following the linked docs. The “AAAA” record is similar.

Step 7: Check your website

It’s time to try out your website in a browser!