We hope you find this tutorial helpful. In addition to guides like this one, we provide simple cloud infrastructure for developers. Learn more →

How To Create an Ansible Playbook To Automate Drupal Installation on Ubuntu 14.04

PostedDecember 23, 2014 50k views Ansible Drupal Configuration Management Ubuntu

Introduction

Ansible is a configuration management tool that system administrators use to automate infrastructure management activities.

Ansible uses only SSH to run commands remotely, and thus does not need an agent on the remote server. This makes Ansible preferable over other popular tools like Puppet or Chef when you don't want to install agents on the managed servers.

Moreover, it is much easier to get started with Ansible because it uses YAML (Yet Another Markup Language) which is simpler than the more powerful programming languages that other tools use.

Drupal is a popular CMS whose installation is time-consuming, but easy to automate. In this tutorial, we are going to create an Ansible Playbook that automates the installation and configuration of Drupal and all its dependencies on systems that run Ubuntu 14.04.

Prerequisites

You will need the following:

  • Ubuntu 14.04 server (which is accessible over SSH); this server will run Ansible and a local copy of Drupal
  • Optional: Additional Ubuntu 14.04 servers where you want to install Drupal
  • A sudo user on each server; you should use the same username and same password for each server where you want to install Drupal
  • A basic understanding of how a Drupal installation works. You can refer to How To Install Drupal on an Ubuntu 14.04 Server with Apache, although you do not need to pre-install Drupal

Step 1 — Install Ansible

Ansible is not available in the default repositories that apt-get uses. Therefore, add the repository ppa:rquillo/ansible.

sudo add-apt-repository ppa:rquillo/ansible

Press ENTER when prompted.

Update the package lists.

sudo apt-get update

Install Ansible.

sudo apt-get install ansible

Step 2 — Create a Directory for the Playbook

Ansible's instruction sets are called playbooks. It's a good idea to store all your playbooks in a single directory. Create a directory named MyPlaybooks.

mkdir ~/MyPlaybooks

Let us name our playbook drupal_setup. Create a new directory named drupal_setup.

mkdir ~/MyPlaybooks/drupal_setup

Step 3 — Create a hosts File

Each playbook usually has a hosts file that contains names of the servers that it should use.

In this tutorial, we are going to install Drupal on localhost and one other server, drupal_server. You are free to add more servers to this file. Remember, every server you add should be accessible over SSH.

Use nano to create and edit a file named hosts.

nano ~/MyPlaybooks/drupal_setup/hosts

Let it have the following contents:

[drupal_hosts]
localhost
drupal_server_ip

You should replace drupalserverip with your second server's IP address. You can list as many IP addresses here as you want; you can use this playbook to install Drupal on any number of Ubuntu 14.04 servers.

Note: The hosts file is the file you should update if you want to reuse this playbook in the future to configure more Drupal servers. Note that you should remove the already-configured servers from the list, and add your new server IPs, before you re-run the playbook.

Save and close the file.

Step 4 — Create a Role to apt-get update

Create a new directory to store all the roles of the Playbook.

mkdir ~/MyPlaybooks/drupal_setup/roles

We need to apt-get update the servers before doing anything else, so create a directory for the role update.

mkdir ~/MyPlaybooks/drupal_setup/roles/update

Each role has one or more tasks. Create a directory named tasks to hold all tasks associated with this role.

mkdir ~/MyPlaybooks/drupal_setup/roles/update/tasks

Use nano to create and edit a new task file named main.yml. This is the file that tells Ansible what to do when it executes this role.

nano ~/MyPlaybooks/drupal_setup/roles/update/tasks/main.yml

In this file, use Ansible's apt module to update the system:

---

- name: apt-get update the server
  apt: update_cache=yes

Make sure your file doesn't have any extra whitespace; Ansible is picky about this. Save and close the file.

Step 5 — Create a Role to Set Up PHP

Create a directory for the role php.

mkdir ~/MyPlaybooks/drupal_setup/roles/php

Create the tasks directory for this role:

mkdir ~/MyPlaybooks/drupal_setup/roles/php/tasks

Drupal needs a web server which is configured to use PHP. In this tutorial, we use Apache. When we install PHP, Apache is installed automatically, so we don't need any extra commands for it.

Use nano to create and edit the main.yml for the php role.

nano ~/MyPlaybooks/drupal_setup/roles/php/tasks/main.yml

Use Ansible's apt module to install PHP5 (and the packages it depends on), and the PHP5 GD library. Add the following to the file:

