Deploy Laravel PHP App to AWS Elastic Beanstalk using GitHub Actions – Ultimate Guide

Deploy PHP Laravel App to AWS Elastic Beanstalk using GitHub Actions

This article demonstrates how to deploy a PHP (Laravel) application to Elastic Beanstalk using GitHub Actions. A breakdown of the article is as follows.

We recommend reading this article without skipping any sections, as it will surely add alot of value.

Before We Deploy Laravel to Elastic Beanstalk from GitHub

If you’re replicating the steps of this walkthrough, make sure you do the following.

  • Fork or clone this Laravel repository from GitHub.
  • Deploy the PHP Laravel application to Elastic Beanstalk.

Our CloudOps Articles on Hosting Laravel Apps on AWS & Beanstalk

What are GitHub Actions?

GitHub Actions is a CI/CD platform. It automates your build, test, and deploy pipeline. Continuous Integration/Continuous delivery (CI/CD) is a popular standard in agile software development. The motive of a CI/CD pipeline is to automate all the processes involved in pushing applications to production. 

Speed is a crucial feature in agile software development, and that’s why CI/CD exists to automate workflows and quickly deploy application sprints all the way to production. Here’s a gentle introduction to CI/CD.  

Deploy PHP App to Elastic Beanstalk using GitHub Actions
GitHub Actions

GitHub Actions is built-in into GitHub and run workflows on corresponding events. These workflows go beyond the scope of DevOps and add many other functionalities – for instance, linting and sanity checks, commit message validation, and so on. Read more about GitHub Actions.

Workflow for Deploying our Laravel PHP App to Elastic Beanstalk using GitHub Actions

Here’s a block diagram that visualizes the complete workflow that we are going to bring to life in this article.

GitHub Actions CI/CD Pipeline Block Diagram
GitHub Actions CI/CD Pipeline Block Diagram

A textual overview of this workflow is as follows.

  1. The developer pushes a commit to the repository.
  2. On code push, GitHub Actions triggers the workflows and deploy the latest repository version to an S3 bucket. 
  3. GitHub Actions then updates Elastic Beanstalk to the latest application source code.

This breakdown is an abstract view. The following sections will dive into the specifics, and by the end of this article, we will have a working Elastic Beanstalk application with a CI/CD pipeline.

Step 1 | Create IAM Users with Appropriate Permissions

It is always recommended to assign the least privileges to users so that they can only do what they are supposed to do and nothing more than that – Least Privilege Principle. On a similar note, we won’t use the root account for subsequent AWS access via GitHub Actions, and that’s why we create IAM users with two permissions.

  1. S3FullAccess
  2. ElasticBeanstalkFullAccess

GitHub Actions will interact with these AWS S3 and ElasticBeanstalk, so we need a user with these specific permissions. Here’s how to create an IAM user in AWS.

1. Navigate to Identity Access and Management (IAM) in AWS Services.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
AWS IAM

2. In the IAM dashboard, navigate to Users.

IAM Dashboard
IAM Dashboard

3. In IAM > Users, click on Add users.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
Add IAM Users

4. Provide a username and check the Access key – Programmatic access. Click Next: Permissions to proceed.

Add Username
Add Username

5. Toggle to Attach existing policies automatically.

Attach a Policy
Attach a Policy

6. In the search box, type “AmazonS3FullAccess” and select the policy.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
AmazonS3FullAccess Permission

7. Repeat Step 6 for “AdministratorAccess-AWSElasticBeanstalk”

EBSFullAcess Permission
EBSFullAcess Permission

8. Click Next: Tags to proceed further.

9. Add a tag (optional) and click on Next: Review.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
Add Tags

10. Review the user, double check the permissions, and click Create User.

Review IAM User
Review IAM User

11. Copy your Access key ID and Secret access key to a secure destination. You can also download the .csv. 

Deploy PHP App to Elastic Beanstalk using GitHub Actions
IAM Credentials

12. Once you’re done, click Close.

Congratulations! Here’s the newly created IAM user among the pool of others.

IAM User Pool
IAM User Pool

Note: Never share your Access key ID and Secret access key.

Step 2 | Create an AWS S3 Bucket

As we have seen in the block diagram already, GitHub Actions upload the repository versions to an AWS S3 bucket. After that, it runs a job that uploads the new source code to Elastic Beanstalk. Why though? Just because we can’t upload to Elastic Beanstalk directly.

1. Navigate to S3 in the AWS service.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
AWS S3

2. In the S3 dashboard, click Create Bucket.

AWS Create Bucket
AWS Create Bucket

3. Provide a unique bucket name, leaving the rest of the settings as such. Scroll down and click Create bucket.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
Create S3 Bucket

Congratulations! The S3 bucket is initialized now.

Step 3 | Add GitHub Secrets

