Monday, May 2, 2016

[tutorial] a primer to cdist

cdist is tool for configuration management, similar to puppy and ansible with the big difference that it does not need an agent on the target machine but only password-less ssh access. The whole thing is based on simple shell scripts and thus needs nearly nothing. Only the control server has 1 dependency: python

start here: git clone https://github.com/ungleich/cdist.git

Basically you have a manifest and types as the 2 most important things. The manifest says what to execute where and can be a simple one liner up to a complex file (see sample file).
Types are the "what is there to do" and can be interdependent, e.g. there is a type called __package which installs packages and automatically uses the correct package manager depending on what distro it detects (via an explorer). Now this type can be used in your type if you need to install dependencies you simply run e.g.
for package in nginx php5 mysql
          do __package $package
done
Another important thing is dependencies. If you have to make sure certain steps need to be done before other steps e.g. build-essential needs to be installed before you can compile something, then you have to use "require". Example"
require="__package/build-essential" __postgres_database $user --owner $user
Pay attention to spaces when you use require! Read manual about that

Now a type directory can contain the following files:
  • manifest (optional)
  • singleton (optional)
  • explorer (optional)
  • gencode (optional) 
  • parameter (optional)
Types are stored below cdist/conf/type/. Their name should always be prefixed with two underscores (__) to prevent collisions with other executables in $PATH.
To implement a new type, create the directory cdist/conf/type/__NAME.
For more explanation of each see: http://www.nico.schottelius.org/software/cdist/man/latest/man7/cdist-type.html

Let's do an example:
We want to create a LEMP stack type:
we create new directory __LEMPstack

In the manifest we put:
#!/bin/sh
for package in nginx mysql-server php5-fpm php5-mysql
       __package $package
done
Now let us assume you want to change the nginx default port and have it reloaded. For that we can use the gencode-remote file, which executes after the other things.
We put the following:
echo "sed -i -e 's/80/8080/g' /etc/nginx/sites-enabled/default"
echo "service nginx reload"

Now to execute that whole thing you can simply put "__LEMPstack" in your manifest that is under /manifest/ (name doesn't matter, for a short one I usually just call it init) and run cdist like this: ./cdist config -v 192.128.100.100
Instead of IP you could also set any hostname if its defined in your manifest (see the sample file).
You will end up with an error about missing object_id. If you want to run types without object_id you need to create a "singleton" file in the type directory. Then it will work.

Best way to learn is to take a look at some of the types that cdist comes with.

No comments:

Post a Comment