Install LAMP Stack on Ubuntu / Debian with Ansible

Posted on 147 views

LAMP stack is an acronym for Linux, Apache, MySQL/MariaDB, and PHP stack. This forms a powerful stack that powers many websites and web applications on the internet. LAMP stack is a combination of the four open-source projects that when put together will give you a complete solution. In this guide, we shall discuss how to set up a LAMP stack on Ubuntu/Debian using Ansible.

LAMP Stack comprises the following open-source software applications.

  • Linux – This is the operating system hosting the Applications.
  • Apache – Apache HTTP is a free and open-source cross-platform web server.
  • MySQL/MariaDB – Open Source relational database management system.
  • PHP – Programming/Scripting Language used for developing Web applications.

We shall discuss all that is needed to set up the stack, including how to prepare your environment for this.

Ansible is an open-source configuration management and orchestration tool that is widely used for automating tasks and operations for system administrators and cloud users.

Setup Pre-requisites

Before we can get started, make sure you have the below minimum requirements.

  1. Ubuntu 20.04 or Debian 10/11 hosts
  2. A remote user with sudo privileges
  3. SSH key authentication set up for remote execution
  4. Ansible installed on your control node

1) Environment Preparations

In this guide, we shall be making use of Ansible playbooks and roles. These are some of the modules that make Ansible much easy to use.

If you don’t have Ansible installed on your machine (your workstation), you can install it with the commands below. Remember, this shouldn’t be done on the servers we intend to deploy the LAMP stack, but rather the machine you will use to run the ansible commands.

For Ubuntu/Debian:

sudo apt install ansible -y

For RPM-based OS:

sudo yum install ansible -y

Configure SSH key authentication to the remote server:

ssh-copy-id [email protected]

Create a directory on your workstation that will be used as the working directory for this setup.

mkdir ansible_playbook && cd $_

2) Configure Ansible Playbook and Roles.

As discussed before, we shall configure Ansible playbooks and roles to perform the tasks below:

  1. Install Aptitude, prefreded package manager for Ansible
  2. Will install Apache, MariaDB-server and PHP
  3. Create and enable a VirtualHost for Apache
  4. Disable the default VirtualHost for Apache
  5. Configure the root password for MariaDB
  6. Configure PHP test file
  7. Allow HTTP traffic through the firewall.

We will create an ansible role for Apache and PHP installation and another one for MariaDB installation.

Create Default Variables

Create the default variables file that will contain information such as the domain name, MariaDB root password, etc.

In our working directory, create a sub-directory named vars and add a variables configuration file.

mkdir vars && cd vars
vim default.yml

In the default.yml file, add the information below, replacing the variables with your details.

mysql_root_password: "[email protected]"
app_user: "apache"
http_host: ""
http_conf: ""
http_port: "80"
disable_default: true

Create a hosts inventory file in the default working directory. Here, we add the IP of the remote server that we intend to set up LAMP stack.

vim hosts

Create Apache Role

Create a roles sub-directory from the working directory and another sub-directory for Apache.

mkdir -p roles/apache

Here, we need to create the role for Apache and PHP, which shall contain all the required steps, modules, and templates for Apache service.

Create Apache & PHP task

Create the main execution task for Apache and PHP, inside the Apache directory

mkdir tasks && cd tasks
vim main.yml

Add the content below in the main.yml file:

- name: Install prerequisites
  apt: name= item  update_cache=yes state=latest force_apt_get=yes
  loop: [ 'aptitude' ]

  #Apache Configuration
- name: Install Apache and PHP Packages
  apt: name= item  update_cache=yes state=latest
  loop: [ 'apache2', 'php', 'php-mysql', 'libapache2-mod-php' ]

- name: Create document root
    path: "/var/www/ http_host "
    state: directory
    owner: " app_user "
    mode: '0755'

- name: Set up Apache virtualhost
    src: "files/apache.conf.j2"
    dest: "/etc/apache2/sites-available/ http_conf "
- name: Enable new site
  shell: /usr/sbin/a2ensite  http_conf 
- name: Disable default Apache site
  shell: /usr/sbin/a2dissite 000-default.conf
  when: disable_default
  notify: Reload Apache
# UFW Configuration
- name: "UFW - Allow HTTP on port  http_port "
    rule: allow
    port: " http_port "
    proto: tcp

  # PHP Info Page