---

- name: Install PHP and associated packages
  apt: name=php5 state=latest

- name: Install PHP GD library
  apt: name=php5-gd state=latest
  notify:
    - Restart Apache

Apache has to be restarted after the PHP GD library is installed. Therefore, this role also needs a handler.

All handlers of a role are stored in a separate directory. Create a directory named handlers for the current role.

mkdir ~/MyPlaybooks/drupal_setup/roles/php/handlers

Use nano to create and edit the main.yml file.

nano ~/MyPlaybooks/drupal_setup/roles/php/handlers/main.yml

Add the following code to it:

---

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

You're done with the PHP and Apache setup.

Step 6 — Create a Role to Set Up MySQL

Drupal needs a database to store settings and content. In this tutorial, we use MySQL.

Create directories for this role and its tasks.

mkdir -p ~/MyPlaybooks/drupal_setup/roles/mysql/tasks

The first task of this role installs MySQL and its dependencies. Use nano to create and edit a file named setup.yml.

nano ~/MyPlaybooks/drupal_setup/roles/mysql/tasks/setup.yml

In this file, we will tell Ansible to use the apt module again to install:

  • mysql-server
  • libapache2-mod-auth-mysql
  • php5-mysql

So, add the following to the file:

---

- name: Install MySQL server
  apt: name=mysql-server state=latest

- name: Install Apache module for MySQL authentication
  apt: name=libapache2-mod-auth-mysql state=latest

- name: Install MySQL module for PHP
  apt: name=php5-mysql state=latest

Our role has one more tasks file. As Drupal needs its own MySQL database and database user, we will create a separate tasks file to create them. Use nano to create and edit a file named create_db.yml.

nano ~/MyPlaybooks/drupal_setup/roles/mysql/tasks/create_db.yml

Ansible has modules that let you manage MySQL. In this task, we will use the following modules:

  • mysql_db - To create a new database for Drupal.
  • mysql_user To create a new user and allow it to access the database.

Before we use mysql_db or mysql_user we should make sure that the Python MySQLdb package is installed on the remote host. Use the apt module to install it.

Add the following contents to the file:

---
- name: Install Python MySQLdb
  apt: name=python-mysqldb state=latest

- name: Create the Drupal database
  mysql_db: db={{ db_name }} state=present

- name: Create the Drupal user
  mysql_user: >
    name={{ db_user }}
    password={{ db_password }}
    priv={{ db_name }}.*:ALL
    host=localhost

Note that strings enclosed in {{ }} denote variables. In this task, we have the variables {{ db_user }}, {{ db_password}} and {{ db_name }}. We are going to set the values of these variables in a later step.

Next, we need to let Ansible know that this role has two tasks. To do this, we create a main.yml file.

nano ~/MyPlaybooks/drupal_setup/roles/mysql/tasks/main.yml

Add the following code to this file:

---

- include: setup.yml
- include: create_db.yml

Step 7 — Create a Role to Install Drupal

It's now time to move on to the installation of Drupal itself.

Create directories for this role and its tasks.

mkdir -p ~/MyPlaybooks/drupal_setup/roles/drupal/tasks

Use nano to create and edit a task file named main.yml.

nano ~/MyPlaybooks/drupal_setup/roles/drupal/tasks/main.yml

In this task, we will tell Ansible to perform the following actions:

  • Install git on the remote host. This is necessary because we will be using Ansible's git module
  • Use Ansible's git module to clone the latest stable version of Drupal from its repository at http://git.drupal.org/project/drupal.git. The downloaded files are placed in /var/www/html/drupal
  • Create the settings.php and services.yml files from the default files
  • Update the permissions of settings.php, services.yml, and sites/default/files

Add the following code to the file:

---

- name: Install git
  apt: name=git state=latest

- name: Clone Drupal
  git: >
    repo=http://git.drupal.org/project/drupal.git
    dest=/var/www/html/drupal/
    update=no

- name: Create settings.php
  command: cp /var/www/html/drupal/sites/default/default.settings.php /var/www/html/drupal/sites/default/settings.php

- name: Create services.yml
  command: cp /var/www/html/drupal/sites/default/default.services.yml /var/www/html/drupal/sites/default/services.yml

- name: Update permissions of settings.php
  file: path=/var/www/html/drupal/sites/default/settings.php mode=777

- name: Update permissions of services.yml
  file: path=/var/www/html/drupal/sites/default/services.yml mode=777

