Setting up AWS codebuild to test a PHP project
Idealstack • January 14, 2018configuration
AWS Codebuild provides a reliable, cheap & easy way to automatically run your unit tests with every commit. We use it here at Idealstack to test and deploy.
Like a lot of AWS tools though it doesn't really support PHP "out of the box" and you've got to mess around to get it working well for PHP projects. Thankfully that's not too hard, and since we've gone through the work to get it running we thought we'd share it for your benefit.
Why use codebuild?
You need your tests to run every time you commit a new piece of code to github. If you run your tests manually they’ll get forgotten. I firmly believe there’s no point in writing unit tests unless you also automate them.
Codebuild (like most build tools) can report your build status to github, which gives you a handy indication of whether your builds are passing or failing for each commit, branch & pull request
If you're on AWS, I think the best way to get automated testing happening is AWS codebuild. It’s cheap - for many projects free under AWS's free tier (you get 100 free build minutes per month). You only pay for the builds you use, there's no fixed monthly fee, which makes it great for projects in maintenance mode that don't need of builds. It’s simple to setup and seldom needs ‘fixing’. And like most AWS services it does just one job and does it well, but you can hook it together into all the other AWS services to create any kind of custom solution you want.
The only problem is that, like a lot of AWS services, PHP is not a ‘first class’ supported language on Codebuild and you have to jump through a few hoops to get it going.
Let’s get started - setup codebuild to build your project
Firstly, let’s create a simple PHP project. We’ve used the Lumen microframework here, but really, any PHP code is fine:
If you want to follow along with this howto you might want to fork this repo on github. Or you might prefer to cut out the double-handling and setup codebuild on one of your real projects using these instructions.
Setup a new codebuild project
In the AWS console, go to CodeBuild
Click "Get Started"
In the section What to build? Find your repository on githib. We recomend you check the option Webhook (so builds happen automatically on commit) and the build badge (so codebuild updates pull requests, branches in github with build status).
How to build: Choose an ubuntu image. For the runtime we’ve chose Node.js, since we might be using node tools such as webpack in our build. If you don’t need this just choose ‘Base.’. Choose to get your buildspec from the source code root directory, and leave the buildspec name on the default of buildspec.yml
Choose to do nothing with the artifacts for now. You might want to do something such as upload them to s3 once you've got this working
Leave all the other settings on their defaults (we’ll talk about what you might use them for in a moment)
The most important thing here is the codebuild.yml file. This is a file you should create in the root of your repository that tells codebuild what to do. In our case, we need to bootstrap a PHP environment and run our unit tests.
There’s three ways to do that : one is to create a docker image, push it to ECR, and use that. But it's hard to keep this image up to date, especially if you aren't already using docker elsewhere. Or you can use a pre-existing docker container - if you strike it lucky and find one that’s well maintained configured exactly how you want it, that’s a good option.
Assuming you're not already using docker though, and you don’t want to dig around finding a docker image that suits you, don’t panic. You can pretty easily just use the default Ubuntu image codebuild provides - just install what you need as part of the build process. The buildspec.yml included in this repository does this : https://raw.githubusercontent.com/Idealstack/codebuild-example/master/buildspec.yml
It essentially just uses an inline script to install PHP, mysql or whatever else you need onto the stock ubuntu image that codebuild provides.
In this example we've installed php7.1 (you should just be able to change the version number to whatever you want), mysql (you may not need this - Laravel, Lumen etc often just use sqllite when running unit tests, although sometimes your code needs real Mysql to run. Here at Idealstack we push Mysql hard enough that SqlLite just won't work for us. We also install gulp, grunt & webpack (remove these if you don't use them)
Assuming you've got this buildspec file in place, you should be ready to build your project (either by doing a commit or clicking the "Start Build" button in Codebuild.
With luck, you should see your tests pass:
Setup notifications for codebuild
The other thing your most likely going to want is an email to tell you when your build fails. You can acheive this by setting an event handler in Cloudwatch
- Firstly, we setup an SNS topic to notify us. Go to the Simple Notification Service console in AWS
- Create a new topic
- Check the topic and choose Subscribe to Topic
- One the Create Subscription screen, choose the protocol as Email and enter your email address as the endpoint:
- Go to the Cloudwatch console in AWS
- Under Events in the Cloudwatch menu, click Create Rule
- Configure the Event Source like so: choose "CodeBuild" as the service name, "CodeBuild Build State Change" and choose the states you want to be emailed for:
- Under targets: Configure an SNS Topic. Select the SNS topic you created
In the Configure Input field, choose "Input Transformer". In the Input Path paste this:
Then in the "Input Template" paste this:
' has build status of '" '. https://us-west-2.console.aws.amazon.com/codebuild/home?region= #/projects/ /view
Now (once you confirm your email address for the SNS subscription) you should start receiving build notification emails when your builds complete.
When we were originally setting up codebuild, we relied on Ben Ramsey's helpful post. Ben does it a bit differently, you might want to check out his approach as well.
In the next post, we'll show you how to cache the build so we don't need to keep downloading composer and ubuntu packages on every build. This will speed things up a bit. We'll also upload code coverage reports from PHPUnit. Finally in part 3 we'll show how to deploy automatically over ssh