On Habré, several times they wrote about the configuration management systems puppet and chef, but for some reason the pioneer of this topic is cfengine, deprived of attention, let's take that gap.
The first thing to note about cfengine is the declarative framework, not the imperative. We do not describe the detailed sequential steps to achieve the desired configuration, we describe the desired state of the system. For example, “make sure that all web servers with the name web. * Have the nginx package” or “make sure that the bckup.sh script was launched at the 5th hour of the day and * successfully * completed”. Cfengine uses the notion of “promise” (promice), besides cfengine will try to “restore” (repair) it periodically, and even after a successful recovery it will check the state (state) and restore it again and again to achieve convergence (convergent configuration). The advantage of this approach is that there is no need to know the current state in order to arrive at the desired. This is especially important if you have part of the nodes are not available at the time of adding new policies (policy), or vice versa, you are adding unconfigured nodes.
Hopefully enough background information, let's look at examples.
Installation is simple and does not require much time. For Debian:
cd /tmp wget http://cfengine.com/pub/gpg.key apt-key add gpg.key rm gpg.key echo "deb http://cfengine.com/pub/apt squeeze main" > \ /etc/apt/sources.list.d/cfengine-community.list apt-get update apt-get install cfengine-community
Now create a file containing one simple cfengine bundle and completely
base body which imports the standard library.
cat /var/cfengine/inputs/python_virtualenv.cf:
body common control { bundlesequence => { "python_virtualenv" }; inputs => { "cfengine_stdlib.cf", }; } bundle agent python_virtualenv { vars: "package_list" slist => { "virtualenvwrapper", "python-pip" }; "environments" slist => { "s1.example.com", "s2.example.com" }; packages: "${package_list}" package_policy => "add", package_method => generic; classes: "incorrect_$(environments)" not => fileexists("/tmp/$(environments)/bin/python") ; reports: linux:: "Virtual environment $(environments) is not installed correctly." ifvarclass => canonify("incorrect_$(environments)"); commands: linux:: "/usr/bin/virtualenv /tmp/$(environments) --no-site-packages" ifvarclass => canonify("incorrect_$(environments)"); }
We declare an agent type bundle and with the name python_virtualenv, as you can guess, I want to make sure that I have installed two independent python virtualenv, for example, they will be created in /tmp/s1.example.com and /tmp/s2.example.com, pre-promise variables in slist. Obviously, we need python, which we declare in the promise of the type packages. Notice that cfengine automatically iterates over the list, no cycles need to be written - we simply declare our intention. Further, we declare a class depending on whether there is a specific file or not. I must say, classes are not exactly a good name, it would be more appropriate to call contexts, and in general they are practically boolean - a class in cfengine, or there is or not! Next comes the promise of type report, in it we see the so-called hard class linux, hard classes are declared by cfengine itself and they include the type of operating system, IP, version of the distribution kit and many more that you can see by running
/ var / cfengine / bin / cf- agent -v . The promises in reports and commands will work only if the “incorrect _ $ (environments)” class is set (the canonify option is called, because the class may contain forbidden characters and the check may fail). We try to run:
/ var / cfengine / bin / cf-agent -K -f /var/cfengine/inputs/python_virtualenv.cfWe get:
Q: "...virtualenv /tmp": New python executable in /tmp/s1.example.com/bin/python Q: "...virtualenv /tmp": Installing distribute.................................................................................................................................................................................done. I: Last 2 quoted lines were generated by promiser "/usr/bin/virtualenv /tmp/s1.example.com --no-site-packages" Q: "...virtualenv /tmp": New python executable in /tmp/s2.example.com/bin/python Q: "...virtualenv /tmp": Installing distribute.................................................................................................................................................................................done. I: Last 2 quoted lines were generated by promiser "/usr/bin/virtualenv /tmp/s2.example.com --no-site-packages" R: Virtual environment s1.example.com is not installed correctly. R: Virtual environment s2.example.com is not installed correctly
We look in / tmp and make sure that our virtualenv are created.
Remove rm -rf /tmp/s2.example.com!
And run
/ var / cfengine / bin / cf-agent -K -f /var/cfengine/inputs/python_virtualenv.cfWe see:
Q: "...virtualenv /tmp": New python executable in /tmp/s2.example.com/bin/python Q: "...virtualenv /tmp": Installing distribute.................................................................................................................................................................................done. I: Last 2 quoted lines were generated by promiser "/usr/bin/virtualenv /tmp/s2.example.com --no-site-packages" R: Virtual environment s2.example.com is not installed correctly.
Cfengine recreated only remote virtualenv, which is what was expected.
Obviously, cfengine can work with both standalone and policy hub. Intrigued? You can start from here
http://cfengine.com/manuals/cf3-quickstart