Creating a code pipeline for your S3 static website
Tags: aws, react, github, nextjs
Published: 2023-02-10 04:35:09

Having the ability to create a code pipeline to automate certain tasks is truly a gift. This is my attempt to summarize the following:
- how to create a code pipeline in AWS 
- how to use an existing GitHub repository as the code source
- how to build a static NextJS site
- how to sync the static files to an existing S3 bucket

This summary does **NOT** detail how to create a static website with S3. 
I detailed how to do that in the following post: [Hosting a static website in AWS](https://dev.to/dmeadows8585/hosting-a-static-reactjs-app-in-aws-5769)

## Contents
* [Create a CodePipeline in AWS](#1)
* [Add Source Stage](#2)
* [Create a connection](#3)
* [Add Build Stage](#4)
* [Run the pipeline](#5)
* [Summary](#6)
* [Troubleshooting a failed stage](#7)

## Create a CodePipeline in AWS <a name="1"></a>

First log into AWS console and go to service **CodePipeline**


![Navigating to CodePipeline in the AWS console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uyjxna1807b32vdy227.png)

Next, click on the **Create pipeline** button. For this pipeline, I am going to use my NextJS portfolio application as the code source. So I will simply name the pipeline _my-portfolio-app_.

Note: Check the box to allow AWS CodePipeline to create a service role for this new pipeline.


![Choose pipeline settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kwwbuh9vamyxa0ge32h.png)

## Add Source Stage <a name="2"></a>
Next, this is where a code source is connected as an input to the pipeline. The drop down menu for the "Source provider" will have a few options to select from. In this case, I will select GitHub.

There are two options to choose here (Version 1 & 2). Choose whichever option to connect to GitHub that suites you best.

Note: In the AWS documentation version 2 is recommended.
[GitHub source action](https://docs.aws.amazon.com/codepipeline/latest/userguide/update-github-action-connections.html)


![Add source stage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/goschdx4u9yugiobag9j.png)


### Create a connection <a name="3"></a>


![Create a connection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7hmrlyb26murabbjeoj.png)

Once a connection has been made to GitHub, you will be able to access your existing repositories. Choose the desired one from the drop down menu.


![Adding a source stage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szrbudcqdq51mmsp2jhj.png)




## Add Build Stage <a name="4"></a>
Next is the build stage. This stage is optional, however a pipeline needs more than one stage. So I will add a build stage and skip the Deploy stage.

![Adding the build stage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nm1e8vowocghm1e6kl6m.png)

If you do not have an existing build project you want to use, then click on the **Create project** button.

### Create build project

For the **Environment** configuration, I choose the following options:


![Environment configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/exdhbnxjg5rf2zr6f4x5.png)

For the **Buildspec** option I selected _Use a buildspec file_ and left the Buildspec name empty.

The rest I left as defaults.


### Here is my buildspec.yml as an example
Note: There are many ways to set up your buildspec file to successfully build a NextJS or ReactJS app. This is a very simplistic version. 

```
version: 0.2
phases:
  pre_build:
    commands:
      # install npm
      - echo Performing a npm install...
      - npm install
  build:
    commands:
      # run build script
      - npm run build
  post_build:
    commands:
      - aws s3 sync out <s3 bucket name>

artifacts:
  # include all files required to run application
  #    name: BuildArtifact
  files:
    - '**/*'
  base-directory: out
  discard-paths: no
```

Notice that for the build stage there is a command "npm run build"

The build script I used to build my NextJs app is the following:
    

```
"build": "next build  && next export"
```
This will build the application in a directory named "out".

In order to sync the built files that are in the "out" directory to a S3 bucket, I used the "aws s3 sync out <S3 bucket name>" command.

Note: To use the aws s3 sync command, make sure the codeBuild service role has the proper permissions (s3:ListBucket).


### Add Deploy Stage
For this particular pipeline example I skipped this stage.



Next, review all steps and configurations. Click **Create pipeline** button to continue.


## Run the pipeline <a name="5"></a>

The pipeline will automatically run for the first time. This particular pipeline is simple and hopefully will not have any issues.

![Results of running the pipeline](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omikp2x4g17l907d8caq.png)

## Troubleshooting a failed stage <a name="7"></a>
If the build stage fails, here are two common causes: 

- the buildspec.yml file has an error (typo, incorrect command, etc.)
- role permissions are incorrect (check specific policies attached to the codeBuild service role)


## Summary <a name="6"></a>
Once the pipeline has been created, each commit that is made to the selected repository branch ("main" in my case) should trigger the pipeline to build and sync the files to the specified S3 bucket. That means no more manually copying the built files over to a S3 bucket. 🎉🎉


I hope this is helpful to someone. Good luck out there 👋