Deploy Apps using GitHub Actions to AWS Beanstalk
Tags: devops, aws, githubactions, tutorial
Published: 2022-08-17 05:46:00

**Introduction**

In this post I will show you how you use the GitHub Actions and Amazon Web Services (AWS)-Beanstalk, we'll build a CI/CD pipeline from the ground up. I've broken down the guide into three sections for easier reading and comprehension:

Before getting too bogged down in jargon, let's define a few key terms.

Second, we'll implement continuous integration (CI) to ensure that all builds and tests are executed without human intervention.

Our code will be automatically deployed to AWS after we have set up continuous delivery (CD).

Yes, that was a lot to take in. First, let's define each of these terms in detail so you know exactly where we're headed.

**Definition**
**What is GitHub Action?**
I'm going to oversimplify the GitHub Actions concept because I can't think of a better way to explain it. Hence, I've made below Mind Map for better understanding on GitHub Action.

![What is GitHub Action?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p5tju467xdzowvbyi64j.png)

For more details on GitHub , please go to [GitHub Action Details](https://docs.github.com/en/actions)

**Goals**
1. How to automatically build and run unit tests on push or on PR to the main branch with GitHub Actions.

2. How to automatically deploy to AWS on push or on PR to the main branch with GitHub Actions.

**PART 1: How to Automatically Run Builds and Tests - Continuous Integration (CI)**

**Prerequisites**
**P1:P1 Project Folder & Files Structure**
I have created a demo Django project which you can grab from this repository:

```
git clone https://github.com/devops4mecode/django-github-actions-aws.git
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7uoluad5425pufsmwtp.png)
 
After you download the code, create a virtualenv and install the requirements via pip:

```
pip install -r requirements.txt
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2zazn8jo2d7vm344xmg.png)
 
**Part1:P2 Locally Build and Unit-Test**
We build and test the Django App locally below;

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/257h8zh3inpnlygf63cv.png)

Let's set up GitHub Actions now that you have a local Django project ready to go.

**Part1:P3 Create GitHub Repository for Django App**

We need tp create a new GitHub repository, once create you will get below repository. You may use different name than mine.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95kwcjswx7obv5tyreqc.png)

As you can see, we also don't have GitHub Action configure yet.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhp9jmzd6fvn7qxtzoce.png)
 
I also created a new DEV branch and update all code/script that we need for GitHub Actions.

**STEPS:**
**Part1:S1 How to Configure GitHub Actions**

Our project is now ready to go. More importantly, however, we have committed our polished update to GitHub and have a testcase prepared for the view that we have defined.

Each time a pull request or push is made to master, we want GitHub to automatically initiate a build and run all of our tests. The build and testing weren't triggered by GitHub Actions after we published to main.

Make a new folder in your.github called workflows: The YAML file editor is where all your files will be made. In order to get our build and test routines up and running, we need to make a first workflow. To accomplish this, we make a new file ending in.yml. Put the name "build test.yml" in this file's name. Incorporate the following into the newly produced yaml file:

```
name: Build and Test

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2
    - name: Set up Python Environment
      uses: actions/setup-python@v2
      with:
        python-version: '3.x'
    - name: Install Dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
  
    - name: Run Tests
      run: |
        python manage.py test
  deploy:
    needs: [test]
    runs-on: ubuntu-latest

    steps:
    - name: Checkout GitHub source code
      uses: actions/checkout@v2

    - name: Generate deployment package
      run: zip -r deploy.zip . -x '*.git*'

    - name: Deploy to AWS Elastic Beanstalk
      uses:  einaregilsson/beanstalk-deploy@v20
      with:
        aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        application_name: django-github-actions-aws
        environment_name: Djangogithubactionsaws-env
        version_label: "ver-${{ github.sha }}"
        use_existing_version_if_available: true
        region: "ap-southeast-1"
        deployment_package: deploy.zip
```

**Part1:S2 Push/PR DEV branch code to GitHub Repository**

Now that you've defined a workflow by adding the config file in the designated folder, you can commit and push your change to your remote repo.

