DEV Community

Cover image for How to Set Up an Automated LEMP Stack on AWS Using Ansible
Alan Varghese
Alan Varghese

Posted on

How to Set Up an Automated LEMP Stack on AWS Using Ansible

Manually setting up a LEMP stack — Linux, Nginx, MySQL, and PHP — can be a tedious process, especially when you need to deploy it repeatedly across different environments. Each setup involves installing multiple services, editing configuration files, and verifying connectivity.

To simplify and automate this process, I used Ansible to deploy a fully functional LEMP stack on an AWS EC2 Ubuntu instance. With a single command, Ansible provisions and configures the entire stack — from installing Nginx and PHP to setting up MySQL and verifying the PHP environment.

In this blog, I’ll walk you through the structure, playbook, and testing process for building an automated LEMP server using AWS and Ansible.

What Is a LEMP Stack?

The LEMP stack is a popular open-source web platform used to host dynamic websites and applications. It consists of:

  • L – Linux: The operating system (Ubuntu 24.04 on AWS EC2)

  • E – Nginx: High-performance web server

  • M – MySQL: Database management system

  • P – PHP: Scripting language for server-side logic

Unlike Apache in the LAMP stack, Nginx handles requests more efficiently under heavy load, making it ideal for modern web applications.

Technologies Used

OS ---> Ubuntu 24.04 (EC2)
Web Server ---> Nginx
Database ---> MySQL
Backend ---> PHP
Automation ---> Ansible
Cloud ---> AWS EC2

Project Structure

automated-lemp-setup/
├── inventory.ini
├── lemp_playbook.yml
├── README.md
└── screenshots/
├── ec2-launch.png
├── ssh-access.png
├── inventory-setup.png
├── playbook-run.png
└── phpinfo-confirmation.png

How the Automation Works

Ansible connects to your EC2 instance via SSH and executes a playbook (lemp_playbook.yml) that automates all installation and configuration tasks.

The playbook performs the following actions:

  1. Updates system packages.

  2. Installs and configures Nginx, MySQL, and PHP-FPM.

  3. Updates Nginx’s default configuration to support PHP.

  4. Deploys a test PHP file to verify setup.

  5. Restarts Nginx automatically via Ansible handlers.

The Ansible Playbook

Below is the main automation playbook used for deployment:

  • name: Automated LEMP Stack Deployment on AWS hosts: webserver become: true

tasks:
- name: Update apt cache
apt:
update_cache: yes

- name: Install Nginx
  apt:
    name: nginx
    state: present

- name: Install MySQL server
  apt:
    name: mysql-server
    state: present

- name: Install PHP and extensions
  apt:
    name:
      - php-fpm
      - php-mysql
    state: present

- name: Configure Nginx to use PHP
  copy:
    dest: /etc/nginx/sites-available/default
    content: |
      server {
          listen 80 default_server;
          listen [::]:80 default_server;

          root /var/www/html;
          index index.php index.html index.htm;

          server_name _;

          location / {
              try_files $uri $uri/ =404;
          }

          location ~ \.php$ {
              include snippets/fastcgi-php.conf;
              fastcgi_pass unix:/run/php/php8.3-fpm.sock;
          }

          location ~ /\.ht {
              deny all;
          }
      }
  notify: Restart Nginx

- name: Upload PHP info file
  copy:
    src: phpinfo.php
    dest: /var/www/html/phpinfo.php
    mode: '0644'
Enter fullscreen mode Exit fullscreen mode

handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted

Testing the Setup

Once the playbook runs successfully:

  1. Open your browser and visit:

http://<your-ec2-public-ip>/phpinfo.php

  1. You should see the PHP Info Page, confirming that PHP and Nginx are configured correctly.

Troubleshooting Common Issues

  • Nginx failed to reload ---> Apache running in background ---> sudo systemctl disable apache2 && sudo systemctl stop apache2

  • MySQL failed to start ---> Conflicting DB process ---> Reboot instance and re-run playbook

  • PHP info not showing ---> Incorrect PHP-FPM socket path ---> Check version and update Nginx config

  • 502 Bad Gateway ---> PHP-FPM not running ---> Restart PHP-FPM and Nginx

  • IP changed after reboot ---> Dynamic public IP ---> Assign an Elastic IP in AWS

Tips

  • Always run apt update && apt upgrade before executing playbooks.

  • Allow inbound ports 22 (SSH) and 80 (HTTP) in your AWS security group.

  • Remove the phpinfo.php file after testing — it exposes sensitive configuration details.

  • Use Elastic IPs to maintain a permanent public address for your server.

Final Thoughts

Automating a LEMP stack with Ansible takes the guesswork out of deployment. What used to take hours — from server updates to PHP configuration — now completes in a few minutes with consistent results.

Whether you’re a student learning DevOps or an engineer building scalable infrastructure, mastering automation is one of the best ways to save time, reduce errors, and improve reliability.

“Automation doesn’t just make deployment faster — it makes it smarter.”

🔗 Portfolio:

Top comments (0)