---
slug: Getting Started with Ansible Installing and Configuring LAMP on Ubuntu 18.04
title: Getting Started with Ansible Installing and Configuring LAMP on Ubuntu 18.04
authors: [slorber]
tags: [hola, docusaurus]
---

<!-- truncate -->

import CodeBlock from '@site/src/components/CodeBloack';
import php from '@site/static/img/phpinfo.png';


<div className="head">Introduction</div>

<div classNam="text">Automating server setup is crucial in today's world, where applications often come and go. Tools like Ansible make this process easier by creating standard procedures for new servers and reducing mistakes that can happen with manual setups.</div><br/>

<div className="text">Ansible is great because it has a simple design and doesn't need extra software on your servers. It also comes with lots of useful features and built-in tools that make writing automation scripts easier.</div><br/>

<div className="text">This guide will show you how to use Ansible to automate the steps from our tutorial on setting up a LAMP stack (Linux, Apache, MySQL, PHP) on Ubuntu 18.04. A LAMP stack is like a bundle of tools that work together to let a server host dynamic websites and web apps. 'LAMP' stands for Linux (the operating system), Apache (the web server), MySQL (where site data is stored), and PHP (for processing dynamic content).</div><br/>

<div className="head">What You Need Before Automating Server Setup with Ansible</div>

<div className="text">Before you can use the playbook to automate the setup, make sure you have:</div><br/>

<div className="text">One main Ansible control node: This is an Ubuntu 18.04 machine with Ansible installed. It should be configured to connect to your other servers using SSH keys. Also, make sure this machine has a regular user with sudo permissions and has a firewall enabled. You can set up Ansible by following our guide on 'How to Install and Configure Ansible on Ubuntu 18.04'. One or more Ansible Hosts: These are remote Ubuntu 18.04 servers that you've already set up using Ansible. You can do this by following our guide on 'How to Use Ansible to Automate Initial Server Setup on Ubuntu 18.04'.</div><br/>

<div className="text">Before we dive in, let's make sure your Ansible control node can talk to and command your Ansible host(s). For a quick check, take a look at step 3 in our guide on 'How to Install and Configure Ansible on Ubuntu 18.04'.</div><br/>

<div className="head">Automating LAMP Setup: A Quick Guide with Ansible Playbook</div>

<div className="text">This Ansible playbook is like a shortcut compared to doing things step by step from our guide on 'How To Install Linux, Apache, MySQL and PHP (LAMP) on Ubuntu 18.04'.</div>

<div className="text">When you run this playbook, it will do the following on your Ansible hosts:</div>

<div className="text"><ol><li>Install aptitude, a tool Ansible likes to use instead of the regular apt package manager.</li><li>Install all the necessary packages for LAMP.</li><li>Create a special place for your website and set it up with Apache.</li><li>Turn on this new place for your website.</li><li>Turn off the default Apache website if you want to (you can decide).</li><li>Set a password for the big boss of your MySQL database.</li><li>Clean up some unnecessary things in MySQL.</li><li>Make sure your firewall allows traffic for your website on the internet highway</li><li>Add a little PHP script to test if everything's working.</li></ol></div>

<div className="text">After the playbook completes, you'll have a working web environment that runs PHP on Apache. It'll be set up just the way you wanted, thanks to the choices you made in the configuration.</div>

<div className="head">Fetching the LAMP Playbook and Dependencies</div>

<div className="text">Now, let's get our hands on the LAMP playbook and the things it needs from the do-community/ansible-playbooks place. We're going to copy this stuff to a special spot on the computer that controls Ansible.</div><br/>

<div className="text">If you've done this copying before when following another guide, find the folder where you saved these playbooks and run a command that looks like 'git pull' to make sure everything is up-to-date.</div>

<CodeBlock code={`cd ~/ansible-playbooks
git pull
`} /><br/>

<div className="text">If you've never done this before, let's start by making a copy of the do-community/ansible-playbooks stuff and putting it in a special place. Use the command below to do this:</div>

<CodeBlock code={`cd ~
git clone https://github.com/do-community/ansible-playbooks.git
cd ansible-playbooks
`} /><br/>

<div className="text">The things we want are kept in a folder called lamp_ubuntu1804. Inside, you'll find these files organized like this:</div>

<CodeBlock code={`lamp_ubuntu1804
├── files
│   ├── apache.conf.j2
│   └── info.php.j2
├── vars
│   └── default.yml
├── playbook.yml
└── readme.md
`} /><br/>

<div className="text">Let's take a quick look at what each of these files does:</div>

<div className="text"><ol><li>files/info.php.j2: This file is like a blueprint for creating a PHP test page on the web server's main spot.</li><li>files/apache.conf.j2: Think of this file as a plan for setting up the Apache VirtualHost.</li><li>vars/default.yml: Here, you can tweak settings in the playbook to match what you want.</li><li>playbook.yml: The real action happens in this file. It has a list of things to do on the remote server(s).</li><li>readme.md: This is just a text file with info about how to use this playbook.</li></ol></div>

<div className="text">Let's make some changes to how our playbook works. Go to the lamp_ubuntu1804 folder, find a file named vars, and open up a file called default.yml. You can use any text editor you like for this, just pick your favorite one!</div>

<CodeBlock code={`cd lamp_ubuntu1804
nano vars/default.yml
`} /><br/>

<div className="text">This file has some things you might want to change:</div>

<CodeBlock code={`---
mysql_root_password: "mysql_root_password"
app_user: "sammy"
http_host: "your_domain"
http_conf: "your_domain.conf"
http_port: "80"
disable_default: true
`} /><br/>

<div className="text">Here are some things you might want to change in this file:</div>

