CICD With AWS CodePipeline and Laravel Vapor

Feb 15, 2022 3 minute read

Introduction

Continuous Integration / Continuous Delivery, or CI/CD for short, is a deployment practice where incremental code changes are made frequently & reliably. This blog will walk through the steps of creating an AWS CodePipeline pipeline to run PHPUnit tests on a Laravel project and subsequently deploy the project to Laravel Vapor, a serverless deployment platform for Laravel, powered by AWS

Each CodePipeline consists of a series of Deployment Projects each of which contains actions that are performed. Each project is executed when the previous task completes meaning that if the PHPUnit tests do not pass, the code will not be deployed to Vapor.

Create the Pipeline

Create The Pipeline

From the AWS Console create a new CodePipeline and give it a name. From there let's add our first stage of the pipeline, the source stage. For this stage we will create a connection to our Github account, select our repository and branch.

Set the Repository

Adding our Build Projects

Once we have the repository setup we'll need to create 2 CodeBuild projects. The first for running our tests and the second for deploying our code to Laravel Vapor.

Build projects use buildspec.yml files to specify configuration settings for the project. You can specify custom locations for these files. We will be placing our files in the .cicd directory.

Start by creating a CodeBuild project to run our tests. You'll need to specify the same Github repository we used during our pipeline build.

We need to tell the project how to run our tests. This is accomplished by using a buildspec file.
Add the following to a .cicd/PHPUnit_Test.yml file

1version: 0.2
2 
3phases:
4 install:
5 on-failure: ABORT
6 
7 runtime-versions:
8 php: 8.0
9 nodejs: 12.x
10 
11 commands:
12 - |
13 #Install composer
14 php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
15 php composer-setup.php ;
16 php -r "unlink('composer-setup.php');" ;
17 mv composer.phar /usr/local/bin/composer
18 
19 pre_build:
20 commands:
21 - |
22 rm -rf composer.lock
23 composer install --no-interaction --prefer-dist --optimize-autoloader
24 mv .env.staging .env
25 php artisan key:generate
26 
27 build:
28 on-failure: ABORT
29 commands:
30 - |
31 echo Running Tests...
32 ./vendor/bin/phpunit

You'll notice that we are telling the project what version of php and node we need in the build container. There are also different stages of the build process. Each of these stages runs basic commands to build our test environment and execute our tests.

Next, create a CodeBuild project for our Vapor deployment. Use the code below in your .cicd/Vapor_Deploy.yml file.

1version: 0.2
2 
3phases:
4 install:
5 on-failure: ABORT
6 
7 runtime-versions:
8 php: 8.0
9 nodejs: 12.x
10 
11 commands:
12 - |
13 #Install composer
14 php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
15 php composer-setup.php ;
16 php -r "unlink('composer-setup.php');" ;
17 mv composer.phar /usr/local/bin/composer
18 
19 pre_build:
20 commands:
21 - |
22 rm -rf composer.lock
23 composer install --no-interaction --prefer-dist --optimize-autoloader
24 composer require laravel/vapor-cli --update-with-dependencies
25 
26 build:
27 on-failure: ABORT
28 commands:
29 - |
30 echo Deploying to Vapor...
31 php vendor/bin/vapor deploy production --commit="${CODEBUILD_RESOLVED_SOURCE_VERSION}"

We will also need to authenticate to the Vapor services to allow our build project to perform the vapor deployment. In your build project, create a VAPOR_API_TOKEN environment variable and enter your Vapor API token as the value. Save the build project.

At this point your pipeline is complete and ready to test. Commit some code to your repository and watch the pipeline execute.

Complete Pipeline

Conclusion

In this blog we created an AWS CodePipeline to test a Laravel project and deploy the project to Vapor. The pipeline is triggered when changes are pushed to the main branch of a repository. We hope you enjoyed this blog post and thank you for reading.