- name: Update permissions of files directory
  file: >
    path=/var/www/html/drupal/sites/default/files
    mode=777
    state=directory
    recurse=yes

You'll want to update the permissions for these files later after completing the browser installations on each server (on each server, rather than through Ansible).

Step 8 — Create a File to Use All the Roles

At this point, all our roles are ready. We now need to use them.

Use nano to create a file named site.yml. This is the file we will actually run with Ansible.

nano ~/MyPlaybooks/drupal_setup/site.yml

In this file we perform the following activities:

  • Specify the hosts that this Playbook will run on
  • Specify that sudo should be used to run all tasks of this Playbook
  • Set default values to variables used in various roles
  • Run all the roles

Add the following code to it:

---

- hosts: drupal_hosts

  sudo: yes

  vars:
    - db_name: drupal
    - db_user: drupal_user
    - db_password: drupal_db_pass

  roles:
    - update
    - php
    - mysql
    - drupal

Make sure you change the value of the variable db_password to something other than drupal_db_pass. You are free to change the values of the other two variables as well to match your preferences.

Step 9 — Establish an SSH Connection

Before you run the Playbook, your ~/.ssh/known_hosts file should have an entry for each of the hosts mentioned in the hosts file.

An easy way to do this is to connect once to each server listed in the ~/MyPlaybooks/drupal_setup/hosts file from this server, using SSH.

Connect to localhost via SSH using the command:

ssh localhost

If this is the first time you are connecting to the server this way, you will be prompted with a message that says:

The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is b1:18:3d:19:15:21:39:5a:f7:9f:3c:37:68:ba:62:01.
Are you sure you want to continue connecting (yes/no)?

Once you say yes, you will get a message saying:

Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.

Connect to any other servers listed in the hosts file:

ssh drupal_sudo_user@drupal_server_ip

Make sure you replace the username and IP address with the actual information for each server. Please keep in mind that the sudo username (drupal_sudo_user in the example) and password should be the same for each server, including localhost.

Note: Instead of using passwords, you could copy the SSH public key for the Ansible server's sudo user to the drupal_sudo_user's authorized_keys file on each managed server.

Once you have connected to each server, you are ready to run the playbook.

Step 10 — Run the Playbook

The Playbook is now ready to be tested. Fire it off using the ansible-playbook command. The -k option forces Ansible to ask for the SSH password, and is not necessary if you have set up passwordless authentication. The -K option forces Ansible to ask for the sudo password.

cd ~/MyPlaybooks/drupal_setup/
ansible-playbook -i hosts site.yml -kK

Enter the SSH password, and wait as the Playbook runs. Once the run completes, you'll have a fresh Drupal installation on your server.

Note: You could leave out the -k flag if you have added the SSH key from the Ansible server's sudo user to each managed server.

This will take a few minutes to run, and Ansible will show you what it is doing at each step.

Important: If you want to run this script to set up more servers in the future, you must remove the IP addresses of the servers that are already set up from the ~/MyPlaybooks/drupal_setup/hosts file, or Ansible will overwrite your customized Drupal sites.

Step 11 — Set Up Drupal

Now, you will be able to use a browser to access Drupal and complete the browser-based installation, at http://your_server_ip/drupal/.

Drupal Setup Page

If you need help with completing the browser installer for Drupal, follow along with the instructions in this article.

Your database settings will be the variables you set in the vars section of the ~/MyPlaybooks/drupal_setup/site.yml file.

Double-check that each server has a successful Drupal installation.

Step 12 — Clean Up the Host List

Now's a good time to remove the hosts from the ~/MyPlaybooks/drupal_setup/hosts file. That way, if you run the playbook again, you won't accidentally overwrite the hosts that you have already set up.

Troubleshooting

Note that YAML is whitespace-sensitive. If you are having trouble with your playbook, you probably have improper indentation or extra spaces in your .yml files.

If you see an error that looks like:

fatal: [server-name] => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host.

This means you missed adding an entry for one or more hosts in the ~/.ssh/known_hosts file.

You'll need to make a manual SSH connection to localhost or to the target remote server first. Then try running the playbook again.

Conclusion

With this tutorial, you have learned to create an Ansible playbook that sets up Drupal for you, along with Apache and MySQL. Before you use this playbook in production systems, you will have to further build on it to make the installation more secure. You could also use Drush commands in the playbook to manage the Drupal installation.

5 Comments

Creative Commons License