I know I missed my last week’s Tuesday tutorial and it was for a good reason; I’ve been working on a tool (or rather a script) that will set up a server, perfectly suited and optimized for WordPress, in one minute. Yes, you read that right.
Developer, meet Ansible
In order to achieve that goal, we need to use a tool, also known as a provisioner. Those are quite commonly known among server administrators, but not so much in the WordPress community, due to their complexity. One of them stands out though, and it’s called Ansible. One of it’s strengths is that it uses SSH as a means to log onto server – the most common way there is. Furthermore, the configuration files are written in YAML format, which is really easy to read, write and understand (I’ll show that in a moment).
In case you still don’t know what a provisioner is: in plain english, it’s a tool to automate server configuration. And they are omnipotent, which means you can re-run the same commands over and over and it will not re-run them if they have already been run previously.
Example: You need to automatically install MySQL on a new server (or multiple servers at once), which only makes sense to do once. The second time you run the command, it will detect that MySQL is already installed and running, thus skipping that command.
Before we dig deeper into what Ansible can do, it makes sense to explain some basic terminology so that if you ever get confused you can refer to it (don’t worry if you don’t understand all of them, they’ll become much more clear once you start writing your first Ansible script):
- Tasks are the central entity of Ansible. Installing a program, updating configuration, copying files into place, everything is done via tasks, which is why we’ll focus on them most.
- Playbooks are files in which we put similar tasks, most commonly ones that perform similar operations or manage a particular service.
- Roles are directories in which we put playbooks to additionally organize tasks. Common roles are “database” and “webserver”.
- Files are just that: Normal files that we need to synchronize or upload to a certain directory on the server.
- Templates are special kind of files; They allow us to put in variables, which get replaced by their values when Ansible uploads templates to the server.
- Variables are placeholders that we can access from within the tasks or put them into templates. For example, if we need to set up a virtual host in our Nginx configuration, we would create a template, and the path to our document root would be stored in a variable. Variables can be set on a per-host, per-group or per-playbook basis (I’ll give some examples shortly).
- Handlers are special kind of tasks, similar to hooks in WordPress – they get called when a certain event occurs. If we update php configuration, we need to restart Nginx, and we do that with a handler.
- Inventories are configuration files in which we put our servers’ IP addresses. They do not have an extension (like *.yml)
- Groups are a way to organize (or rather group) our servers into inside inventories
- Hosts are individual servers (referred to by their IP or DNS addresses) inside groups
Since a picture speaks a thousand words, here’s how all the terms above come together in a real project:
Refer to the Ansible best practices to learn more on how an Ansible project should be organized.
Before we continue, make sure you have Ansible installed. Since it’s written in Python, and most operating systems ship with it already installed, you just need to run the following commands (they may look different on a Windows machine though, refer to the Ansible documentation) to make it work:
$ sudo easy_install pip $ sudo pip install ansible $ sudo pip install --upgrade ansible
To test whether it has been installed properly, just run
The perfect WordPress server
Now that you understand better how Ansible works and have it installed, I have a little present for you. I’ve written a basic script that in my opinion sets up not only a WordPress server, but also installs WordPress on it! You just need a blank server (We recommend DigitalOcean).
Without further ado, here’s my Ansible WordPress server setup. You’ll need git to clone the repository – or better yet, fork it. Why? Because I want this to become a community project, so that we all can contribute and discuss our best practices in order to really come up with the most optimal server setup.
[bctt tweet=”Configure the most optimal WordPress server in under a minute? Possible.”]
If you open the source, you’ll notice there are two *.yml files,
setup.yml. The former is used as the root user which essentially disables the root login and improves the overall security while the latter is our main script that installs and configures MySQL, Nginx, PHP, Monit and, of course, WordPress (using WP-CLI).
Before you can run it though, you’ll need to copy
group_vars/production.yml and create an inventory file
inventories/production with the following content (change the IP to point at your server):
Once you do that, you can now run ansbile (the
-k parameter will ask you for the root’s SSH password):
$ ansible-playbook first_run.yml -i inventories/production -k
Once this is done, you can re-run it, just to notice how it’ll skip the tasks because it can’t connect as the root user – that’s good!
With some basic security in place, it’s time to run the
setup.yml (note the capital K parameter, which will ask you for the sudo password):
$ ansible-playbook setup.yml -i inventories/production -K
Grab a coffee, wait a minute or two, then navigate your browser to whatever you set in the wordpress_site_domain variable (provided you have a DNS record pointing to that IP). What you should see is a basic WordPress installation. If you do, good job! (And if not, leave a comment)
I’m by no means an Ansible expert, which is why I’m asking you to share this article on social media (or email it to your nerdy friends). This will hopefully attract more developers, obsessed with how their Websites perform.