Use Ansible to install LAMP Stack on Ubuntu / Debian

LAMP stack is an acronym for Linux, Apache, MySQL/MariaDB and PHP stack. This forms a powerful stack that provides support for many websites and web applications on the Internet. The LAMP stack is a combination of four open source projects, putting them together will provide you with a complete solution. In this guide, we will discuss how to set up a LAMP stack on Ubuntu/Debian using Ansible.

LAMP Stack includes the following open source software applications.

  • Linux – This is the operating system hosting the application.
  • Apache —— Apache HTTP is a free and open source cross-platform Web server.
  • MySQL/MariaDB – Open source relational database management system.
  • PHP – A programming/scripting language used to develop web applications.

We will discuss everything needed to set up the stack, including how to prepare the environment for this.

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

Set up prerequisites

Before we start, please make sure you meet the following minimum requirements.

  1. Ubuntu 20.04 or Debian 10/11 host
  2. Remote user sudo privilege
  3. SSH key authentication set up for remote execution
  4. Ansible is installed on your control node

1) Environmental preparation

In this guide, we will use Ansible scripts and characters. These are some of the modules that make Ansible easier to use.

If Ansible is not installed on your machine (your workstation), you can install it using the following command. Remember, this should not be done on the server where we plan to deploy the LAMP stack, but on the machine you will use to run the ansible commands.

For Ubuntu/Debian:

sudo apt install ansible -y

For RPM-based operating systems:

sudo yum install ansible -y

Configure the SSH key authentication of the remote server:

ssh-copy-id [email protected]

Create a directory on your workstation to use as the working directory for this setting.

mkdir ansible_playbook && cd $_

2) Configure Ansible Playbook and roles.

As mentioned earlier, we will configure Ansible playbooks and roles to perform the following tasks:

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

We will create an ansible role Apache And PHP installation, the other is for MariaDB installation.

Create default variables

Create a default variable file containing the domain name, MariaDB root password and other information.

In our working directory, create a subdirectory called vars and add a variable configuration file.

mkdir vars && cd vars
vim default.yml

In the default.yml file, add the following information and replace the variables with your details.

---
mysql_root_password: "[email protected]"
app_user: "apache"
http_host: "lamp.example.com"
http_conf: "lamp.example.com.conf"
http_port: "80"
disable_default: true

Create Host The manifest file in the default working directory. Here, we add the IP of the remote server where we want to set up the LAMP stack.

vim hosts
....
[lampstack]
192.168.100.227

create Apache Role

Create a role subdirectory from the working directory and another subdirectory Apache.

mkdir -p roles/apache

Here we need to create the role Apache And PHP, which should contain all the necessary steps, modules and templates Apache service.

create Apache & PHP task

Create master task Apache And PHP, in it Apache contents

mkdir tasks && cd tasks
vim main.yml

Add the following content 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
  file:
    path: "/var/www/{{ http_host }}"
    state: directory
    owner: "{{ app_user }}"
    mode: '0755'

- name: Set up Apache virtualhost
  template:
    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 }}"
  ufw:
    rule: allow
    port: "{{ http_port }}"
    proto: tcp

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

- name: Reload Apache
  service:
    name: apache2
    state: reloaded

- name: Restart Apache
  service:
    name: apache2
    state: restarted

create Apache Processing program

Add handler Apache. This should be in Apache Role directory:

mkdir handlers && cd handlers
vim main.yml

Add the following content as Apache Processing program

---
- name: Reload Apache
  service:
    name: apache2
    state: reloaded

- name: Restart Apache
  service:
    name: apache2
    state: restarted

Add to Apache document

Create the files that will be used to generate the VirtualHost and info.php index files.This is also Apache Role directory

mkdir files && cd files

Create a virtual host file

vim apache.conf.j2

<VirtualHost *:{{ http_port }}>
    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

    <Directory /var/www/{{ http_host }}>
          Options -Indexes
    </Directory>

    <IfModule mod_dir.c>
        DirectoryIndex index.php index.html index.cgi index.pl  index.xhtml index.htm
    </IfModule>

</VirtualHost>

Create a PHP test file

$ vim info.php.j2
<?php
phpinfo();

Make sure 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 MariaDB tasks, in Role contents.

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

Create a configuration file for MariaDB tasks:

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
  service:
    name: mariadb
    state: started
  become: true

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

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

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

Confirm that your Ansible role structure 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 Ansible manual

Create a script in the parent working directory that uses the role we just created above.

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

The entire configuration tree in the working directory should meet the following requirements:

../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

After the environment is ready, we need to run the playbook to install the LAMP stack on Debian/Ubuntu

$ ansible-playbook -i hosts lampstack.yml -u <remote-user>

will Replace the options with the user you configured for SSH.

The configuration should start. After successful execution, you should get the following output:

Our installation was successful. We can now check whether the server can be accessed from the browser.

navigation https://server-IP/info.phpSet up lamp stack on debian ubuntu

in conclusion

We have successfully set up the LAMP stack on Debian/Ubuntu using Ansible. As you can see, it is easier to configure the LAMP stack with Ansible. We can also reuse the script we created to configure more LAMP stack instances as needed. cheers!

More guides on Ansible topics:

  • Use Ansible to manage SELinux status, context, ports, and boolean values
  • Use Ansible to generate an OpenSSL self-signed certificate
  • Install Ansible AWX on CentOS 8 / Rocky Linux 8
  • Use Ansible to manage users and groups on Linux

Related Posts