Skip to main content

Publish your Koriander blog with S3 and CloudFront

Published: August 30, 2026

This tutorial walks you through all the steps needed to set up your own Koriander CMS blog on AWS S3 and CloudFront.

Here's what you're going to learn in this tutorial:

  1. How to install Koriander CMS and make your first page.
  2. What AWS resources you need to upload your Koriander site.
  3. How to configure Koriander to upload your site.

Install Koriander CMS

Install Koriander CMS on your computer using pipx. Install pipx using the official pipx installation instructions. Open a terminal on your computer and make sure that you can run pipx by typing the following command and pressing the Enter key:

pipx --version

pipx version on the author's computer
pipx version on the author's computer Open in new tab (full image size 38 KiB)

On the author's computer this command prints the following:

1.8.0

If you see pipx printing a version number like 1.8.0, you're ready to install Koriander CMS on your computer. Type the following command and press the Enter key:

pipx install koriander

Install Koriander CMS with pipx install koriander
Install Koriander CMS with pipx install koriander Open in new tab (full image size 47 KiB)

When pipx finishes installing Koriander CMS, pipx install koriander prints the following:

  installed package koriander 0.18.0, installed using Python 3.13.13
  These apps are now globally available
    - koriander
done! ✨ 🌟 ✨

The version numbers Koriander CMS 0.18.0 and Python 3.13.13 may be different when you install Koriander CMS.

Launch Koriander CMS

Type the following command in your terminal to launch Koriander CMS:

koriander

When you launch Koriander CMS, your browser should automatically open the index page. If your browser doesn't open the index page, copy the green address below the Log in with the following link: line and paste it into your browser address bar:

Koriander CMS prints a log in link that you can open in your browser
Koriander CMS prints a log in link that you can open in your browser Open in new tab (full image size 129 KiB)

The next picture shows the Koriander CMS index page at /index.html. Press the Edit link in the top toolbar to edit the page contents.

Koriander CMS automatically opens in your browser
Koriander CMS automatically opens in your browser Open in new tab (full image size 92 KiB)

You've opened the page editor for the index page. In Koriander, pages use Markdown for formatting. Here's the default index page content when you've just installed Koriander:

Edit the page using the Edit page link
Edit the page using the Edit page link Open in new tab (full image size 131 KiB)

Add your own page content on the left side of the Markdown editor:

Add your own text to customize the index page
Add your own text to customize the index page Open in new tab (full image size 104 KiB)

Save your changes by pressing the Save button in the right menu under Publish:

Save your changes by pressing the Save button
Save your changes by pressing the Save button Open in new tab (full image size 110 KiB)

Go back to the start page by pressing the View on site link in the right menu under Publish.

Follow the View on site link under Publish
Follow the View on site link under Publish Open in new tab (full image size 107 KiB)

This screenshot shows how the index page looks like after changing it:

After pressing the Save button, the index page at /index.html now shows your changes.
After pressing the Save button, the index page at /index.html now shows your changes. Open in new tab (full image size 80 KiB)

Set up AWS resources

S3 Bucket

Create an S3 bucket in your preferred AWS zone. Visit the Creating a general purpose bucket tutorial and refer to the Using the S3 console section if you're using the S3 console.

Here you can see the screens that the author walked through to create a test bucket called “koriander-bucket” for this tutorial. First, go to the S3 buckets page in the AWS console:

Go to AWS S3 from the AWS console start page
Go to AWS S3 from the AWS console start page Open in new tab (full image size 118 KiB)

On the Buckets overview page, press the orange Create bucket button:

Press Create bucket to start creating a bucket
Press Create bucket to start creating a bucket Open in new tab (full image size 53 KiB)

Enter a name for your bucket in the following Create bucket screen:

Enter your desired bucket name under Bucket name
Enter your desired bucket name under Bucket name Open in new tab (full image size 59 KiB)

Review the other settings and finish creating your bucket by pressing the Create bucket button:

Press Create bucket to finish creating your bucket
Press Create bucket to finish creating your bucket Open in new tab (full image size 63 KiB)

CloudFront Distribution

Now that you've created your S3 bucket you need a CloudFront distribution to make the S3 bucket contents publicly available. Go to CloudFront in the AWS console and press the orange Create distribution button:

Press Create distribution
Press Create distribution Open in new tab (full image size 45 KiB)

Give your CloudFront distribution a name and press Next. In this example, the distribution name is “koriander-cloudfront”:

Enter a Distribution name and press Next
Enter a Distribution name and press Next Open in new tab (full image size 75 KiB)

On the next Specify origin screen, make sure that you select Amazon S3 as Origin type and press the blue Browse S3 button:

Select Amazon S3 as Origin type and press Browse S3
Select Amazon S3 as Origin type and press Browse S3 Open in new tab (full image size 77 KiB)