This step is going to be a quick one. We will add the access key ID and secret access key of the IAM user we created in step 1 to GitHub repository secrets.

Note: If you’re working on an organization’s repository and don’t have admin-level access to a repository, you won’t be able to add secrets.

  1. In the GitHub repository, navigate to the Settings tab.
GitHub Settings
GitHub Settings

2. Click on Secrets > Actions.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
GitHub Secrets

3. Click New repository secret.

Add New Repository Secret
Add New Repository Secret

4. Add IAM user Access key ID.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
Add Access Key ID to GitHub

5. Repeat the last step for the Secret access key.

Add Secret Access Key to Github

Add Secret Access Key to GitHub

Perfect! We are good to go with secrets. Next, let’s move to the fun part: GitHub Actions.

Step 4 | Get Started GitHub Actions

GitHub Actions uses a .yml file that specifies the template for the pipeline workflow. The most basic out-of-the-box template file looks like this.

name: CI

on:
 push:
   branches: [ master ]

jobs:
 deploy:
   runs-on: ubuntu-latest

   steps:
     - uses: actions/checkout@v2

Looks gibberish? Isn’t it, or perhaps you’re just not familiar with it at the moment? Consider reading the official documentation that demystifies it really well. 

So, setting up a CI/CD via GitHub Actions is all about knowing the ins and outs of the .yml template. We will build upon it and add more steps to materialize our CI/CD pipeline.

1. In the repository, navigate to the Actions tab, and click on the link “setup up a workflow yourself”

Deploy PHP App to Elastic Beanstalk using GitHub Actions
GitHub Actions

2. The basic .yml template appears. We can edit it in place.

main.yml
main.yml

Step 5 | Build CI/CD Pipeline using .yml File

The subsequent sub-sections will modify and add the .yml file. 

Note: The term “step” in the preceding text refers to the steps in the .yml file template.

5.1 – Add Environment Variables

First, change the name and add environment variables to the file. We will be using these environment variables in the steps. Moreover, we have done some cleanup and removed unnecessary lines. You can copy the .yml and supply your env variables.

name: fuelingphp-laravel-cd

env:
  "S3_BUCKET_NAME": "fuelingphp-laravel-bucket"
  "EBS_APPLICATION_NAME": "fuelingphp-laravel-prod"
  "EBS_ENVIRONMENT_NAME": "Fuelingphplaravelprod-env"
  "AWS_REGION": "us-east-1"
  "DEPLOY_PACKAGE_NAME": "laravel-app-${{github.sha}}.zip"
  
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]


  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

  steps:
      - name: Clone the repository
      - uses: actions/checkout@v3

The env contains all the environment variables. All of them are intuitive except DEPLOY_PACKAGE_NAME, which creates a unique name for every zip file it deploys to S3 to differentiate between versions. The uniqueness comes from the ${{github.sha}} variable – a Git unique hash for every commit.

5.2 – Add Step to Zip Cloned Repository

The first step is to clone a repository. Next, we will add another step that would zip up this clone and assign it a unique name. In the next sub-section, we will add another step to upload this zip file to the S3 bucket.

To do that, we will add the lines under the steps as follows.

 steps:
      - name: Clone the repository
        uses: actions/checkout@v3

      - name: Zip the repository
        run: zip -r ${{env.DEPLOY_PACKAGE_NAME}} ./ -x *.git*

5.3 – Configure AWS Credentials

The next step includes configuring AWS credentials. We will use AWS action provided by the GitHub marketplace. We will add IAM user secrets from GitHub as well. That would be yet another step added after the zip repository step.

   - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          node-version: 16
          aws-access-key-id: ${{secrets.ACCESS_KEY_ID}}
          aws-secret-access-key: ${{secrets.SECRET_ACCESS_KEY}}
          aws-region: ${{env.AWS_REGION}}

5.4 – Copy Deployment Package to S3 Bucket

The next step would run a command to upload the deployment package to the S3 bucket.

  - name: Upload Deployment to S3 Bucket
    run: aws s3 cp ${{env.DEPLOY_PACKAGE_NAME}} s3://${{env.S3_BUCKET_NAME}}/

5.5 – Update Elastic Beanstalk Application

The next step would run a command to update the Elastic Beanstalk application to the latest version.

- name: Create new Elastic Beanstalk Application Version
        run: |
          aws elasticbeanstalk create-application-version \
          --application-name ${{env.EBS_APPLICATION_NAME}} \
          --source-bundle S3Bucket="${{env.S3_BUCKET_NAME}}",S3Key="${{env.DEPLOY_PACKAGE_NAME}}" \
          --version-label "ver-${{ github.sha }}" \
          --description "commit-sha-${{ github.sha }}"

The commands here identify the right EBS application and point it to the latest bucket in the S3, which contains the latest repository package.

