Cookiecutter Static Site Template 1.0 Documentation¶
This is the documentation for the Cookiecutter static site template, hosted on GitHub. The template may be used by Cookiecutter to generate a project that will allow for easy and rapid deployment of a static website (a website comprised of only HTML, CSS, and JavaScript).
This documentation is written like a walkthrough, intended for beginners with little to no programming experience. While this template relies on programming tools, using the template requires no programming.
If you are a developer, the Read Me document in the GitHub project is likely enough for you.
Table of Contents¶
Introduction¶
This project may seem silly. After all, Amazon provides a full tutorial on how to set up a static website in the cloud using S3 buckets and a CloudFront distribution. (You can also watch a YouTube video with similar content.)
So why use this template to generate a template? Well, the difficulty with the tutorial is that it focuses entirely on the visual web console. The net effect is that it takes time, is easily forgotten, and is not reporoducible with code.
Far worse, however, is that the official Amazon tutorial does not follow best practices:
- user setup is not covered
- the website is unsecured (no TLS certificate)
- DNS speed is ignored in favor of a bucket redirection trick
The cookiecutter-static-site
template project aims to:
- be fast
- be easily reproducible
- generate the cloud infrastructure (with two commands)
- use a TLS security certificate to secure the website
- optimize DNS lookups for the website domain
- be forgettable (the template provides a
Makefile
with all of the commands you’ll need)
If the template were to recreate the entire Amazon tutorial, only two commands would be necessary.
aws cloudformation create-stack
aws s3 sync
This walkthrough is about mise-en-scène. Getting setup is a little involved. You’ll have to get setup once, but you’ll be off to the races for repeat performances.
This walkthrough is aimed at people who have dabbled with the commandline, but who may not be comfortable with it yet. We’ll walk through each and every step needed to get your site up in the cloud. Your next step will be to install the necessary prerequisites.
If you are a developer, the Read Me document in the GitHub project is likely enough for you.
Installing Project Prerequisites¶
This project relies on several programming tools, but can be used without knowledge of programming languages.
Note
Manually downloading and installing software—as indicated by the instructions in this walkthrough—is fine if you are not doing this very often. If you are learning to develop or code, I urge you to look into package management software, as it will save you time in the long run. If you are on BSD or Linux, your system comes with a package manager. If you are on a Mac, I recommend MacPorts or Homebrew. If you’re on Windows, I hear good things about Chocolatey.
Section Goals¶
This section prepares you for:
- Using the
cookiecutter-static-site
template to generate a project - Generating security certificates to secure your website
- Using the provided scripts in your new project to upload (deploy) your static website to the cloud
This section lists all of the tools required to perform the three steps above. Rather than provide detailed instructions for each installation, this section refers you instead to installation instructions of each utility.
The tools below are listed in the order they will be used.
Python and pip¶
Python version 2.7, 3.3, 3.4, or 3.5 must be installed for both project generation and site deployment. If you’re on a modern Mac, Python 2.7 is already installed for you (but you are encouraged to upgrade Python). If you’re on Windows, you will need to install Python. If you’re on BSD or Linux, you don’t need my help.
Python is installed with pip
, a package manager for Python
packages/applications.
virtualenvwrapper¶
virtualenvwrapper
is an optional tool that allows for the logical
separation of installed packages. I highly recommend using it.
If you are on Windows, you may wish to use either
virtualenvwrapper-win
or virtualenvwrapper-powershell
. The
installation guide for virtualenvwrapper
has more information.
OpenSSL¶
Named after the now-deprecated Secure Sockets Layer security protocol, OpenSSL is an open-source utility that allows for many cryptographic and security applications. In this walkthrough, you will use it to obtain a TLS security certificate for your website.
If you’re on Windows, you will need to google installations instructions (Sorry, I cannot help you here.) If you’re on a Mac, then OpenSSL is already installed. On Linux and BSD, if OpenSSL is not on your system, then your package manager should quickly fix that problem for you.
jq¶
Whereas Python, pip, and virtualenvwrapper are tools for generating
the static site deployment project, jq
is a tool necessary for the
deployment of the site to the cloud. You will not need to use the tool
yourself, but the deployment scripts we will use do rely on the tool.
Downloads and installation instructions may be found here.
Prologue: Signing up for Amazon Web Services¶
This project will give you the tools to deploy your website to the Amazon Web Services (AWS) Cloud. For this to happen, however, you need to have an account with AWS. The process is very straightforward, and the actual signup is not detailed here.
Once you’re done, you’ll be greeted by the overwhelming AWS console.

