Deploy Static Website to Amazon S3 from Github Repository

In this article, I would like to show you how to deploy your static website to Amazon S3 from the Github repository, to achieve this objective, we will use the services below:

  • Github Repository
  • Github Webhook
  • AWS S3 Bucket
  • AWS CloudFront
  • AWS CodeBuild
  • (optional) Custom Domain

Step 01: Setup Project Repository

We will use a simple project using Webpack to show you the use of CodeBuild in this project, you can fork my project here aashari/webpack-starter-basic into your private repository.

You may clone this project on your local machine using below command:

git clone https://github.com/aashari/webpack-starter-basic.git

Then you need to install the dependencies by using below command:

npm install

To run development mode, you may use below command:

npm start
Image for post
Image for post

You can open your web browser to make sure the project run perfectly by accessing http://localhost:8080

Image for post
Image for post

To build this project, you can use below command:

npm run build

The command will generate dist directory to the project root directory

Image for post
Image for post

All of files and directories inside dist directory will be uploaded into our AWS S3 Bucket.

If you have succeeded in generating the dist directory then you are ready to continue to the next step.

Step 02: Setup S3 Bucket

We need to set up AWS S3 bucket for our static website, login into your AWS Console then go to S3 service, click Create Bucket:

  • Bucket name: mq-my-static-bucket
  • Region: Asia Pacific (Singapore)

Click Create button on the bottom left panel

Let’s upload our dist generated files and directories into our mq-my-static-bucket you can upload it manually using AWS console (shown above picture) or using terminal aws-cli (recommended), you may follow this documentation of how to setup aws cli on your local machine https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html.

my@machine:~/webpack-starter-basic$ aws s3 sync dist s3://mq-my-static-bucket --delete

The above command will sync local directories into remote directories which is our bucket mq-my-static-bucket, then after command completed successfully, you will see all of our dist generated files are successfully uploaded into our bucket.

Step 03: Setup CloudFront

In this case, we need to setup CloudFront (AWS CDN Service) to access our mq-my-static-bucket and serve it into public access.

  • Go to the CloudFront service console
  • Click Create Distribution
  • Click Get Started on the Web section

Then fill below information:

  • Origin Domain Name: select our bucket generated public domain, in this case (mq-my-static-bucket.s3.amazonaws.com)
  • Origin Path: leave this blank
  • Origin ID: by default, this field will be auto-generated by CloudFront, you can custom it as you want
  • Restrict Bucket Access: yes
  • Origin Access Identity: Create a New Identity
  • Comment: mq-my-static-bucket-cloudfront
  • Grant Read Permissions on Bucket: Yes, Update Bucket Policy
  • Default Root Object: index.html
  • Leave the rest filled default value
  • Click Create Distribution

Our distribution of CloudFront will be in progress of generating, this will take a while (~15 minutes)

Take your coffee break until distribution finished successfully ;)

Whenever status changed from In Progress to Deployed that’s mean you have successfully set up your CloudFront distributions, try access your CloudFront Domain Name, in my case my domain name was http://djzq966zxhswx.cloudfront.net

You can configure HTTP to HTTPS in the Behaviours tab so your website only accessed by HTTPS protocol

Step 04: Setup CodeBuild and Webhook

Let’s integrate our Github repository to our AWS S3 using CodeBuild to make our continuous deployment, whenever you push your code into the master branch Webhook will trigger CodeBuild and build your project then deploy into AWS S3.

  • Go to CodeBuild console panel
  • Click Create build project
  • Project name: mq-static-website-builder
  • Source provider: Github
  • Select Connect using OAuth
  • Click Connect to Github
  • Click Repository in my Github account
  • Select your project (in my case: aashari/webpack-starter-basic)
  • Click Additional configuration
  • Click Rebuild every time a code change is pushed to this repository
  • Branch filter: master (we only want to deploy master branch)
  • Environment image: Managed image
  • Operating system: Ubuntu
  • Runtime: Node.JS
  • Runtime version: select latest node js version
  • Image version: Always use the latest image for this runtime version
  • Service role: New service role
  • Role name: codebuild-mq-static-website-builder-service-role
  • Leave all rest field filled by a default value
  • Click Create build project

Our CodeBuild is ready to use at this time, the next step is to set up a buildspec.yml file and push it into our master branch.

  • Create a new file inside the root directory of your project named buildspect.yml
version: 0.1phases:
install:
commands:
- npm install
- npm run build
- aws s3 sync dist s3://mq-my-static-bucket --delete
  • Whenever you git add buildspect.yml and push it into the master branch, CodeBuild will start building the project
  • You will get this error when building the project
[Container] 2019/01/13 16:44:49 Running command aws s3 sync dist s3://mq-my-static-bucket --deletefatal error: An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied[Container] 2019/01/13 16:44:54 Command did not exit successfully aws s3 sync dist s3://mq-my-static-bucket --delete exit status 1[Container] 2019/01/13 16:44:54 Phase complete: INSTALL Success: false[Container] 2019/01/13 16:44:54 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: aws s3 sync dist s3://mq-my-static-bucket --delete. Reason: exit status 1
  • That is because CodeBuild does not have S3 permission
  • Add S3 full access permission to role codebuild-mq-static-website-builder-service-role by accessing IAM Console panel
  • On the left bar, select Roles
  • Select role name (in my case: codebuild-mq-static-website-builder-service-role)
  • Click Attach policies
  • Click AmazonS3FullAccess
  • Click Attach policy
  • Back to CodeBuild Console Panel
  • Click Retry build to start rebuilding the project
  • Wait until build finished successfully
  • Your latest dist file generated from your latest code on Github are successfully uploaded into your S3 Bucket at this moment.
  • You can now update your code and deploy it automatically into your S3 Bucket just by push your code into your master branch project.

Step 05: Setup Custom Domain to CloudFront

In this case, let’s say we need to access our static website using our custom domain such as https://aashari.id.

  • Go to CloudFront Console Panel
  • Click on ID link of your Distribution
  • On General tab, select Edit
  • Alternate Domain Names (CNAMEs)
aashari.id
www.aashari.id
  • You need to point your root domain and www domain to your CloudFront Domain Name using CNAME
aashari.id       CNAME   djzq966zxhswx.cloudfront.net
www.aashari.id CNAME djzq966zxhswx.cloudfront.net

Now you can access your static website by accessing your custom domain, you may redirect your www to non-www or vise-versa non-www to www, you should google it ;D with below keyword

CloudFront redirect www to non-www

or this

CloudFront static website force www

Good luck ;D ~~

Image for post
Image for post

Join our community Slack and read our weekly Faun topics ⬇

Image for post
Image for post

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

Written by

I am a Cloud Engineer living in Jakarta. I spend a lot of my time with code, movie and coffee.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store