GitHubActions-Logo

In this Blog you will learn how to use GitHub Actions for building a CI/CD pipeline which builds a Java Web application and deploys it into AWS.

Prerequisites:

  • AWS Account and basic AWS knowledge
  • GitHub Account

Let’s get started.

Setting up the environment

First of all fork this repository: https://github.com/SamPriyadarshi/hello-world-war

Create a user in AWS IAM with the below policies:

  • AmazonEC2FullAccess
  • AmazonS3FullAccess
  • AmazonCloudFormationFullAccess

Note: These policies give very wide range of permissions. Use them mindfully for production use.

After creating the IAM User, make note of the Access Key and Secret Access Key.

Next step is to configure GitHub Secrets:

  • Go to Settings -> Secrets.
  • Create a secret called AWS_ACCESS_KEY_ID and paste the AWS Access Key in the value.
  • Create another secret called AWS_SECRET_ACCESS_KEY and paste the AWS Secret Access Key in the value.

Next Step will be to create S3 Bucket

Let’s create a S3 bucket where all the artifacts should reside, in this case the WAR file, we will use it for storing the WAR file and downloading it to the EC2 instance.

  • Go to AWS S3 console -> Click on create Bucket -> Give a unique name for your bucket and hit create Bucket with all the defaults.

Now you have everything setup. We are ready to dive deeper into the GitHub Workflow file and the CloudFormation template which is responsible for deploying the application.

Understanding the WorkFlow file

Let’s look at the workflows file which is responsible for building and deploying the application to AWS.

# This workflow will build a Java project with Maven and deploy it to AWS using CloudFormation
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Java CI-CD with Maven

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Build with Maven
      run: mvn -B package --file pom.xml
    - name: upload artifacts
      uses: actions/upload-artifact@master
      with:
        name: Package
        path: /home/runner/work/hello-world-war/hello-world-war/target/hello-world-war-1.0.0.war

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - uses: actions/download-artifact@master
      with: 
        name: Package
        path: staging

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1

    - name: Copy files to S3 with the AWS CLI
      run: |
        aws s3 sync /home/runner/work/hello-world-war/hello-world-war/staging s3://<S3 Bucket Name>
    - name: Deploy to AWS CloudFormation
      uses: aws-actions/aws-cloudformation-github-deploy@v1
      with:
        name: MyStack
        # This template installs Tomcat and deploys the war file built in the above step
        template: ec2instance_linux_master_template.yaml
        capabilities: CAPABILITY_NAMED_IAM

This workflow will trigger whenever there a Pull Request or a Merge to the master branch.

It has two steps:

  • Build: This step will build the application using Maven and upload the artifacts, which in this case is a WAR file.
  • Deploy: This step will download the WAR artifact, upload it to S3 and then deploy it to AWS EC2 instance using the CloudFormation template. Be sure to change the S3 bucket name with your respective bucket name. In this step, if you look closely we are also configuring the credentials that we configured earlier which will be responsible for providing appropriate permissions to deploy the application to AWS EC2 instance.

Note: Feel free to change the default region in which you want the CloudFormation Stack to be launched.

Now, let’s look at the CloudFormation template that is called by the GitHub Actions workflows file. https://github.com/SamPriyadarshi/hello-world-war/blob/master/ec2instance_linux_master_template.yaml

This is very standard CloudFormation template that launches an EC2 instance. Make sure to change these fields with your respective values:

  • VPC ID
  • Subnet Id
  • Security Group
  • S3 Bucket name in the User Data

Also, if you take a look at the user data of this template, you can see we are installing tomcat and copying the war file by downloading it from the S3 bucket.

Seeing the magic

Now you know everything about this setup. Let’s create a Pull Request or directly commit to master. And since we have set any Pull Request to master or a merge to master as a trigger, a GitHub Actions wokflow will trigger and will deploy our application.

Below is the CloudFormation template that is created by GitHub Actions:

Now, if you head over to the EC2 instance and grab the Public IP and hit the below URL, you should see your application running.

<Public-IP-of-EC2>:8080/hello-world-war-1.0.0/

Conclusion

GitHub Actions is very powerful and with very minimal setup you can create your CI/CD pipelines which can automatically build, test and deploy your applications to AWS.

If you have any queries or questions, please leave them in the comments section below and I will be glad to answer them.

More Resources:

Leave a comment

Your email address will not be published. Required fields are marked *