The Stack
Let’s dig a bit on our choice. Choosing the right tools is not obvious, so let me take a few minutes to explain why we have created such a stack.
Why use ECS ?
ECS is one of the solutions in AWS if you want to deploy docker containers. We think that it is easier to deal with docker containers and images to deploy our products. It is easier and faster than working with instance images:
- Build the code using our classic Maven tooling (
maven clean install
) - Create a docker image (
docker build .
) - Tag and push the image to ECR (
docker tag ...
and then docker push ...
) - Run the ECS task based on ECR
We are dealing here with couple of Mb (around 500 Mb for a docker image) instead of multiple Gb for a instance image. There is no easy way to generate a instance image containing our product from a CI solution like CodeBuild (the best I know in this area is the very good Packer tool from HashiCorp).
Why use an EC2 instance ?
In an ideal scenario, I would avoid an EC2 instance. It relies on an EC2 image (Amazon Machine Image), and it is bulky to modify. But here we want to deliver a BI solution, and officially, this solution is not compatible with Docker containers. I know some users are trying to dockerize BOBJ (here for example), but we haven’t succeed in this task.
Why use RDS ?
RDS is the de-facto standard solution to deploy a database in AWS. Both our products relies on a database, so we need to ship one. We chose RDS.
Actually it is not the only solution, we can also imagine adding a database container in our ECS task, but this solution complexifies the connectivity between the BOBJ instance and the database.
Why use CloudFormation ?
CloudFormation is the Infrastructure as Code solution in AWS. There are also other tools available like Terraform from HashiCorp (again!).
We chose to use CloudFormation in this project because it allows us to create a full stack and also to tear-down the stack very easily from the AWS API when the user doesn’t need the solution anymore (it is a bit more difficult to teardown a terraform setup, not a single AWS API call !)
Why use CodeBuild ?
Our company mainly uses Jenkins as CI solution. Starting on CodeBuild is not obvious ! The goal of the project was to use a completly AWS solution without any external product.
CodeBuild is quite a mature product now, which allows to setup a project with conditional builds, and to consume multiple git repositories. It also allows to push docker images to ECR, and to trigger the CloudFormation stack creation. Here is an exemple of the buildspec provided in the project:
version: 0.2cache:
paths:
- '/root/.m2/**/*'phases:
install:
runtime-versions:
java: openjdk8
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region $AWS_REGION)
build:
commands:
- |
if test "$BUILD_EYES" = "1"; then
echo "Build 360eyes docker image and push it to ECR";
cd $CODEBUILD_SRC_DIR/360ace/eyes;
mvn clean install -Pdocker;
docker tag 360eyes/360eyes.rest.service:latest xxx.dkr.ecr.$AWS_REGION.amazonaws.com/360ace/eyes:latest;
docker push xxx.dkr.ecr.$AWS_REGION.amazonaws.com/360ace/eyes:latest;
fi
- echo Launching CloudFormation template
- cd $CODEBUILD_SRC_DIR/360ace
- aws cloudformation create-stack --template-body file://360ace.yaml --stack-name ace-$(date +%d%H%M)
This is just does the following:
- build the product and docker image (using this maven plugin)
- tag and push on ECR the docker image
- start the CloudFormation stack
A good point is that it allows to checkout a specific branch (like a developer working branch) or a specific tag (a release) of our product repositories.