CFEngine

 

 

CFEngine On CentOS

CFEngine is a policy manager that ensures each machine it is installed upon meets the policy system’s create for different groupings of machines. Can be configured to monitor, install, check, update, remove, create just about anything

Links

Install CFEngine
Getting Started
CFEngine Reference Guide

Warning

CFEngine is a very powerful tool. You can make it do ANYTHING to a large number of machines. Proceed with caution, remember machines are stupid they will do EXACTLY what you tell them to do. Treat this tool with respect, start new promises with small groups before expanding cluster wide.

myPromises

A sysadmin must create promises that define what a machine should be doing, what it should be running, what it should have installed, etc. I am just showing snippets of these as these are quite long as we have many promises, mostly for ensuring all of our services are up 24/7 and if they do fail start them with 5 minutes. Systems receive emails each time a promise does not meet the expected result(i.e. repeated failures to start a daemon, disk running out of room)

the two most important ones are z01PromiseSetup.cf, which tells the system which promises to keep

bundle common z01_promise_setup
{
vars:
    "bundles" slist     => {
                           
                                "w01_check_mysql",
                                "w01_check_httpd",
                                "w01_check_zedx_jobtoold",
                                "w01_check_hsflowd",
                                "w01_check_mesos_master",
};
   "promise_files" slist
                        => {
                       
                                "myPromises/w01checkmysql.cf",
                                "myPromises/w01checkhttpd.cf",
                                "myPromises/w01checkzedxjobtoold.cf",
                                "myPromises/w01checkhsflowd.cf",
                                "myPromises/w01checkmesosmaster.cf",
};

and z02GlobalClasses.cf, which tells CFEngine which machines fall into which class, machines can be in many classes or excluded from a class should the match a regex.

bundle common z02_global_classes
{

classes:

"mesosslaves" or => {
                        regcmp("appa01","${sys.uqhost}"),
                        regcmp("appa02","${sys.uqhost}"),
                        regcmp("appa03","${sys.uqhost}"),
                        regcmp("appa04","${sys.uqhost}"),

        };

        "app" or => {
                        regcmp("app[0-9]{3}","${sys.uqhost}"),
                        regcmp("appb02","${sys.uqhost}"),
        };

        "web" or => {
                        regcmp("web[a-z]{3}[0-9]{3}",
                        "${sys.uqhost}"),regcmp("funame",
                        "${sys.uqhost}"),regcmp("who",
                        "${sys.uqhost}"),
                        regcmp("idk","${sys.uqhost}"),
                        regcmp("fakename","${sys.uqhost}"),

}

Promise Format

Below is the format of a promise to ensure all machines in the base group that are not centos_5 or Centos_4 machines have sssd running.

w01checksssd.cf

bundle agent w01_check_sssd
{
methods:
# tells it which group that can run this chech_sssd
        base.!centos_5.!dhcp.!centos_4::
        "w01checksssd" usebundle => check_sssd;

}

bundle agent check_sssd
{

vars:
        "grep_name" slist => { "sssd" }; # similar to ps fax | grep sssd
        "service" slist => { "sssd" }; # name of executable in /etc/init.d
        "init_scripts_path" string => "/etc/init.d";

processes:

        "$(grep_name)"
        comment => "Check if the process for '$(service)'",
        restart_class => "restart_$(service)";

commands:

        "${init_scripts_path}/${service} start"
        comment => "Restarting the service",
        ifvarclass => "restart_${service}";

reports:
        done::
         "Heads up - the $(this.promise_filename) promise restarted $(service) on $(sys.fqhost). "      ;

        !done::
        "$(service) is running on $(sys.fqhost).";

}

myTemplates

A user can have files/packages/libraries, etc that need distributed to each machine in the policy group.
first copy the file to mastercf:/var/cfengine/masterfile/myTemplates
from there I have it sub divided by the same groupings as in z02GlobalClasses.cf
rename it so it ends in a .txt .conf .cf or cfengine will ignore it.

then make a promise to distribute, example b21ManageConfig.cf to copy the ssh message of the day to each machine.

bundle agent b21_manage_config
{

methods:
#all machine in the zedxinc domain are in "base"
    base::                                              # <1>
    "b21manageconf" usebundle
                        => b21_run ;

}

bundle agent b21_run
{

vars:
# notice the source dir is /var/cfengine/inputs and NOT /var/cfengine/masterfiles. When cfengine distributes policies to each machine that is bootstrapped to the master, the cf-agent can only execute local files in /var/cfengine/inputs.
    "source_dir" string
                        => "/var/cfengine/inputs/myTemplates" ;   # <2>

    "source_file" string
                        => "$(source_dir)/motd.txt" ;


files:
#creates file and assigns permissions
    "/tmp/motd"
    perms               => mog("640","root","root"),
    create              => "true",
    edit_defaults       => empty,
    edit_line           => expand_template("$(source_file)") ;    # <3>

}

  1. remember to always update z01PromiseSetup.cf each time you add a new promise or it will not be kept.

Commands

Checks consistency of policy file to ensure nothing is incorrect syntax wise. If there is a syntax issue ALL machines start complaining.

 $ cf-agent -f /var/cfengine/masterfiles/promises.cf 

Updates available policies for slave machines. copies to /var/cfengine/inputs

 $ cf-agent -IKf /var/cfengine/masterfiles/update.cf 

Machines should check in every five minutes but if you are testing sometimes this is too slow.

 

Pull the latest promise update from the server on the agent machine:

 $ cf-agent -IKf /var/cfengine/inputs/update.cf

Immediately execute promises:

 $ cf-agent -IKf /var/cfengine/inputs/promises.cf

Show how much of each promise is able to be kept on the agent machine

 $ cf-agent -vn

Bootstrap/Install

To install the agents on slave machines with cfengine’s install script.

 $ wget -O- https://s3.amazonaws.com/cfengine.packages/quick-install-cfengine-community.sh | sudo bash
 $ cf-agent --bootstap 10.0.0.[CF]

For Private Networks

or for any local install that you wish to not go out to the internet to get the latest version for your servers

 $ rpm -Uvh http://rpm.example.com/ZedX/7/cfengine-community-3.8.1-1.x86_64.rpm
 $ cf-agent --bootstap 10.0.0.[CF]

The cfengine-community package is practically OS version agnostic and will install on CentOS 4,5,6, and 7 without any dependencies.