HomeDevOpsDeploying a Drupal Site from a Chef Role

Deploying a Drupal Site from a Chef Role

With a properly setup Chef repository and server, managing Drupal application deployments becomes a simple exercise of managing the subset of metadata within the combinations Chef role files that are specific to each deployment.


This article will focus solely on the mechanics of how to deploy a Drupal site by creating and updating a Chef role file, assigning it to a specific node’s run list, and initializing the deployment through a chef-client run. It assumes you have a working chef server setup to use the Drupal cookbook.

Generating the Role File

Role files contain the metadata used by the individual recipes within a cookbook. Here is an example role file used by the drupal-lamp project, which contain all the necessary attributes to manage a simple Drupal deployment using the Drupal cookbook.

    name: "example",
    description: "An example site to load Drupal.",
    chef_type: "role",
    json_class: "Chef::Role",
    override_attributes: {
        drupal: {
            sites: {
                example: {
                    active: 1,
                    deploy: {
                        action: [
                    repository: {
                        uri: "https://github.com/drupal/drupal.git",
                        revision: "7.26"
                    drupal: {
                        settings: {
                            profile: "standard"
    run_list: [

Let’s look more closely at the important components:

  • name: This is the short code that will be used to identify this specific Drupal site. It’s used for things like the database name, system paths, vhost filenames. etc.
  • uri: This is the git repo for the specific Drupal application.
  • revision: This is the branch name OR specific commit to deploy.
  • profile: This is the profile used during the installation. Post-installation, is the profile to reference to access custom themes, modules, etc.
  • active: This specifies that a deployment is to take place.
  • action: This specifies the type of deployment to take place (i.e. remove, clean install, or update).

It’s worth noting that more complex variations of the Drupal cookbook may contain multiple repositories. For example, one might modify the drupal cookbook (or add a cookbook to run after it) so that it can specify independent drupal webroot and drupal installation profile repositories. While the structure of the role file becomes more complex, the basic principles are the same.

Once this role file is generated (by hand, through a UI, or via an automated route), it should be placed within the /roles file directory of the chef repository and committed. At that point, it can be assigned to any number of nodes that need to deploy that specific repository.

Generating the Data Bags

Depending on which version of the Drupal cookbook you are using, you are going to need to use some form of a site specific databag to manage the database, drupal user1 credentials, and any other sensitive pieces of data used by the cookbook. A typical example might have the following form:

  id: "example",
  development: {
    db_user: "drupal",
    db_password: "drupal",
    admin_user: "example_admin",
    admin_pass: "admin"

Note the “id” here must link to the “name” used within the role file so the two can be associated together. Ideally this information is encrypted and uploaded to the chef server as soon as it’s modified.

Assigning to a Node

Now that a role file has been created, we need to assign it to a particular node’s run list (sidenote: each node should already have a base role assigned to, which may handle configuration management at the LAMP stack level) . This can be done in one of 2 ways:

  • Knife. One can either add this role to an existing run list OR apply all roles to a node during the bootstrap process.
  • Chef Server UI. One can login through the UI and associate a role to an existing node.

Once a role file exists on a chef server, there are several ways to update it.

  • Knife. One can manually run a command like knife role from file roles/ROLE.rb.
  • Jenkins. One can create an integration between Github Webooks and a Jenkins server to automatically update all cookbooks, roles, and databags when a new commit is merged into a particular branch. This is the preferred way because it’s more automated and provides an additional level of code review.

Triggering a Drupal Deployment

Once a role file is updated, it’s time to initiate the deployment to every node that use it. This is typically a 3 step process:

  1. Modify the role file’s action to install or deploy.
  2. Update the role file onto the Chef server (either via knife or a Jenkins job).
  3. Run chef-client on the node.

In a typical Chef configuration, each node is set to automatically run chef-client at 30 minute intervals. Therefore, getting the updated role file uploaded to the chef server via knife or Jenkins job is all that is needed to trigger the a deployment. However, there may be times when its desirable to manually trigger a job. This can be done by logging into the target node as a privileged user and running chef-client.

Notice! If you leave the role file’s action parameter set to deploy or install, it will complete this process every 30 minutes with each chef-client run. While this may be desirable in some instances (i.e. a continuous delivery model), you may wish to immediately follow-up by modifying the role’s ction attribute to disable all subsequent deployments from the Drupal cookbook until you’re ready to do so.


We’ve walked through a basic workflow of modifying a role file, uploading it to a Chef server, assigning it to a particular set of nodes, and initiating a deployment against those nodes. A little practice is all that is needed to realize that this is a simple and straightforward way to manage anywhere from a single to 1000’s of Drupal deployments.