Terraform your Laravel deployments
One click PHP stack provisioning and deployment with terraform for your Laravel application in few minutes with Terraform-php-stack ๐
In this article we will use terraform to provision a lemp stack for a laravel application with all its configurations (database, php, nginx, firewall, ssl, etc) using terraform-php-stack.
PHP Stack Provisioning
Every PHP project you worked on has that phase when you need to deploy it to a desired environment that match the application requirement usually its a LEMP or a LAMP stack.
That may require you to install and configure all these applications on the server every time manually, which can be boring, time consuming and redundant.
Terraform-php-stack
Is a terraform project that i was working on to solve my PHP stack provisioning and configurations.
if you are dealing with that manually this will speed up your applications deployments. It can also help if you are migrating to a new server.
The good part is that you can also test it locally before deciding to run it on a production server.
I tried to make the project as user-friendly as possible, so you don't need to know Terraform to use it.
However, I will still provide a step-by-step explanation:
1. Installing Terraform
In fact terraform installation is very simple, i will only cover ubuntu/debian installation for other OS, you can check the official documentation (=>).
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
2. Setup Target machine
You can use this terraform project against a fresh linux instance (vps) or a local virtual machine which is cool to test stuff before a real deployment.
I used it for both cases, and things went very well๐๐ .
For local testing i use vagrant & VirtualBox, you can use any other hypervisor.
This is my Vagrantfile :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/jammy64"
config.vm.hostname = "kbouzidi"
config.vm.provision "shell", inline: <<-SHELL
apt update && hostname -I
SHELL
config.vm.network "private_network", type: "dhcp"
config.vm.provider "virtualbox" do |vb|
end
end
COPY SSH KEY
You need to copy your public ssh key to your target server.
ssh-copy-id user@targetIP
๐จ if you skip this probably you will be lost into a desert ๐๏ธ
Well only if you will use vagrant with its own private key.
3. Configure terraform-php-stack
In this part, I will walk you through how I used this for a Laravel 10 project, and don't worry, you don't need to know Terraform at all.
First, you need to clone the project
git clone git@github.com:Safemood/terraform-php-stack.git
To start, you need to copy the example files to create your own configurations.
cd terraform-php-stack
cp terraform.tfvars.example terraform.tfvars
As you can see, this is the folder structure :
โโโ main.tf
โโโ modules
โ โโโ install_dependencies
โ โ โโโ configure.sh
โ โ โโโ main.tf
โ โ โโโ variables.tf
โ โโโ install_node
โ โ โโโ main.tf
โ โ โโโ variables.tf
โ โโโ install_mysql
โ โ โโโ create_db.sh
โ โ โโโ main.tf
โ โ โโโ variables.tf
โ โโโ install_nginx
โ โ โโโ default.tftpl
โ โ โโโ main.tf
โ โ โโโ variables.tf
โ โโโ install_php
โ โ โโโ main.tf
โ โ โโโ php.ini
โ โ โโโ setup.sh
โ โ โโโ variables.tf
โ โโโ setup_app
โ โโโ main.tf
โ โโโ .env.tftpl
โ โโโ variables.tf
โโโ terraform.tfvars.example
What is important in here :
main.tf where we can set all the required modules.
modules folder where the supported modules exist.
terraform.tfvars where we can set our environment variables && configurations.
.env.tftpl the template .env file for your php project.
We will configure the whole deployment only from terraform.tfvars
ssh_host = "target ip"
ssh_user = "ssh user"
ssh_key = "private_key path"
php_version = "8.2"
webmaster_email = "example@test.com"
mysql_root_password = "crazySecurePassword"
git_repo = "git@github.com:laravel/laravel"
db_connexion = "mysql"
db_host = "localhost"
db_port = "3306"
db_name = "kbouzidi"
db_user = "safemood"
db_password = "terraform"
domain_name = "kbouzidi.com"
app_env = "production"
app_debug = false
scheme = "http" // 'https' will auto assign ssl certificates to your domain
stack_modules = ["dependencies", "node", "nginx", "php", "app", "mysql"] // dependencies","mysql", "nginx", "php","app" , "node"
system_dependencies = "git tmux vim zip unzip htop fail2ban"
installation_steps = [
# Set Folder Permissions
"sudo chgrp -R www-data storage bootstrap/cache",
"sudo chmod -R ug+rwx storage bootstrap/cache",
# Installation
"composer install --optimize-autoloader --no-dev",
"php artisan key:generate --force",
"php artisan storage:link --force",
"php artisan migrate --seed --force",
"sudo php artisan optimize:clear",
"npm install && npm run build",
"php artisan optimize"
]
What you need to know :
stack_modules is an array of the modules that you wanna install :
dependencies : to install required system dependencies and make other necessary configurations.
php : to install php on the system with the required version "php_version".
node : to install nodejs & npm on the system with the required version "node_version".
nginx : to install nginx and setup an nginx web server.
mysql : to install and setup a mysql server and a dadicated database to your project with the required permissions.
app : to setup and install our application.
Some other important notes:
scheme : https will auto assign ssl certificates to your domain using certbot.
git_repo : when its a private repo, you will need to add a deploy key to your project (link).
๐จ for private github repo make sure to use deploy keys so the token has access only to the related project only.
4. Deployment
Deployment is the simplest part; just access the 'terraform-php-stack' folder and hit :
terraform init // only the first time
terraform apply
// or if you know what your doing ๐ฅ
terraform apply --auto-approve
You can see how the deployment process works in action.
As you have seen, the whole LEMP stack took only 4 minutes!
You can destroy this infrastructure with :
terraform destroy
5. Thoughts
I created this with Laravel โค๏ธ in mind and i really love to expand it to be helpful for all major PHP framework and stacks ๐ค๐ฅฐ.
What i have in mind for this project:
Add Symfony support .
Add a fully docker version to provision the whole stack with containers.
Add support for major cloud providers (aws, google cloud, azure) to make PHP stack provisioning easier on these platforms.
...
I hope the information I provided was helpful. If you have any questions or need further clarification, don't hesitate to reach out to me. I'm always open to feedback, so please feel free to share any thoughts or suggestions you may have.
You can find me on LinkedIn || Twitter || Github!
Feel free to drop by and say hello - I'm always up for meeting new people and expanding my network!๐