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.
- Create IAM User for AWS S3 and EBS access.
- Create an S3 bucket for storing deployment packages.
- Add credentials to GitHub repository secrets.
- Start with GitHub Actions – main.yml.
- Create CI/CD pipeline with main.yml file.
- Deploy to Elastic Beanstalk from GitHub.
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.

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.

A textual overview of this workflow is as follows.
- The developer pushes a commit to the repository.
- On code push, GitHub Actions triggers the workflows and deploy the latest repository version to an S3 bucket.
- 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.
- S3FullAccess
- 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.

2. In the IAM dashboard, navigate to Users.

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

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

5. Toggle to Attach existing policies automatically.

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

7. Repeat Step 6 for “AdministratorAccess-AWSElasticBeanstalk”

8. Click Next: Tags to proceed further.
9. Add a tag (optional) and click on Next: Review.

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

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

12. Once you’re done, click Close.
Congratulations! Here’s the newly created IAM user among the pool of others.

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.

2. In the S3 dashboard, click Create Bucket.

3. Provide a unique bucket name, leaving the rest of the settings as such. Scroll down and click Create 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.
- In the GitHub repository, navigate to the Settings tab.

2. Click on Secrets > Actions.

3. Click New repository secret.

4. Add IAM user Access key ID.

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

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”

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

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.

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.

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

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.

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.
Hosting Web Applications in AWS
This article is part of our series to make AWS easy. We love AWS, but let’s be honest. It isn’t effortless. Like way too complicated. We’ve created this learning path to help level you up and get your PHP app onboarded fast.
- Is AWS Cloud Services Hard to Learn?
- AWS PHP Website & Application Hosting Options
- Using PHP in AWS Lambda: Comparing Options
- Deploy Laravel to Elastic Beanstalk using GitHub Actions
- Deploy Laravel from Github to Elastic Beanstalk via CodePipeline
- Install LAMP Stack on AWS EC2
- Install AWS SDK for PHP
- Host and Deploy a Laravel PHP App to AWS Elastic Beanstalk
- Amplify vs Elastic Beanstalk
- AWS App Runner Review
- App Runner vs Elastic Beanstalk
- App Runner vs Fargate
- Elastic Beanstalk vs AWS Lightsail
- Elastic Container Service vs Beanstalk
- Setup & Use AWS Parameter Store in PHP
- How to use AWS Secrets Manager with PHP
- PHP & AWS S3