Terraform is an open source infrastructure as code(IaC) software tool. We will be using Terraform for creating AWS infrastructure. We can collaborate effectively when we configure the infrastructure using code and commit to our version control systems. We can also execute reviews/suggest new approaches for configuring certain tasks. Additionally, we can spin up new environments(like staging, production etc.) with ease when we use Terraform IaC.
LEMP(stands for Linux, NGINX, MySQL(or MariaDB) and PHP) is a ubiquitous tech stack used for developing and deploying web applications. I prefer NGINX over Apache due to its better performance and its underlying mechanism in handling/processing HTTP(S) requests. LEMP stack is open source, easily customizable/installable, and suits basic/complex web applications. We can run a simple PHP application in the LEMP stack or replace it with a framework like Laravel so that we don’t have to reinvent the wheel. Laravel aids in faster development of web applications.
This series of articles will provide an overview of setting up a LEMP(Laravel) application on AWS Fargate using Terraform and Docker. It will detail the steps needed to configure and deploy them to AWS.
A word of caution. Please note that the following article is not an attempt to dictate the best way to configure the LEMP stack. There are different ways to achieve the same result. AWS infrastructure and Terraform works best for our requirements, YMMV.
Laravel is a batteries-included web application framework that can handle low to a huge influx of users. The configuration/installation of Laravel framework on servers is pretty straightforward. All code/data reside on the same machine, making it easy for deployment (or) thereby removing all the complexities. The challenges and tricky parts pop up while setting up the application to run in a Dockerized environment that utilizes different infrastructure for each service. This challenge is mainly attributed to the monolithic design of Laravel. Building Docker images that are fit for each purpose requires informed decisions and clever scripting techniques. We will build a single image that can be run behind a web server, use it for processing queued jobs and execute scheduled commands.
I mentioned earlier that Laravel framework design is monolithic. This essentially means that web applications, queue workers and schedulers all share the same codebase. Deploying a Laravel application can be easily accomplished when the web application, queue worker and the scheduler is run on a single server. You need to think differently when you run the application in containers – one service in one container i.e. you would require
These containers cannot speak directly to each other as they are run in isolated environments. Hence, the trick is to make sure that the containers use a common codebase and a common medium for communication.
A container should run only one process in it. Several blog posts suggest otherwise when it comes to running LEMP applications i.e. integrate PHP and NGINX or PHP and Apache in a single container. I am personally against this approach. Containers provide many benefits:
We will be using NGINX and PHP-FPM for deploying Laravel web application in AWS Fargate. The whole infrastructure will be provisioned using Terraform. I have only outlined the core functionality/infrastructure needed to run your application. Please make informed decisions depending on your needs.
Containers package the code and its dependencies together into a single entity. This aids in accelerated development, testing and deployment. Containers make it easy in porting the application to different operating systems. Containers have lower operating costs and utilize resources more efficiently than legacy monolithic applications. LiteBreeze’s goto container management platform is Docker.
AWS Fargate’s advantage is the ability to run containers without the overhead of managing servers or clusters. Fargate abstracts the underlying infrastructure, allowing DevOps to only specify the container image, RAM and CPU requirements to run the application.
It’s straightforward to launch/setup an Amazon EC2 instance for hosting our web applications. However, the complexity increases when we want to deploy our application in a separate virtual private cloud, load balance it across multiple servers in multiple availability zones. Terraform makes it easy to configure complicated infrastructure. Please have a look at Terragrunt if you require a tool to manage multiple infrastructure environments.
litebreeze
.Multiple Terraform versions are being used in LiteBreeze at any given point. Hence I prefer tfenv for handling different versions of Terraform. Install tfenv in your development machine as per their documentation.
Create a folder and initialize a Git repo. Create a file called .terraform-version
inside the folder. Fill the file with the following content:
1.2.6
Execute the following command to install Terraform v1.2.6
tfenv install
Create the AWS cloud provider file provider.tf
and add the following content:
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.25" } } } provider "aws" { profile = "litebreeze" region = var.aws_region }
Execute the following command for Terraform to install the cloud providers mentioned in the above file. This needs to be only run for the first time.
terraform init
Commit and push the changes to the repository. All the codes related to the above section are available in this GitHub link.
Part 1 – Getting started with Terraform
Part 2 – Creating the VPC and ALB
Part 3 – Backing services
Part 4 – Configuring the LEMP stack in Docker
Part 5 – ECS