AWS CodeBuild Example

Continuing with the discussion of my presentation at CFCamp this week, and following on from the post about creating a continuous delivery system with AWS, I wanted to give an example of how AWS CodeBuild works, to build and test the Docker image, as part of that system.

AWS CodeBuild uses a build spec in the form of a YAML file in your project’s repository to build and test the generated image. This file is called buildspec.yml and should be in the root of your project. 

AWS CodeBuild Phases

The file is sectioned into phases, with these being:

  • pre_build
  • build
  • post_build

Each of the phases has a set of commands that are run to complete that phase of the build. 

Pre-build Phase

  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)

In this phase we are simple outputting some text to log and then doing exactly what that text says, getting the login for Amazon Elastic Container Registry (ECR).

Build Phase

  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

The build phases is only slightly more complex, again outputting some messages to log, then running the docker build command to build the image, using the repository name and image tag variables passed to the AWS CodeBuild service and then using the docker tag command to tag the generated docker image.

Post-Build Phase

  post_build:
    commands:
      - echo Build completed on `date`
      - echo Test started on `date`
      - docker run -p 8888:8888 --name cfcamp -d $IMAGE_REPO_NAME:$IMAGE_TAG
      - sleep 15s
      - curl -f --connect-timeout 30 http://localhost:8888/ || exit 1
      - echo Test completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - echo '[{"name":"'$IMAGE_REPO_NAME'","imageUri":"'$AWS_ACCOUNT_ID'.dkr.ecr.'$AWS_DEFAULT_REGION'.amazonaws.com/'$IMAGE_REPO_NAME':'$IMAGE_TAG'"}]' > imagedefinitions.json

In the post build phase we are again outputting something to the log, then we are running the docker image as a container and mapping port 8888 on the localhost (the AWS CodeBuild instance) to port 8888 on the container (Lucee Server), then waiting for a bit, to give the container time to start and then running the curl command to see if we get a response and if not exiting the command with a value of 1 (which means failed). If we get past this stage, e.g. we did not exit 1 then we output some more to the log and using the docker push command, push the image to the ECR repository. Finally we are creating a file called imagedefinitions.json which contains the details of the newly generated image and is passed to the next step in the AWS CodePipeline, the deploy step.

Artifacts

artifacts:
  files:
    - imagedefinitions.json
  discard-paths: yes

The artifacts section of the buildspec is information about where AWS CodeBuild can find the build output and how AWS CodeBuild prepares it for uploading to the Amazon S3 output bucket. In our example we are specifying two things, firstly a file in thefiles: section, in this case, the imagedefinitions.json created at the end of the post build phase and also the discard-paths directive, which tells AWS CodeBuild to discard paths to files in the build output artifact.

And there is more…

There is also another phase not used in this example called “install” which is executed before the “pre-build” phase and many other options and parameters not used in this simple example. To see them all take a look at the Build Specification Reference for AWS CodeBuild page.

The code for this example is available on Github:

https://github.com/andrew-dixon/cfcamp-aws-ecs-example

Leave a Reply

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