AWS Console, accessible by clicking the top left icon.
Section Goals¶
Once you have an account, your goal will be to create a user to allow command-line access to the cloud. However, before we can create the user, we will have to secure the cloud.
Both securing an account and creating a user happen in the Identity and Access Management (IAM) section. You can find it on the AWS console under Security & Identity, or you can click here if you’re currently logged in.
Securing your Account¶
When you are greeted by the IAM Management Console, you will discover a list of actions to take to secure your cloud resources.

Security Task List in the AWS IAM Management Console
By default on new accounts, the first item will have been completed for you (if your account is older, this may not have been done for you).
The second item, Multi-Factor Authentication (MFA), will allow us to setup Two-Factor Authentication using a smartphone. This is certainly not required, but I heartily recommend it. Click on the Activate MFA on your root account item in the list, then on Manage MFA, and then follow the instructions. You will need to install Google Authenticator on your smartphone to properly setup the service.
You may have to hit the Dashboard link towards the top left of your window to get back to the IAM console. You’ll be greeted by a green checkmark in your task list.

Security Task List with MFA Setup Complete
We can then skip to the end of the task list, and setup password restrictions for any future users. Click on Apply an IAM password policy and then on Manage Password Policy. You’ll be greeted with a page with a number of choices. My usual selection consists of the following (but feel free to pick your own):

Andrew’s Password Policy Settings.
Once you successfully apply a password policy, the task list will appear with three checkmarks:

Security Task List with Password Policy Complete
Creating a User and applying permissions with a Group¶
With user management comes the idea of permissions: we want to restrict what a user can do on our system for security purposes. The best way to do this is to create a group, and assign permissions to that group. We then add users to that group, rather than adding permissions directly to the user.
Creating a Group with Permissions¶
Our first task is thus to create a group. In the IAM console, in our security task list, click on Use groups to assign permissions and then on Manage Groups. Alternatively, you can simply click on Groups in the sidebar on the left.

Groups button in the IAM Console Sidebar
On this new page, click on the Create New Group button. This will bring you to the Create New Group Wizard. I will call the new group administrators and then click Next Step at the bottom right of the screen. This brings us to the long list of permissions we can apply to our new group.

Groups button in the IAM Console Sidebar
As we’re creating a user policy for our own command-line access, we want to give ourselves full access to the cloud. We therefore click the checkbox next to AdministratorAccess, and click Next Step.

AdministratorAccess Policy in the AWS IAM Create New Group Wizard
AWS will give us an overview of our new group, allowing us to click Create Group to actually finish the task.

AdministratorAccess Policy Review in the AWS IAM Create New Group Wizard
Creating a User¶
Finally, we can create a user, and then add the user to our administrators group.
Much like with groups, we can either click on Create individual IAM users in the task list and then click on Manage Users, or use the Users link in the sidebar. On the new page, click Create New Users.
We only need a single user, so I will only fill in the top text field. Make sure that Generate an access key for each user checkbox at the bottom of the textfields is checked (the default).

Create User in AWS IAM Console
With this new user created, you will be prompted to download the authentication credentials for the new user (the button at the bottom right of the screen on the new page). You will need this information when generating the static site project with our template. I recommend saving this information in a safe location, such as a password manager, as this information gives full access to your AWS account.
After you’ve downloaded and saved your credentials, your new user will appear in the list of users.

New User in User List of AWS IAM Console
If you click on the new user, the full profile will be displayed.

New User Profile
Warning
The Amazon Resource Numbers (ARNs) associated with various cloud resources are unique, and should be kept semi-secret.
Use the Add User to Group button to add the new user to the administrators group.
Having created a user and assigned it a group with permissions, the task list for securing your account is now complete. Congratulations!