5.6 – Deploy PHP App to Elastic Beanstalk using GitHub Actions

Finally, we run a step to deploy to Elastic Beanstalk.

- name: Deploy new ElasticBeanstalk Application Version
       run: aws elasticbeanstalk update-environment --environment-name ${{env.EBS_ENVIRONMENT_NAME}} --version-label "ver-${{ github.sha }}"

5.7 – Print a Message to the Console

The last step would run a command to echo a completion message on the CI/CD console.

  - name: Print Success Message on Completion
    run: echo "CI/CD pipeline ran successfully"

5.8 – Commit .yml File

The final thing to do is to commit the .yml file. It is usually available in the .github/workflows folder in the repository.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
Commit main.yml

Congratulations! We have successfully completed the setup part of GitHub Actions. Here’s the final main.yml file.

name: fuelingphp-laravel-cd

env:
  "S3_BUCKET_NAME": "fuelingphp-laravel-bucket"
  "EBS_APPLICATION_NAME": "fuelingphp-laravel-prod"
  "EBS_ENVIRONMENT_NAME": "Fuelingphplaravelprod-env"
  "AWS_REGION": "us-east-1"
  "DEPLOY_PACKAGE_NAME": "laravel-app-${{github.sha}}.zip"
  
on:
  push:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Clone the repository
        uses: actions/checkout@v3

      - name: Zip the repository
        run: zip -r ${{env.DEPLOY_PACKAGE_NAME}} ./ -x *.git*
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          node-version: 16
          aws-access-key-id: ${{secrets.ACCESS_KEY_ID}}
          aws-secret-access-key: ${{secrets.SECRET_ACCESS_KEY}}
          aws-region: ${{env.AWS_REGION}}
          
      - name: Upload Deployment to S3 Bucket
        run: aws s3 cp ${{env.DEPLOY_PACKAGE_NAME}} s3://${{env.S3_BUCKET_NAME}}/
      
      - name: Create new Elastic Beanstalk Application Version
        run: |
          aws elasticbeanstalk create-application-version \
          --application-name ${{env.EBS_APPLICATION_NAME}} \
          --source-bundle S3Bucket="${{env.S3_BUCKET_NAME}}",S3Key="${{env.DEPLOY_PACKAGE_NAME}}" \
          --version-label "ver-${{ github.sha }}" \
          --description "commit-sha-${{ github.sha }}"
        
      - name: Deploy new ElasticBeanstalk Application Version
        run: aws elasticbeanstalk update-environment --environment-name ${{env.EBS_ENVIRONMENT_NAME}} --version-label "ver-${{ github.sha }}"
      
      - name: Print Success Message on Completion
        run: echo "CI/CD pipeline ran successfully"

Next, let’s test the pipeline.

Deploy PHP App to Elastic Beanstalk using GitHub Actions

Switch back to the Actions tab, and we’ll see the workflow initiated there.

GitHub Build
GitHub Build

Click on the build to see the pipeline steps in the process. If anything fails, we will be able to pinpoint the problematic stage.

Deploy PHP App to Elastic Beanstalk using GitHub Actions
Build Pipeline

Though we don’t see any issues, the build is deployed successfully.

Commit to Deploy PHP App to Elastic Beanstalk using GitHub Actions

Open your Laravel project locally and run the following command in the local main branch.

git pull origin main

Make a small change – it could be as simple as adding a comment. Afterward, run the following two commands

git commit -am “your commit message”

git push origin main

Switch to the Actions tab in the GitHub repository, and you’ll notice that a new workflow is already in progress.

Build in Progress
Build in Progress

That’s super cool and efficient. Hopefully, you’re already inspired by CI/CD.

Conclusion | Deploy PHP App to Elastic Beanstalk using GitHub Actions

This article explores how to deploy to Elastic Beanstalk from GitHub using Actions. GitHub Actions are popular CI/CD platform that’s easy, efficient, and fast. The article includes a block diagram that outlines the workflow of Elastic beanstalk to Github auto deployment. The rest of the sections then thoroughly explore each part of the flow.

First, we create an IAM user with S3 and EBS access. Following that, we create an S3 bucket with the intent to store the deployment packages. Afterward, we add secrets to the GitHub repository and then move on to the bulk of the article – creating the CI/CD pipeline.

GitHub Actions rely on a .yml file that defines the jobs and steps the pipeline should perform. The article breakdown this section into many sub-sections, which add steps to the file. Finally, with .yml ready, the article shows how the pipeline works in reality and what it does on every new commit.

Hope you’ve enjoyed this article. If you want to see similar articles, stay tuned at FuelingPHP.

Want to learn more about PHP?

We have many fun articles related to PHP. You can explore these to learn more about PHP.


© 2022 Confident.Systems