Select your bucket in the S3 Origin popup and confirm with Choose:

Select your bucket and confirm your choice by pressing Choose
Select your bucket and confirm your choice by pressing Choose Open in new tab (full image size 53 KiB)

Decide whether you need a Web Application Firewall (WAF) and confirm your decision by pressing the Next button:

Press Next after choosing your WAF setting.
Press Next after choosing your WAF setting. Open in new tab (full image size 40 KiB)

Finish creating your CloudFront distribution by pressing Create distribution on the next screen:

Press Create distribution after reviewing the new CloudFront distribution details
Press Create distribution after reviewing the new CloudFront distribution details Open in new tab (full image size 81 KiB)

After you press Create distribution, the AWS console should show you your new CloudFront distribution and its Distribution domain name. This is where you can access your Koriander site once you've finished uploading it to your S3 bucket.

The AWS console shows Successfully created distribution
The AWS console shows Successfully created distribution Open in new tab (full image size 53 KiB)

Finally, you'll set up a root object for your CloudFront distribution. Press the Edit button next to Settings. Enter “index.html” under Default root object - optional. Scroll down and press Save changes.

In your distribution settings, enter index.html under Default root object - optional
In your distribution settings, enter index.html under Default root object - optional Open in new tab (full image size 127 KiB)

Configure an IAM user for your S3 bucket

Go to IAM and create a user for your newly created S3 bucket. Review the Create an IAM user in your AWS account tutorial on docs.aws.amazon.com if you're not sure how to continue.

Press the orange Create user button:

Press Create user to create a IAM user
Press Create user to create a IAM user Open in new tab (full image size 65 KiB)

Enter the IAM user name. In this example, the user name is “koriander-bucket-user”. Press Next to continue to the Set permissions screen.

Enter a user name and press Next
Enter a user name and press Next Open in new tab (full image size 55 KiB)

On the Set permissions screen, select Attach policies directly under Permissions options and press the blue Create policy button:

Select Attach policies directly and then press Create policy
Select Attach policies directly and then press Create policy Open in new tab (full image size 72 KiB)

This opens a new window. In the Policy editor, enter the following policy 3 while adjusting the “koriander-bucket” name for the bucket name that you've chosen:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListObjectsInBucket",
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": ["arn:aws:s3:::koriander-bucket"]
        },
        {
            "Sid": "AllObjectActions",
            "Effect": "Allow",
            "Action": ["s3:*Object"],
            "Resource": ["arn:aws:s3:::koriander-bucket/*"]
        }
    ]
}

Here's what it should look like when you enter your user policy. Press Next to continue creating your IAM policy:

Paste the policy and make sure to adjust the bucket name. Press Next to continue
Paste the policy and make sure to adjust the bucket name. Press Next to continue Open in new tab (full image size 80 KiB)

On the next Review and create screen, enter a name for the policy and press Create policy.

Enter a Policy name and press Create policy
Enter a Policy name and press Create policy Open in new tab (full image size 105 KiB)

On the next screen you should see the follow green confirmation:

Policy koriander-bucket-policy created

The AWS console shows you a success message Policy … created when you create your policy. You can close this window.
The AWS console shows you a success message Policy … created when you create your policy. You can close this window. Open in new tab (full image size 72 KiB)

Close this Policies window and go back to the IAM user creation screen. Press the refresh button in the policy selector. Attach the “koriander-bucket-policy” to the IAM user by selecting it in the following list and pressing Next.

Press the refresh button, filter policies by Customer managed , select your policy, and press Next
Press the refresh button, filter policies by Customer managed, select your policy, and press Next Open in new tab (full image size 81 KiB)

Finish creating your user by pressing the orange Create user button:

Finish creating your IAM user and press Create user
Finish creating your IAM user and press Create user Open in new tab (full image size 63 KiB)

You should now see your new “koriander-bucket-user” in the list of IAM users:

You should now see your new user in the IAM users list. Select your user to create an access key
You should now see your new user in the IAM users list. Select your user to create an access key Open in new tab (full image size 65 KiB)

Open the “koriander-bucket-user” and select the Security credentials tab and press Create access key.

Select the Security credentials tab and press Create access key
Select the Security credentials tab and press Create access key Open in new tab (full image size 155 KiB)

Select Other1 as your use case on the next screen and press Next:

Select Other and press Next
Select Other and press Next Open in new tab (full image size 147 KiB)

Enter a description for your access key and press Create access key:

Enter a Description tag value and press Create access key
Enter a Description tag value and press Create access key Open in new tab (full image size 89 KiB)

On the next screen, press Download .csv file to download your access key.

Press Download .csv file to download your access key details
Press Download .csv file to download your access key details Open in new tab (full image size 28 KiB)

Go to the user's page and select the Security credentials tab again. Confirm that your access key is there:

