Revision #1 on Feb 10th, 2016: Included instructions for installing Jekyll 3.1.x, since it requires Ruby 2.0 or better. Revision #2 on Mar 20th, 2018: Included instructions for installing Jekyll 3.7.x on OS X High Sierra, since it requires Ruby 2.1 or better.
1. TECH.ASIMIO.NET = AWS S3 + JEKYLL + JENKINS
Creating a blog was in my TODO list for too long, being too ambitious prevented it me from just getting it up. WordPress or Drupal + phpCAS or Java-based blog/CMS + Jasig CAS for Single Sign On between the blog + Asimio.net; it was too complex and time-consuming.
A static blog hosted on AWS S3, built with Jekyll and Jenkins— Orlando Otero (@orly_otero) July 1, 2016
Read at: https://t.co/6yea0ZtVRL
Earlier this year I read Soft Skills: The software developer’s life manual which I found it to be a really interesting book and that was it, I was decided to start a blog, but took a different route than what was suggested, it had to be simple and fun where I would learn something new in the process and after a day of quick research, I decided it to use Jekyll to generate a static blog and hosted it on Amazon S3 since I’m already using a couple of AWS services with Asimio.net.
In this post I’ll detail how to accomplish this and optionally, use Jenkins to implement a Continuous Deployment approach to automatically deploy the blog when new posts become available. It will also serve me as a short how to guide in case I decide to create a static site again.
- 1. TECH.ASIMIO.NET = AWS S3 + JEKYLL + JENKINS
- 2. SETUP AWS S3 BUCKET
- 3. AWS S3 STATIC SITE AND DNS
- 4. SETUP JEKYLL
- 5. PUBLISHING JEKYLL-GENERATED STATIC SITE TO AWS S3
- 6. STATIC BLOG’S CONTINUOUS DEPLOYMENT WITH JENKINS
- 7. YET ANOTHER IMPROVEMENT
2. SETUP AWS S3 BUCKET
In this section an S3 Bucket will be created to host a static website. Once completed it will serve a simple index.html page.
- Sign up to create an AWS Account or
- Login to AWS S3 if you already have one
- Click on Services -> S3 -> Create Bucket. If you plan to host it using a domain or subdomain, make sure the bucket’s name matches your domain or subdomain name. Keep in mind that bucket names are global to AWS. For the scope of this blog entry, I chose Name and Region to be: test.asimio.net and US Standard respectively.
- Click on newly created bucket on the left side -> Properties at the top-right side and expand Static Website Hosting section to edit the values as displayed in the next image:
- Click Save and make sure you take note of the Endpoint value, it will be needed it later. It’s test.asimio.net.s3-website-us-east-1.amazonaws.com for the purpose of this tutorial.
- Expand Permissions section, found on top of previously edited Static Website Hosting section, click Add bucket policy button and enter the following policy in the Bucket Policy Editor pop-up dialog. It’ll make Bucket’s content publicly accessible.
Make sure yours is updated to match your bucket name. Click Save to store policy and close the dialog and once more to save Permissions.
- Create a simple index.html page in your PC with this content:
- Upload it to the newly created S3 bucket via All Buckets (top-left side) -> test.asimio.net (or your bucket name) -> Actions -> Upload … -> Start Upload
- At this point bucket should include a single file named index.html. I mentioned earlier that the Endpoint for the bucket used for this how-to was test.asimio.net.s3-website-us-east-1.amazonaws.com, just enter that in a Browser and it should display: Hello Blog!
Now that an S3 bucket has been setup and it’s successfully serving a static .html file, let’s setup Ruby and Jekyll.
3. AWS S3 STATIC SITE AND DNS
Actually, before setting up Jekyll, let’s fix that weird static site URL.
I mentioned earlier that Asimio.net is using a couple of Amazon services, Route 53 is one of them, but my guess is that this should work with most DNS providers.
Since I’m hosting the blog as a subdomain of asimio.net domain, I just need to add a CNAME record for test.asimio.net:
4. SETUP JEKYLL
This guide needed to be updated once I upgraded to OS X Sierra and needed to re-install Jekyll 3.1.x, the latest as of Revision #1, but was at version 2.5.x when this post was first published.
This post needed to be updated once I upgraded to OS X High Sierra and needed a clean install of Jekyll 3.7.x, the latest as of Revision #2, requiring Ruby version >= 2.1 while High Sierra ships with Ruby 2.0.
- Ubuntu 14.04
- Jekyll 2.5.x
Previous command installs Ruby 1.9.3 which is good for Jekyll 2.5.x but not for Jekyll 3.1.x.
- Ubuntu 14.04
- Jekyll 3.1.x requires Ruby 2.0 or better
The last commands section includes a couple of gems that are used by this blog but are not required for test.asimio.net example site being set up.
Mac OS X Sierra should have Ruby 2.0 already bundled
Mac OS X High Sierra ships with Ruby 2.0 but Jekyll 3.7.x requires Ruby version >= 2.1.
brew package manager:
If it still shows
ruby 2.0.x ... [universal.x86_64-darwin16], you could also try addind these commands to your
- Ubuntu 14.04 and Mac OS X
Depending on when the preceding commands section is run, it might install Jekyll 2.5.x, 3.1.x or 3.7.x.
Technically, jekyll would be the only gem needed, but tech.asimio.net
uses Freshman21 Jekyll theme and it requires jekyll-sitemap and sass gems as well.
I would suggest to start a new project downloading an existing Jekyll theme, but for the purpose of this post, creating a simple one from scratch is fine.
- Create a new test site
- Open it at localhost:4000
5. PUBLISHING JEKYLL-GENERATED STATIC SITE TO AWS S3
In this section I’ll setup an AWS IAM User for publishing/deployment to AWS S3 purposes, install a useful gem, s3_website, along with its dependencies and configure it with AWS credentials.
- Ubuntu 14.04 - Install Java
- Ubuntu 14.04 and Mac OS X - Install s3_website plugin
- Create AWS IAM Group
- Login to AWS IAM if you haven’t logged in yet.
- Click on Groups on the left-side menu
- Click Create New Group
- Enter Group Name, which I’ll name test.asimio.net-s3-deployer-group where test.asimio.net is the name of the S3 bucket where the site will be deployed to.
- Leave Policy Type empty and click Next then Create Group
- Click on the newly created Group, expand Inline Policies section to create a new policy and click Select
- Update Policy Name and Policy Document as shown in the picture (JSON Policy could be found next to the picture). Click Apply Policy
- CREATE AWS IAM USER
- Login to AWS IAM if you haven’t logged in yet.
- Click on Users on the left-side menu
- Click Create New Users
- Enter test.asimio.net-s3-deployer-user, keep Generate an access key for each user checked and click Create
- Click Download Credentials and keep this .csv file safe then click Close.
- Click on the newly created User -> Attach User to Groups and select test.asimio.net-s3-deployer-group -> Add to Groups
At this point, test.asimio.net-s3-deployer-user will be able to deploy/publish a site hosted on AWS S3.
- CONFIGURE s3_website FOR my-new-site
This creates a file named s3_website.yml in the site’s root directory that would still need to be edited
with credentials from previously created AWS IAM User, which could be found in the downloaded .csv file.
Open it and update these settings:
Save it and run:
I’m not using Cloudfront so:
I answered “N” to Do you want to deliver your website via CloudFront, the CDN of Amazon? question.
- DEPLOY my-new-site to AWS S3 BUCKET
After changes are made to the site, it can be published executing:
Open it at test.asimio.net
6. STATIC BLOG’S CONTINUOUS DEPLOYMENT WITH JENKINS
I’ll go a step further, I’ll setup Jenkins to automatically deploy the site after a new post is added.
- Site under SCM. I have a Stash instance running in my home lab that includes a few repos, this blog being one of them.
- Jenkins instance. I also have a Jenkins master running in my home lab and a few Jenkins slaves to build artifacts, this is what I’ll use to build and deploy my blog.
- Jenkins S3 Plugin
- The Jenkins slave was also setup according to instructions in SETUP JEKYLL section.
I would also like to prevent the site from building and deploying when there are meaningless changes, like checking changes into the site’s _drafts directory. The strategy I came up with was to create a Git branch for every new blog entry, work with this branch is done either in _drafts or _posts directories, once an entry is ready to be published, it makes it to the _posts directory of the branch and then merged it with master which should cause Jenkins to trigger build job.
- S3 Jenkins Plugin Configuration. Once completed, s3_website-related steps as described in CONFIGURE s3_website section won’t be needed since this plugin would be doing that work. Jenkins -> Manage Jenkins -> Configure System -> Amazon S3 profiles -> Add
Update Access Key and Secret Key with same values used when configuring s3_website in CONFIGURE s3_website section.
- Jenkins Job. Create Freestyle project named test.asimio.net. Since I’m building this artifact in a VM, I’m restricting it to build in a slave labeled jekyll so that other VMs without required packages don’t pick this job up -> Setup Git repo -> Build -> Execute shell with this content:
Then add Post-build Actions -> Publish artifacts to S3 Bucket configured as shown below:
- Seeing it in Action
7. YET ANOTHER IMPROVEMENT
I recently landed on this blog entry and noticed there could be another improvement to the process I’m using to deploy my blog, include html-proofer gem to find broken links. I haven’t used it yet, but you might find it useful.
If you found this post helpful and would like to receive updates when content like this is published, sign up to the newsletter.
This website includes affiliate links to Udemy, Amazon, Google. This means if you click an affiliate link and buy a product, I might earn a commission at no extra cost to you.