Target Mode with Chef Server and Chef Automate

Target Mode with Chef Server and Chef Automate

It is not sufficient to provision remote devices via Target Mode but we also want an overview of node attributes, run history and changed resources.

In this post we have a look at how to connect agentless resources with central servers to give us the much-needed visibility.

After our quick run down of the new Chef Target Mode, we know how to use it with a local workstation only, but have no connection to Chef Server/Automate, which would be a major benefit to most environments.

The Chef Runner

Currently, Chef does not include a way to schedule Chef runs in target mode on itself. The pattern we use for now is not unlike the way Ansible works as well: a workstation to schedule and run all our tasks… I mean runlists.

For each device you want to remotely manage, you need to create a new node in Chef - for example inside the Chef Server itself. You should safely store the private key of that new device, because we will need it lateron. You might as well set a runlist for that node, if you already have uploaded a Target Mode-compatible cookbook to your server.

Add Devices

First, we will add the client credentials to our system-wide /etc/chef/credentials file with its nodename being the section heading. If you don’t know how that file is structured, check the first post in the Target Mode series.

To authenticate against the server, we then add the private key of the new device under /etc/chef/nodename/client.pem, so the Chef client can easily find it.

And, of course, we might configure some things to reach our Chef server (or switch backend protocols) in our /etc/chef/client.rb. Just specifying the chef_server_url property might be enough, though.

Set Schedule

Without a Target Mode runner inside the Chef server we are stuck with good old cron jobs. Runs of your Target nodes can be scheduled easy enough with a file in /etc/cron.d/:

cat > /etc/cron.d/nodename.cron <<EOF
PATH="/opt/chefdk/bin:/opt/chefdk/embedded/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
GEM_ROOT="/opt/chefdk/embedded/lib/ruby/gems/2.6.0"

0,30 * * * * * chef-runner /usr/bin/chef-client -t nodename
EOF

If you want to randomly offset the runs, like with the chef-client splay attribute, you might either use the RANDOM_DELAY variable (if your cron implementation features it) or have a random offset command like sleep $(numrandom 0..30)m (from ubuntu’s num-utils package) as a prefix to your command.

Afterwards, you will see your node pop up in Chef Server/Chef Automate just like a regular node.

Missing Features

As already stated, most resources do not yet have target mode implemented. In addition, there still is no “Remote OHAI” for getting more than basic platform data via Train. That feature is on Chef’s roadmap though, so it should not be too long until it lands. Until then, you won’t even see a Chef Client version in your node attributes.

Similar Posts You Might Enjoy

Target Mode with Serial Devices

Target Mode with Serial Devices Usually, you will work with SSH or WinRM to connect to remote nodes and configure them. Those standard protocols bring along all the perks of a modern network connection: Encryption, Authentication, File transfers, etc But what if you have a device without network connectivity? - by Thomas Heinen

Custom Resource Diffs in Chef

Custom Resource Diffs in Chef If you are writing custom resources regularly, you might have been annoyed by a general “diff” functionality in Chef. In this post we will work on some snippets to make this possible - by Thomas Heinen

Writing Chef Target Mode Resources

Writing Chef Target Mode Resources After my previous blog posts, you might be tempted to write your own Chef custom resources which are compatible with Target Mode. Luckily, this is very easy - so this will be a short one. - by Thomas Heinen