wk8 / cookbook-cloudflare

A Chef cookbook to register your servers with Cloudflare's DNS & threat control services
The Unlicense
7 stars 12 forks source link

Description

This Chef! cookbook defines one LWRP that you can easily use in your own cookbook to create and delete Cloudflare DNS records and manage your threat control services.

It is built on top of B4k3r's Ruby wrapper for the Cloudflare API. (https://github.com/B4k3r/cloudflare)

Requirements

Requires Chef-client version 11.x or later.

Attributes

To be able to use the clouflare_dns_record resource, you must define two nodes attributes: ['cloudflare']['credentials']['email'] and ['cloudflare']['credentials']['api_key'].

I strongly recommend storing your Cloudflare credentials in an encrypted data bag, and then decrypting them in your own cookbook.

There also are a number of optional node attributes:

Those attributes come in especially handy if you have a number of servers and get throttled by Cloudflare's API limits.

A couple of threat-control-related attributes are explained in the "threat_control Resource" section below.

Usage

To use the clouflare_dns_record resource in your own cookbook, simply tell Chef! that your cookbook depends on this one, by adding depends 'cloudflare' in your metadata.rb file.

clouflare_dns_record Resource

This resource defines the following attributes (they're all Strings unless otherwise specified):

For instance, the following code in your cookbook's recipe would create an A DNS record server_name.example.com pointing to 1.2.3.4 with an automatic TTL:

cloudflare_dns_record 'server_name' do
    zone 'example.com'
    content '1.2.3.4'
end

The clouflare_dns_record resource defines two different actions: :create and :delete (pretty self-explanatory); :create is the default one.

Another example:

cloudflare_dns_record 'resource_name' do
    zone 'example.com'
    record_name 'server_name'
    action :delete
end

would delete the server_name.example.com record from your Cloudflare account.

threat_control Resource

CloudFlare's threat control can be used to whitelist or blacklist IPs hitting your domains going through their network. cf. CloudFlare FAQ - How do I block or trust visitors in Threat Control?

Attribute:

Actions: :whitelist, :blacklist, :remove_ip Should be self-explanatory, the latter one being used to remove a white/blacklisted IP from their respective list. Note that the default action is :nothing!

Examples:

cloudflare_threat_control 'whitelist_current_server' do
  action :whitelist
end

cloudflare_threat_control 'shall_we_trust_this?' do
  ip '208.73.210.203'
  action :blacklist
end

A word on how this LWRP works: we don't want to have Chef hit Cloudflare's API every time it runs, for Cloudflare's API usage thresholds are pretty low. The thing is, unlike DNS records (for which we can query a DNS server instead of the API), there's no way to double-check the current status without making API calls. To get around this, this LWRP caches the current status (and trusts that the cached information is valid) for a while, which is reasonable if your Chef recipe is the only way this should ever be modified in your setup. The cache's validity is controlled by the ['cloudflare']['threat_control']['cache_duration'] node attribute, which defaults to 1 day. Note this attribute expects this duration in days, but does accept floats (so you can set it to 1.0 / 24.0 to reduce it to one hour).

If you happen to have few enough servers that you don't care about Cloudflare's API usage thresholds, or if you really want your recipe to make calls to the API at every run, you can set the ['cloudflare']['threat_control']['disable_cache'] node attribute to true (defaults to false).

A caveat worth noting with this resource is that Cloudflare's API as of today (08/18/14) offers no way to check the current status of a given IP w.r.t threat control settings, nor does it give any information when making a call to set an IP's status regarding its previous status. As a result, this resource will be marked as updated whenever an API call is made, even if the status wasn't actually changed.

Note that you can't use the cache with Chef solo, as there's nowhere to save the information to. Chef-zero will do nicely though if you don't have a Chef server around.

Example recipe

You can have a look at the cloudflare::example recipe for examples on how to use the DNS-related LWRPs.

You can also test my cookbook with Vagrant (see the 'Vagrant' section below).

Vagrant

You can test this cookbook locally, provided you have a bunch of free software installed, namely Vagrant, Berkshelf, VirtualBox, and a couple of Vagrant plugins: Vagrant-Berkshelf and Vagrant-Omnibus.

You also need to define 3 environment variables to be able to use my Vagrantfile:

You can do so by typing e.g. export CLOUDFLARE_EMAIL='me@example.com' and so on in your shell.

Be aware that the example recipe will then proceed to create a few DNS records on that DNS zone with your credentials, so use with caution! That being said, all said records will start with 'cl-cb-test-' so they have little chance of clonflicting with exisiting records on your account. Also, it does white-black list a couple of private IP addresses.

You can also easily clean up the test records created that way by running CLOUDFLARE_CLEANUP=1 vagrant provision.

Then playing with this cookbook should be as easy as running bundle install --path vendor/bundle && vagrant up!

Note that if you want to test/do stuff on the caching mechanism for the threat control LWRP, you'll need to use Chef-zero. For now this project uses the Vagrant-Chef-Zero plugin, but we'll soon migrate to Test Kitchen. To use the Chef-Zero plugin, simply install it, the Vagrantfile will pick it up automatically.

Contributing & Feedback

As always, I appreciate bug reports, suggestions, pull requests, feedback... Feel free to reach me at wk8.github@gmail.com

Changes

Contributors