Syntax highlighting in "Learning CFEngine 3"

The electronic versions of the book contain full syntax highlighting and other useful features. I'm biased of course, but I think it is both functional and beautiful. Here's a sample from Chapter 4:


The syntax highlighting in my opinion greatly helps in reading the code. Additionally, each one of those numbered callouts in the code are in-document links that take you to the paragraph where that part of the code is described. Conversely, the callouts in the text take you back to the corresponding line in the code. And finally, most CFEngine keywords and concepts are links to the corresponding description in the CFEngine Reference Manual. In the PDF, clicking on that blue "files:" in the last paragraph will take you to

CFEngine community event: March 8th, 2012

I am visiting the Bay Area this week, and we took the opportunity to organize a CFEngine community event on Thursday, March 8th, at 6:30 PM. Come by, meet the CFEngine team, hear about some of the exciting things we are working on, and give us your feedback for the future.

Hope to see you there! If you plan to attend please don't forget to register.

Book status: production

Some people have asked me what the status of the book is, so I thought I would post it here. The book is currently in the "production stage", which means that the draft has been finalized content-wise, and is now being prepared for publication by O'Reilly. They have a specialized group of people for this, who work on preparing nice final versions of the figures, making sure the layout of the book is correct, and doing a few thorough proofreading and editing passes.

This means that it's now really close to publication. I cannot make any promises about the specific date, but it should be before the end of March.

Thank you for your interest!

Searching CFEngine documentation

The CFEngine Reference Manual is extremely useful, and is the ultimate guide to everything about CFEngine. However, it is not always the easiest to find what you are looking for.

To help in this respect, I have created a cross-referenced index of all the section headings in the manual. You can search it using the second search box on the right of any page of this site. For example, try searching for "ifvarclass", and you will be redirected to the section of the manual that described that attribute. If your search term matches more than one section (for example, try searching for "root"), you will be shown a disambiguation page where you can select which one you want.

