Building PHP Projects on AWS CodeBuild

AWS re:Invent 2016

I’ve had a great time at AWS re:Invent this week, attending sessions and hanging out with some of the ShootProof team. My favorite part of the week was the “mini con” on containers. I spent Thursday immersed in sessions dedicated to deploying Docker containers on AWS.

Of course, the main hightlight of re:Invent is always the keynotes and the new services and features announcements they make during the keynotes. One of the new services caught my attention, and I decided to give it a try. That service is AWS CodeBuild.

CodeBuild is designed to be used as part of the AWS CodePipeline, but it may also be used by itself. Additionally, with AWS’s increased focus on their container service (ECS), it’s designed to integrate with ECS to use images you’ve stored in AWS, but it may also use images available on Docker Hub.

Out of the box, CodeBuild provides some managed images that you may use to build your projects. These include environments for Android, Java, Python, Ruby, Golang, and Node.js. PHP is missing from this list, but since you’re able to use other images, I decided to see how easy it is to get up and running on CodeBuild with a PHP project. I chose to try out my ramsey/uuid library for a simple test. Feel free to follow along with me.

Getting Started

From your Amazon console, search for “CodeBuild” from the AWS Services search box, and choose it from the drop down menu that appears.

Figure 1. Search for “CodeBuild” from the AWS console

Search for CodeBuild from the AWS console

If you’ve not yet begun playing with CodeBuild, you’ll see a page like the one in Figure 2. Click the “Get Started” button to begin.

Figure 2. Getting started with CodeBuild

Getting started with AWS CodeBuild

Configuring Your Project

Figure 3 shows most of the options available when configuring a project, pre-filled for the ramsey/uuid library. I’ll step through each option to explain what’s going on.

First, provide a project name. Here, I’ve named the project “ramsey-uuid.”

For Source provider, choose GitHub and then click the link provided to connect to GitHub. This will take you through the OAuth dance to grant AWS with access to your GitHub account. Afterwards, the Repository drop-down will be populated with a list of your GitHub repositories. Here, I’ve selected the uuid repository.

Next, you need to tell CodeBuild how to build your project by specifying an image to use. To use an image in Docker Hub, select “Specify a Docker image” for Environment image and choose “Other” for Custom image type. For the Custom image ID, I’m using benramsey/composer-uuid:latest to specify the repository, image name, and image tag. You may place a buildspec.yml file in the root of your repository to specify build commands (similar to a .travis.yml file). Since ramsey/uuid doesn’t have a buildspec.yml file, I’m specifying the Build commands directly.

The full build command I’ve specified for ramsey/uuid is:

composer install --no-interaction --prefer-dist \
&& ./vendor/bin/parallel-lint src tests \
&& ./vendor/bin/phpunit --verbose --no-coverage \
&& ./vendor/bin/phpcs src tests --standard=psr2 -sp

Finally, I’m not generating any artifacts for this build, so I selected “No artifacts” for the Artifacts type, and I chose to let it automatically create a service role in my account.

Our project is now configured, so click Continue, review your choices, click Save and Build, then click Start build to run a build.

Figure 3. Configure a project (click to enlarge)

Configure a CodeBuild project

Building Your Project

As your project is building, you’re able to view the progress of each stage of the build, complete with the last 20 lines of the log output, or you may view the complete log in CloudWatch to see any errors or problems that were emitted during the build. If the build passes, you’ll see the word Succeeded in a comforting bold green.

Figure 4. Project build progress (click to enlarge)

View the progress of your project build

What Next?

My team is looking into CodeBuild as an alternative to running a dedicated Jenkins instance, and as we evaluate it, there are a few things we’re considering:

  • Some of our tests talk to a dev database in a VPC. How do we grant VPC access to a container running in CodeBuild?
  • In Jenkins, we capture a handful of artifacts, including code coverage reports and generated docblock documentation. With CodeBuild, we might consider copying these artifacts into an S3 bucket configured for website hosting.
  • What do we do about the other information we currently capture, like JUnit and Clover XML files?

Feel free to use ramsey/uuid and my directions here to play with CodeBuild, or use your own project. In the comments, let me know what you think and whether you’ve run into any caveats with your builds. If you come up with any solutions for the things we’re considering, I’d love to hear them.