Published on 29 February 2016 by

One thing about infrastructure technology: There are always new and interesting-looking tools being released that warrant investigation and, potentially, being deployed into your production environment. With Puppet already in place, trying out new technologies is generally made much easier by standing on the shoulders of others and using an existing module from the Forge. In this occasional series, I'm going to look at the state of Puppet integration with various recent technologies. If you have something in particular you’d like to see a post on, please leave a comment on this post.

What is Consul, and why should I care?

I'm going to start this series looking at Puppet and Consul. Consul is an open source tool for discovering other services on your network. It provides a simple API for registering services — for example, registering several instances of an application server — and then exposes that list via an API and via a built-in DNS server. You can also use Consul to store arbitrary key/value data, and have it automatically distributed across your data center.

Consul has many uses, but a few examples of the types of things you might do:

  • Let’s say you have a load balancer and you want to constantly add new web servers to the pool. How does the load balancer discover when new servers are added? Or existing ones removed? WIth Consul you can have new web servers register a service in Consul, and then the load balancer can watch for changes to that service and react accordingly.
  • Now let’s say your application requires a Redis backend. But you want your configuration to be portable between environments, so hard-coding things to point to a specific IP address won’t do. With Consul you point at an internal Consul DNS record, and have your Redis instances automatically register the right address with Consul.

The Consul module

The Consul module from Kyle Anderson (it's on the Puppet Approved list) is an excellent example of just how popular and useful Forge modules are. It’s been downloaded more than 45,000 times and has top marks from users.

The module provides several classes and types for installing and managing Consul. For instance, setting up a Consul server is as simple as this:

class { '::consul':
  config_hash => {
    'bootstrap_expect' => 1,
    'data_dir'         => '/opt/consul',
    'datacenter'       => 'east-aws',
    'log_level'        => 'INFO',
    'node_name'        => 'server',
    'server'           => true,
  }
}

Once you have a server up and running, you probably want to launch Consul agents on your other hosts, like so:

class { '::consul':
  config_hash => {
    'data_dir'   => '/opt/consul',
    'datacenter' => 'east-aws',
    'log_level'  => 'INFO',
    'node_name'  => 'agent',
    'retry_join' => ['172.16.0.1'],
  }
}

The module includes support for all the configuration options for Consul, the ability to set up the web interface, and a type for managing the built-in access control features.

Consul extras

Consul has a number of related applications that add additional features to the core Consul service — for example, Consul Template and Consul Alerts. Luckily for users interested in those applications, they both have modules available on the Forge too: gdhbashton/consul_template and jlondon/consul_alerts.

Integrating Consul with Puppet

Once you have Consul set up, you likely want to populate the service registry. The kyleAnderson/consul module mentioned above has a few resources to do just that from within Puppet. Here we’re using the consul::service defined type to register a Redis instance running on port 6379 with consul. You could imagine this snippet of Puppet code fitting alongside your service definition in your existing manifests.

::consul::service { 'redis':
  checks  => [
    {
      script   => '/usr/local/bin/check_redis.py',
      interval => '10s'
    }
  ],
  port    => 6379,
  tags    => ['master']
}

Once you have services registered in Consul you’ll likely want to make use of them. One simple use case might be watching Consul for changes in a particular service (for instance, adding more Redis instances on other nodes, or an existing service becoming unavailable) and triggering some action. For this, Consul supports watchers, and the Puppet module allows you to configure those in Puppet.

::consul::watch { 'my_watch':
  handler     => 'handler_path',
  passingonly => true,
  service     => 'serviceName',
  service_tag => 'serviceTagName',
  type        => 'service',
}

You might also want to use data from Consul directly in Puppet — for example, to ensure you have a monitoring check for each service registered in Consul. Puppet already has Hiera for introducing data from external sources into Puppet manifests, and luckily there is an excellent Hiera backend from Marc Cluet, lynxman/hiera_consul for just this purpose. Configuring the backend is simply a matter of providing the paths under which you want Hiera to query for information.

:backends:
  - consul

:consul:
  :host: 127.0.0.1
  :port: 8500
  :paths:
    - /v1/kv/configuration/%{fqdn}
    - /v1/kv/configuration/common
    - /v1/catalog/service
    - /v1/catalog/node

The module also features functions for formatting the data returned. For instance, the following code queries Consul via Hiera, and then returns a hash of all the IP addresses related to the rabbitmq service.

$consul_service_array = hiera('rabbitmq',[])
$mq_cluster_nodes = consul_info($consul_service_array, 'Address')

Some real-world examples

The above modules make it possible to use Consul and Puppet together, but that still leaves the questions of what to do and how best to do it. Luckily, the Puppet community has lots of answers here as well.

I gave a talk last year at Puppet Camp London titled Service Discovery and Configuration Management. You can look at the slides and video online. The talk covered some of the introductory material above, and also included a fully working demo of using Consul with Puppet Enterprise to automatically add nodes to, and remove nodes from, a load balancer. It's done by having Consul run Puppet on the load balancer node whenever the service registry changes.

We had another excellent Puppet Camp talk in London from Marc Cluet (who wrote the Hiera backend mentioned above). it’s definitely worth checking out the slides for his talk, Service Discovery and Puppet.

Community member Lee Briggs has recently worked on using Consul to allow nodes to automatically discover new Puppet masters, and he's also set up a health check of the Puppet server in Consul.

Conclusions

Hopefully the above provides a good starting point for anyone looking to use Consul alongside Puppet. Using the above-mentioned modules greatly lowers the barrier to to rolling out a tool like Consul across your estate, and keeping it running and correctly configured. Thanks to all the awesome community members who have contributed to such a strong set of tools and examples for a relatively recent tool like Consul.

As mentioned at the start of this post, do let us know in the comments if you’d like to see other technologies covered in this way, and which technologies you’re particularly interested in. If you have any other Consul and Puppet tips as well, please leave those in comments too.

Learn more

Gareth has written a number of recent posts on using different technologies with Puppet. Here are some more to check out:

Share via:
Tagged:

Add new comment

The content of this field is kept private and will not be shown publicly.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.