• No results found

Puppet, Chef, Salt, and Ansible

While Cloud-Init is a general system for running scripts for whatever purpose you like, there are numerous tools dedicated solely to configuration management. Puppet, Chef, Salt, and Ansible aren’t the only options in this realm, but they are definitely the biggest players, and they have some important similarities and differences to consider if they are to be used as part of an OpenStack-backed deployment.

First off, all of these applications share the idea of plug and play modules (called

recipes in Chef, and playbooks in Ansible). These prebuilt blocks are the biggest thing that differentiates them from configuring a server with Bash or other

scripting tools like Cloud-Init. Modules are available from public repositories that anyone can submit to or retrieve from, similar to PIP in Python or NPM in

Node.js. Additionally, they have all attempted to come up with a simple

language/structure for describing a server’s configuration, handle installation errors, and provide different configurations for servers in different roles. The formats are familiar—JSON, YAML, etc., but the actual syntax and methodology are proprietary and not portable across solutions.

The language they were built upon, their need to have installed clients (Ansible, for example, doesn’t need one), and the breadth and depth of their module

libraries, are really what differentiates these tools from each other. As with most technologies, you will find enthusiastic supporters and dissenters of each, but for most purposes they are equivalent. In fact, their similarity, and the ability to

develop a generic syntax for their use, is a big reason why there is growing support for all of these tools within OpenStack.

Let’s look at what a simple Puppet Manifest might look like to configure a server to run Apache and PHP:

# install apache package { 'apache2': ensure => installed }

# start apache and ensure its running service { 'apache2':,

require => Package['apache2'], ensure => running

} # install php package { 'php5': require => Package['apache2'], ensure => installed }

#create an info.php file to show that this all worked file { '/var/www/html/info.php': ensure => file, content => '<?php phpinfo(); ?>', mode => 0444, require => Package['php5'] }

With the Puppet client correctly installed and the preceding file saved as

manifest.pp, you could then execute this template as follows: $ sudo puppet apply ./manifest.pp

Puppet deals with any error handling, determines the order things have to happen in based upon the require statements, and handles all of the differences in OS

types. For example, using these tools, you don’t have to write one script for

CentOS that installs software via Yum, and another version that supports apt-get installation on Debian or Ubuntu.

As was mentioned before, Heat actually provides hooks for all of these tools in the form of a SofwareConfig resource. If your configuration supports Chef, then a Heat template to set up Wordpress might look like this:

resources: wordpress_config: type: OS::Heat::SoftwareConfig::Chef properties: cookbook: http://www.mycompanycom/hot/chef/wordpress.zip role: wordpress

# input parameters that the chef role(s) need inputs: wp_admin_user: type: string mapping: wordpress/admin_user wp_admin_pw: type: string mapping: wordpress/admin_password db_endpoint_url: type: string mapping: wordpress/db_url

# various other input parameters …

# Have chef output the final wordpress url outputs:

wp_url:

type: string

From the OpenStack documentation at

https://wiki.openstack.org/wiki/Heat/Blueprints/hot-software-config-spec:

The resource type OS::Heat::SoftwareConfig::Chef indicates that this is a Chef-specific Software Config definition. The cookbook property points to the used Chef cookbook, and the role property points to the role to be set up via this Software Config. The inputs section contains the definition of input parameters that have to be passed to Chef for configuring the role. Input parameters are defined in terms of name and type. In addition, a mapping specifies to which role attribute the respective input parameters needs to be assigned (i.e. Chef-specific metadata).

If this seems confusing, don’t worry. This example is simply meant to show the developers behind OpenStack are aware of these tools, and that if you are familiar with them, there are a number of ways to tightly integrate them into your

deployment. Again, exactly how you choose to configure your servers and your application is entirely up to you. Your company and/or your operations team may have a lot to say on the subject, or the choice might be yours alone. What’s

important is to have a general understating of the options available and form a game plan.

With that in mind, let’s to go over two other important pieces of functionality that all of these configuration management solutions provide. First off, they offer

centralized management of servers. Once the client is installed, and the server has been registered into the master, you can use a web interface to do things like

search for a server, see what software is installed, or even push/schedule a patch for it (see Figure 6.5).

Figure 6.5

This configuration isn’t required though, and these tools can all be used in masterless mode where this central authority is entirely absent. There is a lot of crossover between what these centralized systems and what OpenStack/Horizon can offer, so it’s not unusual to use them in this masterless manner.

The other piece of functionality they all offer is the ability to execute arbitrary commands on remote servers. This is an aspect of the same mechanism that

allows the master servers to patch remote computers. Ansible in particular can be an indispensible tool when used for this purpose.

Unlike Puppet, Chef, and Salt (to some extent), Ansible doesn’t require the

installation of a specialized client to support remote command execution. It uses SSH and private/public keys to achieve a similar result. It is also easy to configure Ansible with a local file to push these commands to many servers at once (as

opposed to sequentially). This makes remote execution quick and easy from any computer with Ansible installed. A configuration file for Ansible looks like this:

[devservers]

[prodservers] prod01.cloud.mycompany.com prod02.cloud.mycompany.com prod03.cloud.mycompany.com [otherservers] server1.cloud.mycompany.com server2.cloud.mycompany.com

This file defines three groups of servers (devservers, prodservers, and

otherservers). Commands can be run on an individual box, a group, or all groups at once. You can also determine how many servers to run the command on

simultaneously. So if, for example, you want to update Git on all of your production servers at once you could run:

$ ansible prodservers -a "yum update -yq git" -f 3 -u myusername ––sudo ––ask-sudo-pass -i /myuser/ansible_hosts

Since Yum often requires sudo access, the ask-sudo-pass value has been invoked,

and -f 3 indicates that you want to run it on three servers at once. If there were 6

servers defined in the prodservers group, then it would run this in two separate

batches. This is often useful to avoid things like cache slamming or to avoid rebooting all of your servers at once, making your application temporarily unavailable.

Ansible is highly recommended as an easy way to execute remote commands, but this does not make it a shoe-in for the configuration solution for our demo

application. In fact, there is one drastically different option to consider.