If you are a website administrator who manages several instances of WordPress, you will know how repetitive a job it is to keep all your themes and plugins updated. Moreover, with so many new and interesting themes and plugins showing up every other day, you are bound to find yourself installing and uninstalling lots of them.
In this tutorial, you will learn how to use simple Puppet manifests and WP-CLI to automate activities like installing, deleting, and updating WordPress themes and plugins.
You will need the following:
Use this tutorial to set up both WordPress and Puppet: How To Create a Puppet Module To Automate WordPress Installation on Ubuntu 14.04
In this step, we’ll build on the vanilla WordPress installation we created in the first tutorial.
Our module will use WP-CLI (WordPress Command Line Interface) to perform most of its operations. As its name suggests, WP-CLI is a tool that allows us to interact with WordPress using the command line (and scripts) instead of a browser.
Now, create a module that allows us to interact with WP-CLI using Puppet.
Enter the Puppet modules directory.
cd /etc/puppet/modules
Let’s call the module wordpress_manager
. Create a new directory for it.
sudo mkdir /etc/puppet/modules/wordpress_manager
Create a directory named manifests
to store all its manifests.
sudo mkdir /etc/puppet/modules/wordpress_manager/manifests
In this step, we’ll automate the installation of WP-CLI. Installation of WP-CLI must be automated because it has to be present on every server which is running WordPress.
Here’s what we do in this class:
curl
is installed. This is needed to download the latest version of WP-CLI.php5-cli
is installed.curl
and place it in the /usr/bin
directory.775
or a+x
.Use nano
to create a new file named install.pp
.
sudo nano /etc/puppet/modules/wordpress_manager/manifests/install.pp
Add the following code to it. The in-line comments should help you understand what the code does:
class wordpress_manager::install {
# Install curl
package { 'curl':
ensure => latest
}
# Install php5-cli
package { 'php5-cli':
ensure => latest
}
# Download WP-CLI using curl
exec { 'Install WP CLI':
command => "/usr/bin/curl -o /usr/bin/wp-cli -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar",
require => [ Package['curl'], Package['php5-cli'] ],
creates => "/usr/bin/wp-cli"
}
# Change the mode of WP-CLI to a+x
file { '/usr/bin/wp-cli':
mode => "775",
require => Exec['Install WP CLI']
}
}
The creates
attribute in the exec
command is there to check if WP-CLI has already been downloaded. Without this attribute, Puppet will download WP-CLI every time the module is used.
To manage themes, WP-CLI’s theme
command should be used. In our manifest, we use the activate, delete, install, and update subcommands with the theme
command. Similarly, to manage plugins, WP-CLI’s plugin
command should be used. We use the activate, deactivate, install, uninstall, and update subcommands with the plugin
commands.
Therefore, our defined type needs the following parameters:
$resource_type
- Its value will be either plugin
or theme
.$action
- This will be one of the subcommands.$resource_name
- The name of the plugin or theme.$root_directory
- This is necessary and important because the wp-cli
command has to be run from inside the directory where WordPress is installed.$user
- The value of this parameter should be the username of the Unix user which owns the WordPress instance.Here’s what we do in this type:
In order to avoid errors, add the following restrictions using the unless
and onlyif
attributes of Puppet’s exec
command:
is-installed
command is used to determine if the item is installed or not.Create a new file named resource.pp
.
sudo nano /etc/puppet/modules/wordpress_manager/manifests/resource.pp
Add the following code to it. Again, the in-line comments should help you understand what the code does.
Note: By default, our module will use /var/www
as the Wordpress installation directory, and root
as the Wordpress files owner. You might have to change the values of the $root_directory
and $user
attributes toward the top of the code to reflect your environment.
define wordpress_manager::resource (
$resource_name,
$resource_type,
$root_directory = "/var/www/",
$action,
$user = "root",
) {
# Make sure WP_CLI is installed
require wordpress_manager::install
$wp_cli = "/usr/bin/wp-cli --allow-root"
# Install the theme or plugin unless it is already installed.
if $action == "install" {
exec { "Install $resource_name":
command => "$wp_cli $resource_type $action $resource_name",
unless => "$wp_cli $resource_type is-installed $resource_name",
cwd => $root_directory,
user => $user
}
}
# Activate or update the theme or plugin only if it is currently installed.
if $action == "activate" or $action == "update" {
exec { "$action $resource_name":
command => "$wp_cli $resource_type $action $resource_name",
onlyif => "$wp_cli $resource_type is-installed $resource_name",
cwd => $root_directory,
user => $user
}
}
# Uninstall or deactivate a plugin only if it is currently installed.
if $resource_type == "plugin" {
if $action == "uninstall" or $action == "deactivate" {
exec { "$action $resource_name":
command => "$wp_cli plugin $action $resource_name",
onlyif => "$wp_cli plugin is-installed $resource_name",
cwd => $root_directory,
user => $user
}
}
}
# Delete a theme only if it is currently installed.
if $action == "delete" and $resource_type == "theme" {
exec { "$action $resource_name":
command => "$wp_cli theme $action $resource_name",
onlyif => "$wp_cli theme is-installed $resource_name",
cwd => $root_directory,
user => $user
}
}
}
We use the --allow-root
flag for all WP-CLI commands in this module. It is required in order to handle WordPress instances that are owned by root. Without this flag, trying to run WP-CLI as root will fail with an error message saying:
Error: YIKES! It looks like you're running this as root. You probably meant to run this as the user that your WordPress install exists under.
Our Puppet module is now ready. Here are a few examples to help you understand how you can use it.
Let’s use our Puppet module to apply a new WordPress theme to a WordPress instance.
By default, WordPress uses the twentyfifteen
theme. Here’s what it looks like:
Let’s install and apply a new theme named expound
. To find more themes, you can browse through WordPress’s Themes Directory.
Use nano
(or the editor of your choice) to create a new file named manage_expound_theme.pp
.
nano /tmp/manage_expound_theme.pp
Add the following code to it:
wordpress_manager::resource { 'install expound':
resource_name => "expound",
resource_type => "theme",
action => "install"
}
wordpress_manager::resource { 'activate expound':
resource_name => "expound",
resource_type => "theme",
action => "activate",
require => WordPress_manager::Resource['install expound']
}
Use the puppet apply
command to run the manifest.
sudo puppet apply /tmp/manage_expound_theme.pp
After completing the run, the output should look similar to this:
Notice: Compiled catalog for zona-virtualbox in environment production in 0.81 seconds
Notice: /Stage[main]/Main/WordPress_manager::Resource[install expound]/Exec[Install expound]/returns: executed successfully
Notice: /Stage[main]/Main/WordPress_manager::Resource[activate expound]/Exec[activate expound]/returns: executed successfully
Notice: Finished catalog run in 13.72 seconds
Visit your WordPress site at http://your_server_ip/
to see the new theme in action:
If you want to delete a theme, you should first activate another theme. For example, if you want to go back to the twentyfifteen
theme, open manage_expound_theme.pp
again:
nano /tmp/manage_expound_theme.pp
Delete everything in the file, and overwrite it with:
wordpress_manager::resource { 'activate twentyfifteen':
resource_name => "twentyfifteen",
resource_type => "theme",
action => "activate"
}
wordpress_manager::resource { 'delete expound':
resource_name => "expound",
resource_type => "theme",
action => "delete",
require => WordPress_manager::Resource['activate twentyfifteen']
}
Apply the manifest again.
sudo puppet apply /tmp/manage_expound_theme.pp
You can now visit your WordPress site at http://your_server_ip/
to see the twentyfifteen
theme applied.
The Akismet plugin is installed by default, but it is not activated, so let’s use our Puppet module to activate the akismet
plugin now.
Create a new manifest named manage_akismet.pp
.
nano /tmp/manage_akismet.pp
Add the following code to it:
wordpress_manager::resource { 'activate akismet':
resource_name => "akismet",
resource_type => "plugin",
action => "activate"
}
Apply the manifest.
sudo puppet apply /tmp/manage_akismet.pp
You can check if Akismet was activated running the plugin list
command. By default, our module will use /var/www
as the WordPress installation directory, but if this is different for your environment, you can modify the --path
flag appropriately.
wp-cli --allow-root --path=/var/www/ plugin list
You should see an output similar to:
+---------+----------+--------+---------+
| name | status | update | version |
+---------+----------+--------+---------+
| akismet | active | none | 3.0.4 |
| hello | inactive | none | 1.6 |
+---------+----------+--------+---------+
Before a plugin can be uninstalled, you should make sure that it is not active. Here’s how you can uninstall akismet
. Open manage_akismet.pp
.
nano /tmp/manage_akismet.pp
Delete everything in the file, and overwrite it with:
wordpress_manager::resource { 'deactivate akismet':
resource_name => "akismet",
resource_type => "plugin",
action => "deactivate"
}
wordpress_manager::resource { 'uninstall akismet':
resource_name => "akismet",
resource_type => "plugin",
action => "uninstall",
require => WordPress_manager::Resource['deactivate akismet']
}
Re-run the manifest.
sudo puppet apply /tmp/manage_akismet.pp
Now, rerun the plugin list
command.
wp-cli --allow-root --path=/var/www/ plugin list
You will see that Akismet is not listed anymore.
+---------+----------+--------+---------+
| name | status | update | version |
+---------+----------+--------+---------+
| hello | inactive | none | 1.6 |
+---------+----------+--------+---------+
You now know how to manage your WordPress instance’s plugins and themes using a simple Puppet module. You have seen examples of how you can use the module to perform various tasks. For the sake of simplicity, all the examples in this tutorial make use of Puppet’s standalone mode.
As an example of something else you can do using Puppet, you can perform the same operations on multiple hosts using Puppet’s Agent-Master mode. All you have to do is use the type wordpress_manager::resource
in the node definitions of those hosts. To update the Akismet plugin on two hosts named host1
and host2
, the site.pp
of your Puppet Master should contain:
node 'host1', 'host2' {
wordpress_manager::resource { 'update akismet':
resource_name => "akismet",
resource_type => "plugin",
action => "update"
}
}
WP-CLI is very powerful and offers a lot of commands. Feel free to extend the module we created in this tutorial to add more WP-CLI commands. If you want to learn more, there is additional information about Puppet in this tutorial; to learn more about WP-CLI, you can refer to this tutorial.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Using a Puppet with WordPress theme is such a great idea. It’s a configuration management tool, used by system administrators in order to automate the process related to maintain a company’s IT infrastructure. On the other hand, individual Puppet-manifest files is useful to automate non-complex tasks. This can be indeed helpful to overcome administrator’s efforts of updating the content time to time.