This is what you should see when you've created your access key
This is what you should see when you've created your access key Open in new tab (full image size 10 KiB)

The .csv file should contain the data for the access key that you've just created:

The .csv file contains your access key details
The .csv file contains your access key details Open in new tab (full image size 76 KiB)

You're going to use the Access key ID and Secret access key in the next step.

Configure S3 uploads in your Koriander CMS site

Open the Koriander administration screen by following the Admin link in the toolbar:

Follow the Admin link in the Koriander CMS toolbar
Follow the Admin link in the Koriander CMS toolbar Open in new tab (full image size 81 KiB)

In the administration screen, select Site settings in the Koriander CMS table.

Under Koriander CMS follow the Site settings link
Under Koriander CMS follow the Site settings link Open in new tab (full image size 109 KiB)

Select the grey S3 upload link next to the Change Site settings title.

Next to Change Site settings press S3 upload
Next to Change Site settings press S3 upload Open in new tab (full image size 116 KiB)

On the next screen, select AWS S3 under S3 endpoint type and press Continue:

Select AWS S3 and press Continue
Select AWS S3 and press Continue Open in new tab (full image size 111 KiB)

Select your AWS S3 region. The bucket in this tutorial lives in the “ap-southeast-2”2 AWS S3 region. Press the Continue button.

Select your AWS S3 region and press Continue
Select your AWS S3 region and press Continue Open in new tab (full image size 102 KiB)

On the next screen, enter your S3 bucket, S3 access key ID and S3 access key. Under S3 bucket, enter the name of the bucket that you've just created. For S3 access key ID and S3 secret access key, enter the two values from the .csv file that you've downloaded. Press Continue to confirm:

Enter your S3 bucket name , Access key ID , Access key , and press Continue
Enter your S3 bucket name, Access key ID, Access key, and press Continue Open in new tab (full image size 112 KiB)

You're ready to upload your site to S3 and publish it with CloudFront.

Upload to S3

Pressing Continue should take you to the Upload to S3 screen. Select Dry run and press Upload.

When Koriander performs a Dry run, it checks which files in your site have changed or which ones you've added or removed. You can always try a Dry run if you're not sure what changes.

Select Dry run and press Upload
Select Dry run and press Upload Open in new tab (full image size 112 KiB)

Koriander CMS now tells you which files it would upload to your S3 bucket, but hasn't yet uploaded since it's a Dry run:

After the Dry run , Koriander shows you which files it would upload
After the Dry run, Koriander shows you which files it would upload Open in new tab (full image size 137 KiB)

Press Upload now to upload your Koriander CMS site to your AWS S3 bucket. This takes you to a results page:

Press Upload now to upload your site
Press Upload now to upload your site Open in new tab (full image size 107 KiB)

Confirm that you've uploaded your file to your bucket by opening the bucket in the AWS Console:

Open your bucket in the AWS console and select the Objects tab to view your uploaded files.
Open your bucket in the AWS console and select the Objects tab to view your uploaded files. Open in new tab (full image size 139 KiB)

Go to your CloudFront distribution. You should see the Last modified field updating. Note the “…cloudfront.net” Distribution domain name:

The Last modified field in your CloudFront distribution should update
The Last modified field in your CloudFront distribution should update Open in new tab (full image size 27 KiB)

Now open the “…cloudfront.net” Distribution domain name in your browser. You should see your own Koriander CMS site appear:

Open the "…cloudfront.net" Distribution domain name in your browser
Open the "…cloudfront.net" Distribution domain name in your browser Open in new tab (full image size 85 KiB)

You have just published your Koriander Site using AWS S3 and CloudFront.

Here are some more things that you can do:


  1. For local tools, AWS advises you to use an "Integrated Development Environment which supports the AWS Toolkit", which isn't realistic for Koriander to support at the moment. Further, the Learn more link directs you to a generic landing page with tools for vibecoded projects that doesn't explain how one should go ahead and integrate this into the Koriander CMS. If anything, AWS does their users a disservice by not providing a safer escape hatch that works for local tools. Surely they could also make it easier to add automatic expiry to access keys. ↩

  2. The AWS console lists "ap-southeast-2" as "Asia Pacific (Sydney)". You can see the region name in the console address. Example: http://ap-southeast-2.console.aws.amazon.com/s3/buckets. The AWS S3 documentation also has a page documenting S3 endpoint names. ↩

  3. Grant read and write access to Amazon S3 bucket objects further describes this policy. ↩

  4. When you open your bucket to the public, anyone can read anything inside the bucket. Be sure you use this bucket only for hosting your Koriander site. You may want to place AWS Cloudfront before the S3 bucket to avoid having to make this bucket public. ↩

Tags

I would be thrilled to hear from you! Please share your thoughts and ideas with me via email.

Back to Index