Gitlab pipeline deploy spring boot to AWS elastic beanstalk

gregoire barret
Cover Image for Gitlab pipeline deploy spring boot to AWS elastic beanstalk

On this article we will see how to deploy a spring boot application on AWS elastic beanstalk with gitlab pipeline.

Prerequisite

For start this tutorial, we need to have a working spring boot application already deployed on AWS beanstalk. I will not see how to deploy on bean stalk on this article. The GIT repository should be on GITLAB.

Create Access key

Before we can deploy anything, we need to create access key for AWS. You should not use your private key, but create a new pair with more access restriction for allow to deploy only on beanstalk and not be able to access to an other AWS service.

First open your AWS IAM console and select add new user.

Add new user

On the second page, you have to choose a name for the new user. It's gitlab_deployment on us case. You should also select the Programmatic access check box.

Create user name

On the next panel, you have to select the permissions attached to the new role. You can do it by creating a new group, or select permissions for this user only. As we need only this user be able to deploy, we select Attach existing policies directly. On the list of policy search for AWSElasticBeanstalkFullAccess and select the check box.

Attach role to user

Then we have to add tags, this step is optional.

Add tags

Now you can see a overview of what will be created. If everything is fine, click on Create user.

Overview

Last step and most important one, download and save the credential. Be careful They will be provided only there. If you lose them, you will have to create new one. Save your access id and secret key securely.

Credentials

That id from The IAM console. We can now go to the gitlab.

Add credentials on gitlab

We now need to save them credential on gitlab variable, so they can be accessible on the pipeline. For do that, got to settings->CI/CD and expend the Variables section.

Gitlab Variable

Now we can add two variable. The first one AWS_ACCESS_ID who will contain you access_id from AWS key. And AWS_SECRET_KEY who contain the secret previously generated.

Gitlab add Variable

Now variables are set on gitlab, we can start the pipeline script.

Gitlab pipeline script

You local project should already been setup and deployed using AWS EB CLI. My .elasticbeanstalk/config.yml look like that:

branch-defaults:
  master:
    environment: project-env
    group_suffix: null
global:
  application_name: simpleproject
  branch: null
  default_ec2_keyname: null
  default_platform: Java 8
  default_region: ap-southeast-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: null
  repository: null
  sc: git
  workspace_type: Application

deploy:
  artifact: build/libs/simpleproject-0.0.1-SNAPSHOT.war

For build a project with gitlab CI/CD, we need to create a .gitlab-ci.yml file at the root of the project. On us case we will keep it simple with two step, build who take care of building spring boot project and deploy who take care of deploy to AWS. You can add extra step for test, documentations, configurations, etc...

image: java:8-jdk

stages:
  - build
  - deploy

build:
  stage: build
  allow_failure: false
  script:
    - ./gradlew clean bootWar
  artifacts:
    paths:
      - build/libs/roombooking-0.0.1-SNAPSHOT.war

deploy:
  image: python:latest
  stage: deploy
  script:
    - pip install awscli
    - aws configure set aws_access_key_id $AWS_ACCESS_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_KEY
    - aws configure set region ap-southeast-1
    - pip install awsebcli --upgrade --user
    - ~/.local/bin/eb use Roombooking-env
    - ~/.local/bin/eb deploy
  dependencies:
    - build
  only:
    - master

Let's read in detail this file.

image: java:8-jdk is the docker image we are using for run this build

stages:
  - build
  - deploy

Specify we have two stages build and deploy.

Build stage

allow_failure: false Make the pipeline fail in case of build failure.

 script:
    - ./gradlew clean bootWar

We are using gradle for build us project. clean will take care of cleaning previous build folders, bootWar will generate a war file.

  artifacts:
    paths:
      - build/libs/roombooking-0.0.1-SNAPSHOT.war

Save the war file generated and make it accessible on the next stage.

Deploy

image: python:latest Use python 3.7 image. Pip is already installed on this image

pip install awscli install aws cli.

aws configure set aws_access_key_id $AWS_ACCESS_ID Setup the access key id as the one we previously setup on gitlab Variables.

aws configure set aws_secret_access_key $AWS_SECRET_KEY Setup the secret key as the one we previously setup on gitlab Variables.

aws configure set region ap-southeast-1 Setup region, it's should be the same than the one you use for create the AWS elastic beanstalk project.

pip install awsebcli --upgrade --user Install eb CLI. As we are using this tool for deploy the project. We don't need to do eb init as the config already exist.

~/.local/bin/eb use project-env Setup the project environment for eb. I use the path of eb executable as i didn't at it on the PATH variable.

~/.local/bin/eb deploy Deploy the project using eb.

  dependencies:
    - build

Specify this need the build stage to run first.

  only:
    - master

We want to run the deployment only when we push on master branch.

Final

You can now commit and deploy on the master branch. If everything is fine, you should see the status of the build on CI/CD -> pipeline.

Gitlab add Variable

For more information about gitlab CI/CD, you can refer to the documentation. You can build much complex build system than that.