Problem:  How to determine machine role from the hostname using Cfengine?

Data:  My server hostnames contain location code, department code,
type (web/db/etc.) and environment (stage/prod/dev).

For example:  "lax-it-web01-prod01".
Location: Los Angeles
Department: IT
Primary role: Web (first server)
Environment: Production (first production environment)

This model falls short when roles move from host to host, or additional
roles are added to to an existing server.

I don't have a host inventory database in my current environment.  How to
document which machine does what?  Preferably in a way native to Cfengine.

Solution 0.    Setting classes based on hostnames is elementary functionality
of Cfengine.    So let's set a role class based on the hostname:


    # set a "webserver" class if hostname is lax-it-web01-prod01
    classes:   lax-it-web01-prod01::    "webserver";

Error!  "Irreconcilable constraints in classes for webserver (broken promise)".

I don't know what irreconcilable constraints are, in fact, there are
no constraints
here besides the class. Mark, is there something semantically wrong with the
shorter version?  It embodies my intention with nothing extra added.


So then I added:

    # set a "webserver" class if hostname is lax-it-web01-prod01
    classes:   lax-it-web01-prod01::    "webserver"  expression => "any";

and that worked, but now I've got "noise" in my config due to the added text.

Is it possible to do without the mandatory explicit constraint, please?


Let's continue with this example:

Let me put my "who does what" config data in the Cfengine config:

    classes:   lax-it-web01-prod01::    "webserver"  expression => "any";
    classes:   lax-it-web01-prod01::    "nagios"  expression => "any";
    classes:   lax-it-web02-prod01::    "webserver"  expression => "any";
    classes:   lax-it-db01-prod01::      "postgres"  expression => "any";
    classes:   lax-it-db01-prod01::      "zenoss"  expression => "any";

If I want to do something on all nagios servers, I use the nagios:: class.
If I want to identify all the roles on lax-it-web01-prod01 (for knowledge
management),  I would run a shell command like:

    grep '^classes:   lax-it-web01-prod01::' who_does_what.cf | awk '{print $3}'


Comments?


Alternatives - store the config data OUTSIDE Cfengine:

1. My current method, with Cfengine 2, is to seed the role name into
the hostname
line in /etc/hosts -- this way it'll be set as a hard class when
cfengine starts.

For example, let's say the name is "lax-it-web01-prod01".  /etc/hosts
would read:

xxx.xxx.xxx.xxx   lax-it-web01-prod01 webserver nagios

"webserver" and "nagios" are the roles.

When I bring up a new instance, I have to edit /etc/hosts to add the
role, and then
Cfengine takes care of the rest of the configuration (based on the role).


2. Make a text file with hostnames and roles in them, and set up
cfengine classes
by running grep and parsing the output with regex.


3.  Set up a database: make a table of hostnames and whether each host has
(yes or no) each of all the possible roles.  Read it from inside
cfengine with a
command-line database client and set up classes based on regex parsing
of the output.


4. Put an /etc/roles file on each machine, and put roles into that
file, one role per line,
plain text, when roles are added to the server.  Or make an
/etc/roles/ directory, and
touch /etc/roles/webserver, /etc/roles/nagios, etc.

I am inclined to go with option 0, native to Cfengine, I just don't
like the noise of
'expression => "any";'  Could we please get rid of it?

Best,
-at
_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to