You can also search the index directly by going to, replacing "keyword" with your search term. Without a search term (, it will redirect you to the top of the manual. Here are a few examples to get you started:

In the electronic versions of the book, all CFEngine keywords in the text will be linked to this index, to provide you easy access to the reference documentation about that concept.

But the real power, in my opinion, comes from using these links as browser "search keywords". Most modern browsers allow you to define search keywords or search engines. If you define a keyword whose search URL is as shown above (using whatever mechanism necessary to put the search term in the place of "keyword", then you will be able to easily search the CFEngine docs. For example, using Safari Omnibar, I have defined a new "search provider" as follows:


So now I can simply type "cf keyword" in my Safari URL bar and it will do a search for that keyword.



A couple of days ago I finished writing all the material that was planned for the book, so it is now content-complete! I am now going through all the comments that came back from the tech reviewers, and from many readers that sent me feedback while reading the early release. After that it goes to the production department at O'Reilly for putting it in its final form, and then it will be ready for publication!

Thank you to everyone who has given me feedback and encouragement so far!

Code examples for "Learning CFEngine 3" now available

I'm happy to announce that the code examples from Learning CFEngine 3 are now available for browsing and download at You can view or download individual files, and also the whole collection. You can also get them from the GitHub repository.

These examples are extracted automatically from the source files for the book, and as such reflect exactly the current state of what you will find in it. This also means, of course, that as the book evolves you will see changes in the files.

As usual, please feel free to play with them, and let me know if you find anything broken.

CFEngine 3 training on January 25-27th, 2012

Quick plug: if you are in the Bay Area and are interested in getting some hands-on introduction to CFEngine 3, please make sure to check out this training session:

Automating System Administration using CFEngine 3
Presented by Mark Burgess & Aleksey Tsalolikhin
Date: January 25-27
Location: Palo Alto, CA
Price: $1950 per person (group discount negotiable)
Registration & Agenda:
Mark is the original author of CFEngine and the ultimate CFEngine authority in the world. He will be joined by Aleksey, one of the most experienced CFEngine trainers around. Both are excellent teachers, so the course is guaranteed to be excellent.

cf-cmd: A command-line tool for running CFEngine snippets

While writing this book, I've had to run hundreds of little CFEngine snippets to run tests, develop examples, verify functionality, or get a solid idea of what some constructs did. After building the typical "test bundle" scaffolding in an editor for the hundredth time, I decided to do something about it. The result is the cf-cmd command. I will let it speak for itself:

$ cf-cmd help
cf-cmd v1.0 - Diego Zamboni>

cf-cmd is a tool that allows you to run small CFEngine snippets quickly,
by automatically wrapping them around a standard "test" bundle.

The CFEngine Standard Library is automatically included.

The following inputs are understood by this tool:

help     Print this message
list     Print current policy
clear    Clear current policy
go|run   Execute current policy using cf-agent
type:    Switch to the given promise type
         (classes:, commands:, databases:, environments:, files:, interfaces:,
         methods:, outputs:, packages:, processes:, reports:, services:,
         storage:, vars:)
           The current promise type is shown in the prompt.

All other lines are added literally to the current promise type.

Commands can be abbreviated to any part of their name (for example,
"r" or "ru" for "run").

You can add lines to any of the standard promise types inside the test
bundle by switching to the appropriate promise type first.

The default promise type is "reports:", to make it easier to quickly print
the value of expressions.

You can give the inputs also on the command line, they are interpreted
in exactly the same way (make sure to quote things correctly).

  cf-cmd '"Flavor: $(sys.flavor)";' list run
  cf-cmd '"var1 = $(var1)";' vars: '"var1" string => "test";' l r
  cf-cmd h

You should try out those examples at the end to see what they do. An example interactive session looks like this (I have bolded the inputs to make them easier to see):

$ cf-cmd 
reports: > "this is a test";
reports: > list
body common control {
   inputs => { "/var/cfengine/inputs/" };
   bundlesequence => { "test" };

bundle agent test
  "this is a test";
reports: > run
-> Running policy with 'cf-agent -KI -f ./'
R: this is a test
reports: > clear
reports: > l    (abbreviation of "list")
body common control {
   inputs => { "/var/cfengine/inputs/" };
   bundlesequence => { "test" };

bundle agent test
reports: > files: 
-> Switching to files: promise type.
files: > "/tmp/test"
files: >   create => "true",
files: >   classes => if_repaired("done");
files: > reports: 
-> Switching to reports: promise type.
reports: > done::
reports: > "Success";
reports: > l
body common control {
   inputs => { "/var/cfengine/inputs/" };
   bundlesequence => { "test" };

bundle agent test
    create => "true",
    classes => if_repaired("done");
reports: > run
-> Running policy with 'cf-agent -KI -f ./'
 -> Created file /tmp/test, mode = 600
R: Success
reports: > 

The interactive prompt supports editing and completion of all commands and promise types - press Tab to view available completions.

You can download the script {% gist 1525722 %}.

Just put it somewhere in your path. If needed, modify the location of the file on your system (by default it looks for it under /var/cfengine/inputs/). You need Ruby installed (I tested with version 1.9.3).

If you find it useful, or if you find any problems or have any suggestions, please let me know. I'd be happy to hear from you.

Migrating from CFEngine 2 to CFEngine 3

When designing the CFEngine 3 language, its author Mark Burgess decided a complete overhaul was needed. This decision freed CFEngine 3 from any backwards-compatibility constraints, resulting in a completely new language that is much more flexible, extensible, powerful and expressive.

Unfortunately, this means that migrating from CFEngine 2 to CFEngine 3 is not automated, and requires a certain level of hand-tweaking. One of the frequent comments I heard at LISA'11 was from people who are currently using CFEngine 2, and have been hesitant of migrating to CFEngine 3 because they are not sure how to proceed, and are afraid of the amount of work it will involve (and also, "if it ain't broke, don't fix it"). However, upgrading to CFEngine 3 is a tremendous opportunity for improving the state of the infrastructure, and many of its features can help in making the policies more understandable, flexible and scalable. It is partly for this reason that there is no automatic conversion tool from CF2 to CF3 policy format. Doing it by hand allows close examination of the policies, their intended purpose, and provides an opportunity to improve them in the process.

To help, there is the Upgrading from CFEngine 2 to 3 guide (PDF). It contains some general suggestions, different ways in which the conversion can be handled, and a "Translation Codebook" that helps in converting from CFEngine 2 constructs to their equivalents in CFEngine 3.

Additionally, CFEngine AS is holding a webinar called Migrating from CFEngine 2 to CFEngine 3 on January 25th, 2012. It will be imparted by Joe Netzel from CFEngine. Joe is a great speaker and teacher, and knows CFEngine in and out, so the webinar is assured to be full of good content, and a fantastic learning opportunity. It's free, so why not sign up?

Update: the webinar has passed, but you can view the recording and a related presentation. goes live

I'm happy to announce, the accompanying website for my book Learning CFEngine 3, currently in Early Release from O'Reilly. 

In this website you will find:
  • General information about the book.
  • A discussion forum for any type of questions, feedback or suggestions about the book.
  • Downloadable code examples from the book, plus (over time) many other new examples.
  • List of Errata, and access to the Errata system at O'Reilly.
  • A blog devoted to the book and to CFEngine.
The site is mostly empty at the moment (the blog, the forum and the errata page are live, I encourage you to participate, particularly if you have purchased the Early Release version of the book and want to provide any sort of feedback), but content will grow over time.

Thank you for visiting, and please let me know what you think!

Best regards,