Generating a Static Website Project¶
With all of your Prerequisites installed, and an AWS account with IAM user account, we can actually generate the project that will quickly deploy your website.
Section Goals¶
In all cases, our goal is to use cookiecutter
to download the
cookiecutter-static-site
project (this project!) to jump start our
work by generating a static website project. The project will make
deploying the static website to the cloud as easy as possible.
In the first walkthrough
below, we will do this without any complications. In the second
walkthrough, we will use virtualenvwrapper
to separate our project
tools from other projects.
virtualenvwrapper : to use, or not to use?¶
If you’re planning to learn Python, or use any other Python projects, I
strongly encourage you to use virtualenvwrapper
(discussed and
installed in the Prerequisites section).
If you have no intention of using multiple Python projects or
programming Python, you do not need to use virtualenvwrapper
. Even if
you plan to generate multiple static websites using this project
template, you will not need virtualenvwrapper
.
Generating the project without virtualenvwrapper¶
Our first task is to install cookiecutter
. In your terminal, write
the following code, without the dollar sign (which is shown to designate
the fact that this is a terminal).
$ pip install cookiecutter
Now that you have cookiecutter
installed, we can use cookiecutter
to use the cookiecutter-static-site
template to create our new
project.
$ cookiecutter gh:jambonsw/cookiecutter-static-site
cookiecutter
will prompt you for information to customize your project.
Below is an example of the questions asked (but may not reflect the most
current questions!).
project_name [My Static Website]: JamBon Software
project_slug [jambon-software]: jambonsw
domain_name [example.com]: jambonsw.com
aws_access_key_id [XXXXXXXXXXXXXXXXXXXX]:
aws_secret_access_key [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]:
The project slug will be used to create a new directory (folder) with the project code in it. You can use the code below to navigate into directory using the terminal (you’ll need to replace jambonsw with the slug of your own project).
$ cd jambonsw # replace with the value you specified when prompted by cookiecutter
Note
Your new project will automatically initiate a git project. If you do not want to use version control, or wish to use another version control system, you can easily delete the git project with the code below.
$ rm -rf .git # Warning: deletes with impunity
$ rm -f .gitignore # Warning: deletes with impunity
We then install all of the smaller Python tools (not listed in the prerequisites section!) necessary for our project.
$ pip install -r requirements.txt
Please note that whenever you work on this project, the scripts provided
will need to have specific information available: specifically, the
scripts expect to have several environment variables available in the
environment. To make your life easier, all of these variables are
specified in env.sh
. You will need to enter the command below
whenever you start working on this project (one of the major advantages
of virtualenvwrapper
is that we only need to specify the variables
once).
$ source env.sh
Warning
Note that env.sh
contains information that would allow someone to
hack your website. Keep it safe and secure!
The unenv.sh
script removes these secret variables from your
environment. Us the command below when you stop working on your project
(or you can simply close your terminal window).
$ source unenv.sh
Your project is ready to go! You can either read below to see how to do
the same with virtualenvwrapper
, or jump directly to instructions
about how to obtain a security certificate.
Generating the project with virtualenvwrapper¶
Much like in the first walkthrough above, the goal is to use cookiecutter
to generate a project from the cookiecutter-static-site
project.
However, this time we will separate the project logically according to
terminal environment, making it easy to run other code projects.
Make sure that you have properly installed virtualenvwrapper
, and
that you’ve created the necessary environment variables, as specified in
the installation guide.
To start, we want to create a new virtual environment. In the code
below, I name the project jambonsw
, in anticipation of the fact that
I will name the poject slug the same. The project slug is primarily used
to specify the name of the directory that contains the project. You may
follow this convention, or name the environment as you please.
Warning
Do not copy the dollar signs or anything before the dollar signs in the code!
$ mkvirtualenv jambonsw
Your terminal will change to show you that you are now working in a virtual environment by printing the name of the environment in parentheses before the dollar sign.
Use the code below if you wish to leave the environment.
(jambonsw) $ deactivate
To enable an existing environment, use the workon
command with the
name of the environment.
$ workon jambonsw
In this environment, we then install cookiecutter
. Note that
cookiecutter
will only be available if we’re in the environment!
(jambonsw) $ cookiecutter gh:jambonsw/cookiecutter-static-site
As show in the example code in the first walkthrough above, cookiecutter
will prompt you with various
questions to get you started.
We use the project slug (specified by you when prompted) to enter the
project directory (folder). Replace the jambonsw
directory name in
the code below with the slug of your own project.
(jambonsw) $ cd jambonsw
Note
Your new project will automatically initiate a git project. If you do not want to use version control, or wish to use another version control system, you can easily delete the git project with the code below.
$ rm -rf .git # Warning: deletes with impunity
$ rm -f .gitignore # Warning: deletes with impunity
To make our life easier in the long run, we can now associate this
directory with the environment. We do so with the
setvirtualenvproject
command.
(jambonsw) $ setvirtualenvproject
If you use the workon
command while in another directory, the
command will automatically bring you to this directory.
We then install all of the smaller Python tools (not listed in the prerequisites section!) necessary for our project.
(jambonsw) $ pip install -r requirements.txt
One of the key advantages of using virtualenvwrapper
is that we don’t
need to source env.sh
whenever we choose to work on the project.
Instead, we can get virtualenvwrapper
to add the needed environment
variables to the environment for us. We simply copy the file to a place
where
Warning
The command below will replace the existing postactivate
and postdeactivate
file. If
you edited it (perhaps while reading documentation elsewhere), please
back it up or combine the files yourself.
(jambonsw) $ mv env.sh $WORKON_HOME/$(basename $VIRTUAL_ENV)/bin/postactivate
(jambonsw) $ mv unenv.sh $WORKON_HOME/$(basename $VIRTUAL_ENV)/bin/postdeactivate
Your project is ready to go! Before you can deploy the website, however, you’ll need to obtain a security certificate.
Obtaining Security Certificates¶
Unsecured HTTP (the protocol that computers use to communicate over the web) is being phased out. Securing your website is no longer a recommendation; encrypting communication is becoming a modern requirement for websites.
Section Goals¶
The goal of this section is to upload a security certificate for AWS to use to encrypt communication to and from your website.
To obtain a certificate, we must first buy the right to a certificate from a Certificate Authority (CA). We then use OpenSSL to generate cryptographic keys, which in turn allows us to generate a Certificate Signing Request (CSR). We return to the CA with our CSR to obtain (generate and activate) our certificate.
We will then upload three things to AWS:
- a private key
- a security certificate
- a certificate chain proving the validity of our certificate
Using a classical CA will cost you $10-20/year. If you’re feeling daring (and comfortable with the command line) you may be interested in Let’s Encrypt (LE). LE is a free, open-source CA. However, LE is currently in beta, and can be a bit finicky. Once I think LE is ready for you, I will update this section with instructions on how to use it. In the meantime, you’re on your own!
Obtaining a Security Certificate from a Certificate Authority¶
Warning
At the end of the section, you will need to be able to access the email associated with your domain on whois. Please take a moment to ensure that you are able to do so. If you don’t know what this means, please reach out to your domain registrar’s support team.
Security certificates rely on Public-Key Cryptography. To obtain a security certificate, we first need to generate a set of keys. We will then create a Certificate Signing Request (CSR) for the keys, which will be the information a Certifcate Authority needs to generate a certificate for us.
Before any of that, however, we need to buy the ability to request a certificate from a Certificate Authority (CA).
Buying a Certificate¶
When you buy a certificate from a CA, you’re not actually buying the certificate; you’re buying the right to generate and activate a certificate using a CSR in the future.
There are many places to buy a certificate. Among them are (alphabetically):
Generally, you can find better deals (price-wise) when buying through a domain registrar. I currently use NameCheap’s Certificate options, and would recommend either Comodo PositiveSSL for $9/yr or RapidSSL for $10.95/yr. If you’re looking to secure multiple domains, you’ll want to evaluate other options, as AWS only allows a single certificate per website. Of course, if you already have a domain registrar (other than NameCheap), it’s worth seeing what they have to offer. I furthermore recommend reaching out to your registrar’s support to discuss your options.
Once you’ve bought the ability to activate a certificate, you are ready to proceed.
Generating a Certificate Signing Request¶
This section requires the use of OpenSSL, discussed in the Prerequisites section.
All of this work will occur in the certifcates directory of the project you generated last section. You may optionally be in the virtual environment you created.
$ cd certificates
To start, we generate a private key of length 2048 bits using the RSA
algorithm. We store it in a file called private-key.pem
.
$ openssl genrsa 2048 > private-key.pem
Now that we have a private key, we can generate a CSR, creatively named
csr.pem
.
$ openssl req -new -key private-key.pem -out csr.pem
You will be prompted for the values of your certificate. The Common
Name
field must be the main domain name for the website. Not all of
the fields need be specified. In many cases, the CA will ask that the
challenge password be left blank. When answering the questions for
JamBon Sofware, I entered the following values:
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:MA
Locality Name (eg, city) []:Boston
Organization Name (eg, company) [Internet Widgits Pty Ltd]:JamBon Software
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:jambonsw.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Now that you have a CSR, you will have to go to the website where you
bought your certificate, and activate the certificate. At some point in
the process, they will ask you for the certificate request: you will
either upload the csr.pem
file, or else copy the contents of the
file into a textfield.
At the end of the activation process, you’ll have the option of picking how the CA will verify your ownership of the domain end how to send you your certificate. The simplest of these options will be to
Once you have given the CSR to a CA, the CA will begin the process of generating your certificate.
Preparing the Certificate for AWS¶
It would be too simple if your CA simply sent you what you needed. In this section we’ll take a look at what your CA might send you, and what to do with it in that case.
In all cases, the goal will be to have three files:
- a private key
- a security certificate
- a certificate chain proving the validity of our certificate
AWS specifies that all of these files must be in the PEM format.
Note
The text in the sections below will refer to certificates with the
prefix jambonsw_com
, as this walkthrough is based on JamBon
Software’s own website. You will wish to name your certificates
according to your domain. If your domain is andrew.pinkham.com
,
you’d want to name the certificates with the prefix
andrew_pinkham_com
.
You likely only need to read one of the sections below, depending on what your CA sends you.
Receiving a Certificate and Bundle¶
If you receive two files, one will be the certificate and the other will be the chain bundle. When I ordered the Comodo PostitiveSSL, the two files I received were:
jambonsw_com.crt
jambonsw_com.ca-bundle
Save both files to the certificates
directory of your generated
project. In my case, both of the files I received were already in PEM
format. However, just to make sure, we can use OpenSSL to convert them.
$ openssl x509 -in jambonsw_com.crt -outform pem -out jambonsw_com_cert.pem
$ openssl x509 -in jambonsw_com.ca-bundle -outform pem -out jambonsw_com_ca_chain.pem
You could then delete the originals.
$ rm jambonsw_com.crt
$ rm jambonsw_com.ca-bundle
In the certificates
directory, you should now have:
csr.pem
jambonsw_com_ca_chain.pem
jambonsw_com_cert.pem
private-key.pem
You are now ready to upload your certificate to AWS.
Receiving a Certificate, Multiple Chain Certs, and a Root¶
CAs will frequently send the CA chain as seperate files. Your goal is to concatenate them into a single file, from least to most important. If the email you receive does not tell you what the order is, you will have to read the documentation on your CA‘s site, or contact their support, to determine what that order is.
One of the bundles I received from Comodo was:
AddTrustExternalCARoot.crt
(Root CA Certificate)COMODORSAAddTrustCA.crt
(Intermediate CA Certificate)COMODORSADomainValidationSecureServerCA.crt
(Intermediate CA Certificate)jambonsw_com.crt
We start by ensuring that all of the files are in PEM format.
$ openssl x509 -in COMODORSADomainValidationSecureServerCA.crt -outform pem -out COMODORSADomainValidationSecureServerCA.pem
$ openssl x509 -in COMODORSAAddTrustCA.crt -outform pem -out COMODORSAAddTrustCA.pem
$ openssl x509 -in AddTrustExternalCARoot.crt -outform pem -out AddTrustExternalCARoot.pem
$ openssl x509 -in jambonsw_com.crt -outform pem -out jambonsw_com_cert.pem
Now that all our files are in the right format, we can simply concatenate the files into a single CA chain.
$ cat COMODORSADomainValidationSecureServerCA.pem > jambonsw_com_ca_chain.pem
$ cat COMODORSAAddTrustCA.pem >> jambonsw_com_ca_chain.pem
$ cat AddTrustExternalCARoot.pem >> jambonsw_com_ca_chain.pem
Finally, I opt to delete all of the unnecessary files (having backed up the email from Comodo).
$ rm AddTrustExternalCARoot.crt
$ rm AddTrustExternalCARoot.pem
$ rm COMODORSAAddTrustCA.crt
$ rm COMODORSAAddTrustCA.pem
$ rm COMODORSADomainValidationSecureServerCA.crt
$ rm COMODORSADomainValidationSecureServerCA.pem
$ rm jambonsw_com.crt
In the certificates
directory, you should now have:
csr.pem
jambonsw_com_ca_chain.pem
jambonsw_com_cert.pem
private-key.pem
You are now ready to upload your certificate to AWS.
Uploading your Certificate¶
Now that you have a private key, a certificate, and a certificate chain, you can upload the certificate to AWS to secure your website.
To do so, simply move to the root directory of your project (where the
Makefile
is), and enter the command below.
$ make upload-cert
Ta-da! Your certificate has been uploaded to AWS. You are now ready to deploy your website.
Deploying your Static Site to the Cloud¶
You have the tools. You have the accounts. You have security. Let’s put some content in the cloud.
Section Goals¶
We will first use the scripts to create a Cloud Formation stack. This will create all of the cloud resources we need to store our website.
We will then upload the website to the cloud.
Preparing for Work¶
If you’re using virtualenvwrapper
, simply activate the environment.
$ workon jambonsw # Replace jambonsw with the name of your own env
$ # if you don't remember the name of your env
$ # type workon, and then tap the tab button on your keyboard twice
If you’re not using virtualenvwrapper
, you need to load the
appropriate environment variables.
$ cd Path/To/Your/Project
$ source env.sh
Creating a CloudFormation Stack¶
To create a CloudFormation stack, we need a script (currently in
your_project_dir/certificates/cloudformation_build.json
) and
parameters for that script (will be created at
your_project_dir/certificates/cloudformation_parameters.json
).
To make your life as simple as possible, a script has been supplied to generate the parameters for you (this works as long as you’ve already uploaded a security certificate).
$ ./generate-params.sh
If the script succeeds, it will delete itself after creating
your_project_dir/certificates/cloudformation_parameters.json
.
Note
If you’re using git
, I recommend adding the new file to your
repository.
$ git add certificates/cloudformation_parameters.json
$ git commit -m "Generated CloudFormation parameters."
With all the right files in place, we can now create the CloudFormation stack with the simple command listed below.
$ make create-stack
This can take up to 20 minutes to complete.
Pointing your Domain to Amazon’s Nameservers¶
Now that you have a set of resources in the cloud, you need to point your domain name at the cloud. You are setting the nameservers of your domain.
To get the Amazon Nameservers for your website, simply use the command below.
$ make dns
You will need to go to you domain’s registrar and specify these nameservers. If you don’t know how to do this, look through the FAQ section of your registrar’s website, or contact support.
Uploading Content to the Cloud¶
We now have the infrastructure for a website, but we’ve not actually put
any content in the cloud yet. The command below changes that, by
uploading all of the content in the your_project_dir/content/
directory. By default, the template includes and extremely basic
webpage.
$ make
And with that last command issued, you have successfully deployed your website to the cloud.
Congratulations!
Updating Your Static Website¶
Notes!
update content
and then make sync
update cloudformation_build.json
and make stack
Example case: add MX record
Contributing to the Cookiecutter Static Site Project¶
Notes!
Fork project on Github
git co -m issue_101
git co -m new_feature
Issue PR from branch!