CICD Static Website to S3 with Github Actions
Tags: aws, cicd, hosting, cloudformation
Published: 2021-02-23 16:27:27


Hi!!
A few days ago, I worked with a developer on a simple landing page with zero complications. He needed a simple way to visualize his changes, obviously in our current AWS infrastructure.

The best way to achieve this was with Github Actions + S3 Static websites, and I'll tell you how I did it.

![CICD](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2u2l30tmslb8iq0cctt2.png)

## Steps

1.  Provision an S3 Bucket and IAM User with Cloudformation.
2.  Add the AWS secrets from our IAM user to the Github repository.
3.  Deploy an app to an S3 Bucket through Github actions. 

# 1. Resources provisioning 🏗️

First, we must deploy our resources by AWS Cloudformation. In the following cf template (main.yml), it's defined:

 - S3 Bucket
 - Bucket Policy
 - IAM User
 - IAM Policy inline

{% gist https://gist.github.com/LuisCusihuaman/2ac85fb6f2269d85328ea4c9b425dff5 file=main.yml %}

If you have already installed AWS CLI:

```bash 
aws cloudformation create-stack --stack-name your-stack-name --capabilities CAPABILITY_IAM --template-body file://main.yml --parameters ParameterKey=BucketName,ParameterValue=your-unique-bucket-name
```

Otherwise:

For this need to login into the AWS Console -> Cloudformation -> Stack ->  _Create Sack_ **-> Upload a template file.**

![Create Stack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjhhn8o5vxrdslatqybv.png)

![CAPABILITY_IAM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vurjo94y0kfmq0y0f3un.png)

_It will ask you for confirmation that this cloudformation template will create IAM resources, in this case, a user._

# 2. Secrets 🤫

Now, we go for the `IAM User`: https://console.aws.amazon.com/iam/

![AWS Credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gyj5bk0rzs1n48g64trz.png)

_IAM -> Users -> your-new-iam-user ->_ **Security Credentials**
_Access Key ->_ **Create access key**

![Access keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd75gaarl72ddzy3eh0z.png)
**Download .csv file**

We need to set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in the GitHub repository's secrets section required to upload files to our S3 bucket.

`S3_BUCKET`: The name of the destination bucket
`S3_BUCKET_REGION`: The destination bucket region	

![Github Secrets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g69jcwouh6ywjxyassja.png)
_Settings -> Secrets_ -> **New repository secret**

# 3. Github Actions 🚀
  
I highly recommend using this continuous deployment **only** for stage environments. For that reason, we'll create a QA branch.

 ```bash
git checkout -b QA
```

![Creating branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8dules4af9dn5698mxz9.png)
_Creating branch from Github UI_  

Next, we'll create our deploy.yml file in the path: `.github/workflows`

```bash
mkdir -p .github/workflows && touch .github/workflows/deploy.yml
```
![create new file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knpgybjz3t6om5cmmcd4.png)

_If you want to run it on a specific branch, change_ `branches`

{% gist https://gist.github.com/LuisCusihuaman/2ac85fb6f2269d85328ea4c9b425dff5 file=deploy.yml %}

*Github action:*  https://github.com/Reggionick/s3-deploy.



![Deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wutq0ny9e47ib147tyvo.png)
_Our app is already deployed by Github Actions!_

# Done! 🙌

Check your S3 WebsiteURL from the last Cloudformation output:

_http&#8203;://your_bucket_name.s3-website-your_region.amazonaws.com/_

![Static Website](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p527a63kqyfe9keys6en.png)

For HTTPS: [Configuring a static website using a custom domain registered with Route 53](https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-custom-domain-walkthrough.html#:~:text=If%20you%20want%20to%20use%20HTTPS,%20you%20can%20use%20Amazon%20CloudFront%20to%20serve%20a%20static%20website%20hosted%20on%20Amazon%20S3)

# Bonus 🎁
If you work with react, the following pipeline can help you: 
{% gist https://gist.github.com/LuisCusihuaman/2ac85fb6f2269d85328ea4c9b425dff5 file=react_deploy.yml %}

react-router 404 errors: https://via.studio/journal/hosting-a-reactjs-app-with-routing-on-aws-s3
cors-cloudformation example: https://git.io/JtQZK

If you have any comments or improvements for this post, I would be glad to receive them. 

Thank you for your time 👋👨‍💻.