<div className="text"><ol><li>mysql_root_password: Choose a password for the main MySQL account.</li><li>app_user: Pick a non-root user on your server who will own the application files.</li><li>http_host: Your domain name.</li><li>http_conf: The name of the configuration file in Apache.</li><li>http_port: The HTTP port for your website (usually 80).</li><li>disable_default: Decide whether to turn off the default Apache website.</li></ol></div>

<div className="text">After updating the variables, save and close the file. If you used nano, press CTRL + X, Y, then ENTER.</div><br/>

<div className="text">Now, it's time to run the playbook on your server. Playbooks usually run on every server in your inventory, but we can target a specific server using the -l flag. Also, we can specify the user with the -u flag.</div><br/>

<div className="text">To run the playbook on 'server1' as 'sammy', use this command:</div>

<CodeBlock code={`ansible-playbook playbook.yml -l server1 -u sammy`} /><br/>

<div className="text">After running the playbook, you'll see output similar to this:</div>

<CodeBlock code={`Output

PLAY [all] *********************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************ok: [server1]

TASK [Install prerequisites] *********************************************************************************************************ok: [server1] => (item=aptitude)

...

TASK [UFW - Allow HTTP on port 80] *********************************************************************************************************
changed: [server1]

TASK [Sets Up PHP Info Page] *********************************************************************************************************
changed: [server1]

RUNNING HANDLER [Reload Apache] *********************************************************************************************************
changed: [server1]

RUNNING HANDLER [Restart Apache] *********************************************************************************************************
changed: [server1]

PLAY RECAP *********************************************************************************************************
server1             : ok=15   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
`} /><br/>

<div className="text">Once the playbook completes its tasks, open your web browser and enter the hostname or IP address of your server, as specified in the playbook variables, followed by "/info.php:</div>

<CodeBlock code={`http://server_host_or_IP/info.php`} /><br/>

<div className="text">You'll encounter a page similar to this:</div>

<img src={php} alt="PHP Info" /> <br/>

<div className="text">To enhance security, it's advisable to delete this page from the server after setup. You can do this by using the command rm -f /var/www/info.php once the setup is complete.</div><br/>

<div className="head">Accessing the LAMP Server Setup Script</div>
<div className="text">The LAMP server setup script discussed in this guide is located in the lamp_ubuntu1804 folder within the Cloudtopiaa Community Playbooks repository. To access or download the script contents directly, click the "Raw" button at the top of each script.</div><br/>

<div className="text">For your convenience, the complete contents of the playbook, along with its associated files, are also provided below.</div>

<CodeBlock code={`vars/default.yml`} /><br/>

<div className="text">The "default.yml" file has important information that a playbook uses for its tasks. For example, it might include the password for the main MySQL account and the name of the website for Apache to set up. So, if you need to adjust these details, you'd do it in this file.</div>

<CodeBlock code={`---
mysql_root_password: "mysql_root_password"
app_user: "sammy"
http_host: "your_domain"
http_conf: "your_domain.conf"
http_port: "80"
disable_default: true
`} /><br/>

<div className="text" style={{ fontSize:'28px' }}>files/apache.conf.j2</div>

<div className="text">The "apache.conf.j2" file is like a blueprint for setting up a special space on your Apache web server. It uses a file called "default.yml" to know specific details, like what the new space should be called and other important settings. So, when you want to change how your website works, you can do it by adjusting things in the "default.yml" file.</div>

<CodeBlock code={`<VirtualHost *:{{ http_port }}>
   ServerAdmin webmaster@localhost
   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>
`} /><br/>


<div className="text" style={{ fontSize:'28px' }}>files/info.php.j2</div>

<div className="text">The "info.php.j2" file is like a special script that helps test your new LAMP server (Linux, Apache, MySQL, PHP). It sets up a simple PHP test in the main location of your server, so you can make sure everything is working as it should. If you want to check if your server is running properly, this file helps you do that.</div>

<CodeBlock code={`<?php
phpinfo();
`} /><br/>

<div className="head">Understanding the playbook.yml File in Simple Terms</div>

<div className="text">The "playbook.yml" file is like the main plan that tells your computer what to do. In this plan, it first says which group of servers it's going to work on (probably all of them). Then, it mentions that it's going to do some important tasks with extra powers (like using sudo). After that, it grabs settings and options from another file called "default.yml" to know exactly what to do and how to set things up. So, it's a guide for your computer on getting everything ready.</div>

<CodeBlock code={`---
- hosts: all
  become: true
  vars_files:
    - vars/default.yml

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

  #Apache Configuration
    - name: Install LAMP Packages
      apt: name={{ item }} update_cache=yes state=latest
      loop: [ 'apache2', 'mysql-server', 'python3-pymysql', '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 }}"
      notify: Reload Apache

    - name: Enable new site
      shell: /usr/sbin/a2ensite {{ http_conf }}
      notify: Reload Apache

    - name: Disable default Apache site
      shell: /usr/sbin/a2dissite 000-default.conf
      when: disable_default
      notify: Reload Apache

  # MySQL 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 }}"

  # 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"

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

    - name: Restart Apache
      service:
        name: apache2
        state: restarted
`} /><br/>

<div className="text">Feel free to change these files as you like to make them work better for you. It's like customizing things to fit how you want to do your work.</div><br/>

<div className="con">Conclusion:</div>

<div className="text">In this guide, we used Ansible to make it easy to set up a special environment on a faraway computer. Since everyone has different preferences for working with databases like MySQL, we suggest looking at the official Ansible guide for more info and cool things you can do with the mysql_user tool.</div>

<div className="text">If you want to add more cool stuff to how your server works, check out our beginner's guide called "Configuration Management 101: Writing Ansible Playbooks." It will help you do even more awesome things with your computer.</div><br/>

<div className="text"><strong>Ready to explore? Dive into the guide and make your server even better!</strong></div>


