CI/CD Pipeline setup using GitHub Actions and AWS
By: Ninu Varghese
Tags: AWS, React, Nodejs, Continuous Delivery, Continuous Integration

This tutorial assumes you are familiar with git commands, npm , AWS and you have a working web app that is ready to be deployed. The goal of setting up the CI/CD pipeline is to deploy your Web app to AWS S3 everytime a commit is made to the master branch.

CI/CD workflow

Understanding CI/CD

CI/CD comprises series of steps that are going to be executed automatically every single time we make a change to the code and then push those changes up to GitHub.

The goal of CI/ CD is to make sure that any time we make changes to the code, we have some process that is going to automatically run the CI build of the package and then automatically attempt to deploy that change off to our infrastructure. To implement CI/CD pipeline, we’re going to be making use of something called GitHub actions

What are GitHub actions?

GitHub actions are essentially small bits of code that you can automatically execute whenever some event occurs to your repository.

For example, you can configure code to automatically run any time that you commit some code on your machine and then push it up to GitHub. To be more precise in the following scenarios:

Any time a pull/merge request is created or closed,

Anytime code gets merged into your primary branch,

On some set schedule, for example setup a build to run every day at 9AM.

Any time an issue is created or closed.

There are many different events you can watch for. So, any time one of these different events occurs to our GitHub repository, we can choose to run a set of workflows.

In this article, We are going to trigger an action whenever a change happens to our folder of our master/main (your primary branch).

While creating a workflow for you project , there are a series of different commands that are going to be executed on a virtual machine, this virtual machine is automatically created, destroyed, cleaned up, all that kind of actions will be executed by GitHub automatically.

Configuring a workflow

There are two ways to create workflows in GitHub,

First method is by accessing your GitHub repo’s action tab and click on the link set up a workflow yourself

Second method is by creating a YML file as part of your code repo.

I’m taking the second approach here. Workflows can be created inside your the .github/workflows directory by adding a .yml workflow file. For example, add .github/workflows/container.yml to your project.

A typical workflow file should contain:

Name: The name of your workflow

On: The on keyword defines the Github events that trigger the workflow. For example push events on master/main branch. You can also specify paths

Jobs: A workflow run is made up of one or more jobs. Jobs define the functionality that will be run in the workflow and run in parallel by default.

Env: Env defines a map of environment variables that are available to all jobs and steps in the workflow.

Runs-on: The runs-on define the Operating System your workflow should run on.

Steps: Steps represent a sequence of tasks that will be executed as part of the job.

For more information on how to setup workflow, please follow this article. Sample of my workflow(container.yml) looks like this:

AWS Configuration

Now, that we got our workflow partially ready, let’s focus on how to get the stuffs ready at the AWS side. First you need to have an AWS account, once its ready and the navigate to AWS management console. Select the S3 service. To upload your data to Amazon S3, you must first create an Amazon S3 bucket in one of the AWS Regions. If you are new to AWS ,please follow this article on how to create an S3 bucket.

Create a bucket policy

In AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/. Choose the name of the bucket that you’ve just created. Choose Permissions > Edit Bucket Policy. Copy the bucket ARN as shown below

5. Choose Policy generator to open the AWS Policy Generator in a new window.

6. On the policy generator page, select S3 Bucket Policy from the Select Type of Policy menu. Add the statements as per the example below

7. Add the copied ARN value to the field Amazon Resource Name in the following format:

<arn>/*

Click on the button Add statement and upon success, generate policy by clicking Generate Policy button.

8. Copy the generated policy text, and return to the Edit bucket policy page in the Amazon S3 console.

9. Under Bucket policy, choose Edit.

10. In the Policy text field, type or copy and paste a new bucket policy, and click save changes

Creating an IAM user

In the AWS management console select the service IAM, Select Users and Add User. I found this great tutorial which walks you through creating an IAM user for uploading to S3 bucket. Once, you successfully create the user You should see something similar to this.

Please do not close this window where, the Access key and secret access are displayed . The secret key is only going to be displayed one time. So, we need to make sure that we make use of these keys right away. Otherwise, we’ll have to regenerate the set of credentials. (We’re going to use these keys in the GitHub repository settings).

Here we’re going to create three different secrets: our access key, the secret key and the bucket name. They are essentially key value pairs and eventually refer to these inside of our action config code. Let’s open the GitHub repository in a new tab and go to settings->Secrets >New repository secret. Enter the name (please make sure you follow the below naming convention)and value as below and hit Add secret. You need to repeat this for the Access key, Secret key and bucket name

AWS_ACCESS_KEY_ID :<YOUR-AWS_ACCESS_KEY_ID> AWS_SECRET_ACCESS_KEY: <YOUR-AWS_SECRET_ACCESS_KEY> AWS_S3_BUCKET_NAME: <YOUR-AWS_S3_BUCKET_NAME>

Example of adding secret

Now, that you have our keys in GitHub. Its time to modify your container.yml. We need to add the following under the env(environment) section

env: AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET_NAME }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: "<YOUR-REGION>" # optional: defaults to us-east-1 SOURCE_DIR: "build" # optional: defaults to entire repository

Now, with the new addition the container.yml should look like below

Once, you have the container.yml ready, please go ahead and commit the changes and push it upstream to the master branch (or the branch you’ve specified in your workflow). Once the code is push to master, you should be seeing your build running under the Actions tab

CI Build in Progress

Once the build pass, you should be able to see the success message as below

To verify that your build worked go to Amazon S3 console and choose the bucket you’ve created earlier, and you should be able to see compiled contents inside

Conclusion

In this article you’ve learned on how to create a CI/CD pipeline to deploy a web app using GitHub actions. I hope you enjoyed this article! Please let me know if you have any feedback on how I can improve . Thanks and Cheers!