- name: Sets Up PHP Info Page
    src: "files/info.php.j2"
    dest: "/var/www/ http_host /info.php"

- name: Reload Apache
    name: apache2
    state: reloaded

- name: Restart Apache
    name: apache2
    state: restarted

Create Apache Handlers

Add the Handlers for Apache. This should be done under the Apache role directory:

mkdir handlers && cd handlers
vim main.yml

Add the following content for the Apache handlers

- name: Reload Apache
    name: apache2
    state: reloaded

- name: Restart Apache
    name: apache2
    state: restarted

Add Apache Files

Create the files that will be used for the generation of the VirtualHost and the info.php index file. This is also done in the Apache role directory

mkdir files && cd files

Create the VirtualHost file

vim apache.conf.j2

    ServerAdmin [email protected]
    ServerName  http_host 
    ServerAlias www. http_host 
    DocumentRoot /var/www/ http_host 
    ErrorLog $APACHE_LOG_DIR/error.log
    CustomLog $APACHE_LOG_DIR/access.log combined

          Options -Indexes

        DirectoryIndex index.php index.html index.cgi  index.xhtml index.htm

Create the PHP test file

$ vim info.php.j2

Ensure your Directory tree looks like this:

../apache$ tree

├── files
│   ├── apache.conf.j2
│   └── info.php.j2
├── handlers
│   └── main.yml
└── tasks
    └── main.yml

3 directories, 4 files

Create MariaDB Role

Create a role for MariaDB. Create a directory for the MariaDB task, in the roles directory.

mkdir -p mariadb/tasks && cd mariadb/tasks

Create a configuration file for MariaDB task:

vim main.yml
- name: Install prerequisites
  apt: name= item  update_cache=yes state=latest force_apt_get=yes
  loop: [ 'aptitude' ]

 #Install MariaDB server
- name: Install MariaDB Packages
  apt: name= item  update_cache=yes state=latest
  loop: [ 'mariadb-server', 'python3-pymysql' ]

# Start MariaDB Service
- name: Start MariaDB service
    name: mariadb
    state: started
  become: true

 # MariaDB Configuration
- name: Sets the root password
    name: root
    password: " mysql_root_password "
    login_unix_socket: /var/run/mysqld/mysqld.sock

- name: Removes all anonymous user accounts
    name: ''
    host_all: yes
    state: absent
    login_user: root
    login_password: " mysql_root_password "

- name: Removes the MySQL test database
    name: test
    state: absent
    login_user: root
    login_password: " mysql_root_password "

Confirm that your structure for the Ansible roles looks like this:

../roles$ tree
├── apache
│   ├── files
│   │   ├── apache.conf.j2
│   │   └── info.php.j2
│   ├── handlers
│   │   └── main.yml
│   └── tasks
│       └── main.yml
└── mariadb
    └── tasks
        └── main.yml

6 directories, 5 files

Create the Ansible Playbook

Create a playbook in the parent working directory which makes use of the roles we just created above.

$ vim lampstack.yml
- name: configure lamp
  hosts: lampstack
  become: yes
  become_method: sudo
    - vars/default.yml
    - apache
    - mariadb

The entire configuration tree from the working directory should conform to this:

../ansible_playbook$ tree
├── hosts
├── lampstack.yml
├── roles
│   ├── apache
│   │   ├── files
│   │   │   ├── apache.conf.j2
│   │   │   └── info.php.j2
│   │   ├── handlers
│   │   │   └── main.yml
│   │   └── tasks
│   │       └── main.yml
│   └── mariadb
│       └── tasks
│           └── main.yml
└── vars
    └── default.yml

8 directories, 8 files

30 Run Ansible Playbook to install LAMP Stack on Ubuntu / Debian

With our environment ready, we will need to run the playbook to install LAMP stack on Debian/Ubuntu

$ ansible-playbook -i hosts lampstack.yml -u 

Replace the option with the user you configured for SSH.

The configuration should start. Upon successful execution, you should get an output such as this below:


Our installation was successful. We can now check if we can reach the server from the browser.

Navigate to http://server-IP/info.php



We have successfully set up LAMP stack on Debian/Ubuntu with Ansible. As you can see, it is easier to configure your LAMP stack with Ansible. We can also reuse the playbook we created to configure more LAMP stack instances on-demand. Cheers!


Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.