Let's create Pull Request and Merge it to Master branch.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5kk7wph61vnhxm7m98nf.png)
While our PR being check, you can see our GitHub Action already running;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bevnrjl14xludw59oh0n.png)

If you navigate to the Actions tab of your remote repo, you should see a workflow with the name Build and Test (the name which we've given it) listed there. As of now, we can see our Deploy jobs is failed, since we not setup yet our AWS Beanstalk. So this output is expected, don't worry, we will setup it later.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ku3xxo5ve5gpr34nqvay.png)
 
**PART 2: How to Automatically Deploy Our Code to AWS - Continuous Deployment (CD)**

**Prerequisites**

**Part2:P1 AWS AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY**
Go to AWS Management Console -> IAM -> User -> Access Key
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fm46afxm8wudgret4h5i.png)
 
Please copy and paste Access Key and Secret to your Notepad/any place you prefered, since we will reuse it when we want to setup our secret in GitHub repository later.

**Part2:P2 Elastic Beanstalk environment**
Before showing the workflow, we must have an operating environment to receive our Django app from GitHub Actions.  Since we will use DJango Python as our language, hence, create a new Environment as below.
3.1 Create a new Beanstalk applicaton
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbns4xtaxyillmt5i5k3.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgwcsz7jx1g69ch1ndfu.png)
  
Finally, we have created our Beanstalk Sample App
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o94hlr46nptga8rvrvxp.png)
 
**STEPS:**

**Part2:S1 Configure GitHub Secret**
Previously, we have copy our AWS Access Key and Secret Key, now go to GitHub Repository Setting. Then, go to Secret below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ibmvr7xobvm0l1vydz35.png)

Choose "Action" menu, then click "New repository secret" button;  

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpez3myy1pd8o777clqs.png)

Give your secret name, please follow back what you had defined in our workflow script above.

AWS_ACCESS_KEY_ID:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gfs2vzpwwub1bun5ga86.png)
AWS_SECRET_ACCESS_KEY:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kg7o35dfhf3hw6unc5w0.png)
  
**Part2:S2 Configure your Project for Elastic Beanstalk**

Our project's application.py file is the default location where Elastic Beanstalk will look for our code. Our application cannot run without that file, but it is not included in our repository. The Elastic Beanstalk must be instructed to use the wsgi.py file in our project rather than the default python servlet container. Here's what you need to do:

In the root of your project's directory, make a new folder and label it.ebextensions. Make a configuration file in that directory. What you want to call it is up to you. My file is called eb.config. The following should be included in your configuration file:

```
option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: django_github_actions_aws.wsgi:application
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njxh1pgtc83qvgrr0ia8.png)
 
**Part2:S3 Update and finalize your Workflow File**

Please update all 5 parameters below with your parameters:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2g7jyyw3t1vm6jhja6p.png)

- Your AWS Access Key.
- Your AWS Secret Key.
- Beanstalk's Application Name.
- Beanstalk's Environment Name.
- AWS Region that want to deploy.

This step utilizes einaregilsson/beanstalk-deploy@v20. Actions are reusable apps that handle often repeated activities. the e inaregilsson/beanstalk-deploy@v20 is one.m To emphasize the above, remember our deployment step: 

`GitHub->AmazonS3->Elastic Beanstalk`

We didn't set up Amazon s3 in this tutorial. We didn't upload to or pull from an S3 bucket in our workflow file.  The einaregilsson/beanstalk-deploy@v20 operation performs all that for us. You can construct your own action to handle monotonous activities and sell it on GitHub Marketplace.

Now that you've updated your workflow file locally, you can then commit and push this change to your remote. Your jobs will run and your code will be deployed to the Elastic Beanstalk instance you created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k51hna3hkd4zdjamkhfe.png)
 
You also can check the log on deploy jobs to our AWS Beanstalk below.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzst7p4bc78rl6kjccy9.png)

Lastly, we have updated our Sample App to new code below.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ipnyl97q9zqhntiv7n4.png)

**Conclusion** 
Good lord, this one was a marathon, right? I concluded by defining CI/CD Pipeline, Amazon Web Services (AWS), and GitHub Actions. We also learned how to set up GitHub Actions for automated code deployment to an AWS Elastic Beanstalk environment.