Build a simple DevOps pipeline from GitHub to AWS S3 for static website
Tags: devops, aws, github, tutorial
Published: 2020-11-11 16:26:02

## The simplest way to automate the deployment of your static HTML page


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/6102/0*6l3An2IoN_gJ-koB" width="3051" height="4606" srcSet="https://miro.medium.com/max/552/0*6l3An2IoN_gJ-koB 276w, https://miro.medium.com/max/1104/0*6l3An2IoN_gJ-koB 552w, https://miro.medium.com/max/1280/0*6l3An2IoN_gJ-koB 640w, https://miro.medium.com/max/1400/0*6l3An2IoN_gJ-koB 700w" sizes="700px"/></noscript>

*Photo by [Riley Crawford](https://unsplash.com/@ricrawfo?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)*

One way to host a simple static website is to use AWS S3 to keep your files.

Yes, put your index.html and style files into an S3 bucket named <yoursite>.<extension> and you will be ready to publish your content.

Then you could link your own domain using Route 53, add a CloudFront distribution, HTTPS support…

But what about deployment ?

I can assure you that **you don’t want to spend any time** copy-pasting your pages to the S3 bucket. **You have better things to do !**

Here is my **simple way to automate this**. If you are new to the topic, this is a **30 minutes** configuration, reading this article included !

So, no more talk and let’s build our pipeline !



***To implements the following solution, you will need:***

*   A GitHub account
*   An AWS account

Here is the idea:

1\.  **Create** a GitHub repository for your website — 10min

2\.  **Configure** an AWS IAM user — 5min

3\.  **Configure** a GitHub Action — 5min

4\.  Make a change and **Deploy** — 5min

5\.  **Celebrate** — 5min (at least !)

# 1\. Create a GitHub repository

**_*If you already have your repository configured, you can go to Part 2 !*_**

Here, you want to put your code into a repository that will be used to track the changes and trigger the deployment.

1\.  Go to [GitHub](http://github.com) and connect to your account
2\.  Create a new repository

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5448/1*RtK9xGmjcQh4mMqUTBFp7A.png" width="2724" height="168" srcSet="https://miro.medium.com/max/552/1*RtK9xGmjcQh4mMqUTBFp7A.png 276w, https://miro.medium.com/max/1104/1*RtK9xGmjcQh4mMqUTBFp7A.png 552w, https://miro.medium.com/max/1280/1*RtK9xGmjcQh4mMqUTBFp7A.png 640w, https://miro.medium.com/max/1400/1*RtK9xGmjcQh4mMqUTBFp7A.png 700w" sizes="700px"/></noscript>

3\. Feel free to fill the parameters to have the repository you want

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/3436/1*CDAivennulEvPGrxtl2ktA.png" width="1718" height="1452" srcSet="https://miro.medium.com/max/552/1*CDAivennulEvPGrxtl2ktA.png 276w, https://miro.medium.com/max/1104/1*CDAivennulEvPGrxtl2ktA.png 552w, https://miro.medium.com/max/1280/1*CDAivennulEvPGrxtl2ktA.png 640w, https://miro.medium.com/max/1400/1*CDAivennulEvPGrxtl2ktA.png 700w" sizes="700px"/></noscript>

4\. Clone the newly created repository to your local laptop using Git command line or your favourite UI tool for Git (mine is [GitKraken](https://www.gitkraken.com/invite/k8rKL4iP)).


```
git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
```


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/1536/1*4tr_bdO7VgMjBOmeRxdWkA.png" width="768" height="688" srcSet="https://miro.medium.com/max/552/1*4tr_bdO7VgMjBOmeRxdWkA.png 276w, https://miro.medium.com/max/1104/1*4tr_bdO7VgMjBOmeRxdWkA.png 552w, https://miro.medium.com/max/1280/1*4tr_bdO7VgMjBOmeRxdWkA.png 640w, https://miro.medium.com/max/1400/1*4tr_bdO7VgMjBOmeRxdWkA.png 700w" sizes="700px"/></noscript>

You will find the url to use in your repository, clicking on the “Code” button

For more information on the git clone have a look a [the GitHub documentation](https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/cloning-a-repository).

5\. Put your files on the created folder and push it


```
git push
```


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/1640/1*9w53qGX0VOmSXFXp8kWtpQ.png" width="820" height="374" srcSet="https://miro.medium.com/max/552/1*9w53qGX0VOmSXFXp8kWtpQ.png 276w, https://miro.medium.com/max/1104/1*9w53qGX0VOmSXFXp8kWtpQ.png 552w, https://miro.medium.com/max/1280/1*9w53qGX0VOmSXFXp8kWtpQ.png 640w, https://miro.medium.com/max/1400/1*9w53qGX0VOmSXFXp8kWtpQ.png 700w" sizes="700px"/></noscript>

An example of a simple site repository:

Now, if you go to https://github.com/&lt;username&gt;/&lt;repositoryname&gt;, you will see your code waiting for you on the main branch !

Fine, let’s have a bit of AWS now !

# 2\. Create an AWS IAM user

Your goal is to push some files to your S3 bucket. For this purpose, you will need to have rights on the S3 bucket.

You will use an IAM user with S3 policy.

1\.  Open the [AWS console](http://console.aws.amazon.com/)
2\.  Go to the [IAM page](https://console.aws.amazon.com/iam/home#/home)

3\. Click on “Users” in the menu and Add a new user


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5620/1*9K4NZ4QMInpfiiwwm6fH0Q.png" width="2810" height="1310" srcSet="https://miro.medium.com/max/552/1*9K4NZ4QMInpfiiwwm6fH0Q.png 276w, https://miro.medium.com/max/1104/1*9K4NZ4QMInpfiiwwm6fH0Q.png 552w, https://miro.medium.com/max/1280/1*9K4NZ4QMInpfiiwwm6fH0Q.png 640w, https://miro.medium.com/max/1400/1*9K4NZ4QMInpfiiwwm6fH0Q.png 700w" sizes="700px"/></noscript>

4\. Pick a name and choose the programmatic access

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5512/1*rXLSX36bWGIuH3XBToiyYQ.png" width="2756" height="1302" srcSet="https://miro.medium.com/max/552/1*rXLSX36bWGIuH3XBToiyYQ.png 276w, https://miro.medium.com/max/1104/1*rXLSX36bWGIuH3XBToiyYQ.png 552w, https://miro.medium.com/max/1280/1*rXLSX36bWGIuH3XBToiyYQ.png 640w, https://miro.medium.com/max/1400/1*rXLSX36bWGIuH3XBToiyYQ.png 700w" sizes="700px"/></noscript>

5\. You are going to use an existing policy that will give you full control on the S3 service.

_(We use this for demonstration simplicity. You can enforce more security by creating your own policy to respect the least privilege principle.)_

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5512/1*rXLSX36bWGIuH3XBToiyYQ.png" width="2756" height="1302" srcSet="https://miro.medium.com/max/552/1*rXLSX36bWGIuH3XBToiyYQ.png 276w, https://miro.medium.com/max/1104/1*rXLSX36bWGIuH3XBToiyYQ.png 552w, https://miro.medium.com/max/1280/1*rXLSX36bWGIuH3XBToiyYQ.png 640w, https://miro.medium.com/max/1400/1*rXLSX36bWGIuH3XBToiyYQ.png 700w" sizes="700px"/></noscript>

6\. You can put some tags to identify you user if you need it


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5440/1*nK9xAzpnP0jNQawD31D6xg.png" width="2720" height="1308" srcSet="https://miro.medium.com/max/552/1*nK9xAzpnP0jNQawD31D6xg.png 276w, https://miro.medium.com/max/1104/1*nK9xAzpnP0jNQawD31D6xg.png 552w, https://miro.medium.com/max/1280/1*nK9xAzpnP0jNQawD31D6xg.png 640w, https://miro.medium.com/max/1400/1*nK9xAzpnP0jNQawD31D6xg.png 700w" sizes="700px"/></noscript>

7\. Review your informations and create the user

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5256/1*WOO3AMRFURXMbWEP2VPfgQ.png" width="2628" height="1310" srcSet="https://miro.medium.com/max/552/1*WOO3AMRFURXMbWEP2VPfgQ.png 276w, https://miro.medium.com/max/1104/1*WOO3AMRFURXMbWEP2VPfgQ.png 552w, https://miro.medium.com/max/1280/1*WOO3AMRFURXMbWEP2VPfgQ.png 640w, https://miro.medium.com/max/1400/1*WOO3AMRFURXMbWEP2VPfgQ.png 700w" sizes="700px"/></noscript>


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/4816/1*otzSng7uyRPv_CIL6OHVeg.png" width="2408" height="1298" srcSet="https://miro.medium.com/max/552/1*otzSng7uyRPv_CIL6OHVeg.png 276w, https://miro.medium.com/max/1104/1*otzSng7uyRPv_CIL6OHVeg.png 552w, https://miro.medium.com/max/1280/1*otzSng7uyRPv_CIL6OHVeg.png 640w, https://miro.medium.com/max/1400/1*otzSng7uyRPv_CIL6OHVeg.png 700w" sizes="700px"/></noscript>

8\. Here you need to keep the Access key ID and the Secret access key somewhere safe. This is the equivalent of your Login-Password.

And that’s it for the AWS IAM part ! Easy stuff right ?

Let’s go back to GitHub !

# 3\. Configure a GitHub Action

You will use a **GitHub Action** to deploy your files into the S3 bucket.

To make GitHub able to use our AWS user rights, you need to configure the user credentials you just created.

1\.  Go to the **Setting** section of your repository menu and click on **Secrets**

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5684/1*le-BSsBKVm8loZRhuPMNGQ.png" width="2842" height="1130" srcSet="https://miro.medium.com/max/552/1*le-BSsBKVm8loZRhuPMNGQ.png 276w, https://miro.medium.com/max/1104/1*le-BSsBKVm8loZRhuPMNGQ.png 552w, https://miro.medium.com/max/1280/1*le-BSsBKVm8loZRhuPMNGQ.png 640w, https://miro.medium.com/max/1400/1*le-BSsBKVm8loZRhuPMNGQ.png 700w" sizes="700px"/></noscript>

2\. Create two new secrets and put the values you kept from the IAM User creation.


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5544/1*Jce-zHbIhBhwFUwwmmQQ-g.png" width="2772" height="1172" srcSet="https://miro.medium.com/max/552/1*Jce-zHbIhBhwFUwwmmQQ-g.png 276w, https://miro.medium.com/max/1000/1*Jce-zHbIhBhwFUwwmmQQ-g.png 500w" sizes="500px"/></noscript>


```
AWS_SECRET_ACCESS_KEY
```


Now that you have our credentials ready, let’s create the workflow itself.

All the steps in your workflow should be created in the .github/workflow/ folder. GitHub Action will monitor this folder to find what to execute.

3\. Let’s create a .github/workflow/main.yml


```
mkdir .github/workflow
touch .github/workflow/main.yml
```


And add the following code to your main.yml file:

Here you are creating an Action to execute some steps every time a push happen on the main branch. You run your Action on an ubuntu (linux) machine and you have a dependency to [one of the already created AWS GitHub Actions](https://github.com/aws-actions).

It configures your credentials as well as the region. It should correspond to the one in which you created your S3 bucket.

Then you can see the Action steps.

As you are pushing a simple html/css folder, you have no build step but **you could add some steps** here. Maybe generate some build artefacts into a folder and push this folder to the S3 bucket.

You use the aws s3 sync command to synchronise the folder “thefoldertodeploy” with the content of the S3 bucket.

Now you can push this to the main branch.

# 4\. Make a change and **Deploy**

Now that **your Action is configured**, change a little thing visible on your website and push this change to the main branch.

Then go to the **Actions** section of your GitHub repository and observe the steps being executed !

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5576/1*p1VrgWv2pgZEfOmjm1vsfg.png" width="2788" height="1130" srcSet="https://miro.medium.com/max/552/1*p1VrgWv2pgZEfOmjm1vsfg.png 276w, https://miro.medium.com/max/1104/1*p1VrgWv2pgZEfOmjm1vsfg.png 552w, https://miro.medium.com/max/1280/1*p1VrgWv2pgZEfOmjm1vsfg.png 640w, https://miro.medium.com/max/1400/1*p1VrgWv2pgZEfOmjm1vsfg.png 700w" sizes="700px"/></noscript>


<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/5748/1*f3qx0iMgvd0ZNPakz-uVbw.png" width="2874" height="1176" srcSet="https://miro.medium.com/max/552/1*f3qx0iMgvd0ZNPakz-uVbw.png 276w, https://miro.medium.com/max/1104/1*f3qx0iMgvd0ZNPakz-uVbw.png 552w, https://miro.medium.com/max/1280/1*f3qx0iMgvd0ZNPakz-uVbw.png 640w, https://miro.medium.com/max/1400/1*f3qx0iMgvd0ZNPakz-uVbw.png 700w" sizes="700px"/></noscript>

[If you want to know more about GitHub Actions, here is a link to spend some time on it !](https://github.com/features/actions)


# 5\. Congrats, it’s celebration time!

<noscript><img alt="Image for post" class="dx hb dy hc t" src="https://miro.medium.com/max/4800/0*yLWaUZ_cOlOAKizX" width="2400" height="3000" srcSet="https://miro.medium.com/max/552/0*yLWaUZ_cOlOAKizX 276w, https://miro.medium.com/max/1104/0*yLWaUZ_cOlOAKizX 552w, https://miro.medium.com/max/1280/0*yLWaUZ_cOlOAKizX 640w, https://miro.medium.com/max/1400/0*yLWaUZ_cOlOAKizX 700w" sizes="700px"/></noscript>

*Photo by [Clay Banks](https://unsplash.com/@claybanks?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)*

Congrats ! You have just found **a way to focus** on what really matter: the content !

GitHub Actions is a really good way to implement a simple pipeline for your static website. You can get ready to **push modification within minutes** and you will never be responsible for your deployments anymore.

From there, you can do a little exploration session on GitHub actions or just add this topic to your [Wish list](https://dev.to/flolightc/use-wish-lists-and-certifications-to-extend-your-knowledge-2goo) !

*
I'm always open for feedback and questions, here in the comments or on my [Twitter](https://twitter.com/FlolightC)*