Recently we had a Fireside Chat with long-time contributor and CFEngine Champion Bas Van der Vlies. During that talk he mentioned a Build module he developed: promise-type-docker-compose.
For this month’s Module Monday post I thought I would take this promise type for a spin alongside the Docker Compose Quickstart tutorial.
Setup For this blog I brought up a libvirt vagrant VM with Debian 12 and installed the latest LTS (3.24.0) with cf-remote. To install docker I follow the instructions at Install Docker Engine. I was using Debian 12 “bookworm” and found that the default packages docker.io and docker-compose are rather old and were not compatible with the promise-type-docker-compose module. Additionally, the module relies on the jq utility, so I install that as well. I may write policy some time to take care of these dependencies but especially the Docker Engine install involves quite a few steps so will leave that for another time.
Over three years ago we introduced git and systemd custom propmise types.
While these are quite functional I recently needed to manage a git repository that was private and so needed a way to authenticate to a git server, in this case gitlab.
Gitlab has project access tokens but we didn’t directly support any sort of authentication attributes on the promise type.
I ran across git credential as a way to provide authentication and thought it was a good fit.
I promised more Build modules in my previous monthly Monday module blog post: package-method-winget.
And here they are: windows-capability and windows-optional-feature.
Inventory Both of these modules use similar usage details to control whether to inventory and to promise the state for specific capabilities and optional features.
By default inventory is taken in the form of a classic array which ends up in the Mission Portal as a comma separated list:
OpenSSH.Server~~~~0.0.1.0:Installed, OpenSSH.Client~~~~0.0.1.0:Installed, etc. To disable this inventory, define the class disable_windows_capability_inventory or disable_windows_optional_feature_inventory in the data namespace. The data namespace is the default if you use Host specific data or Group data. If you want to set these in augments you will need to specify the namespace explicitly like this:
As a developer and user of CFEngine I want to use policy to manage the software on my systems so that I can switch operating systems, distributions, computers and have all my normal tools available wherever I go.
Towards this end I searched for a Windows package manager and found one in winget. I showed a prototype in Agent Is In - Episode 37 - Windows package management as well as refined the whole process in Agent Is In - Episode 40 - Windows module workshop.
The rather serious recent OpenSSH vulnerability CVE-2024-6387 could affect as many as 14 million server instances exposed on the internet. Let’s make it easy to examine your infrastructure and see if you need to do any upgrades or mitigations.
On the back of my CFEngine T-shirt it says:
Know more, React faster When I have a problem to solve in CFEngine I look for an easy and correct solution. CFEngine Build is a good first place to look. Two modules stand out as possibly useful;
For security reasons, you generally want to uninstall talk, samba, and apache2 in your infrastructure. However, on your webservers, which have the webserver CFEngine class defined, you might want Apache to be installed. With the conditional-installer module, you can put talk,samba,apache2 in the list of packages to uninstall. And in the list of packages to install, you can put apache2 with the condition webserver. Hence, the module will install apache2 on your webservers and uninstall it everywhere else. talk and samba, on the other hand, will be uninstalled everywhere. As always with CFEngine, if the state is already correct - i.e., packages that should be installed are already installed and packages that should not be installed are not installed - no actions will be performed.
Whether you are migrating from Ansible to CFEngine to gain some of the benefits of scale or autonomy or just need some functionality in an Ansible module, the ansible promise type can be a great tool to utilize.
It also provides a compelling alternative to ansible-pull and works around some of the caveats included with that strategy. CFEngine has battle-tested features needed for the pull architecture:
cf-execd handles scheduling periodic runs as ansible-pull suggests using cron cf-agent handles locking to avoid concurrent runs of the same playbooks A tiny Ansible project example Taking some first-step tips from 5 ways to harden a new system with Ansible let’s make a sample playbook project which patches Linux systems.
Two modules are available for this task: allow-all-hosts and allow-hosts.
The first module, allow-all-hosts, configures the most open situation which is to accept hosts from anywhere. This is only recommended in network restricted environments such as a local machine’s virtual machine network or other such closed down situations.
The second module, allow-hosts, uses cfbs module input to let you decide which hosts (specified by IP addresses and subnets) are allowed to connect to your hub, authenticate, fetch policy, etc. This is by far the more common scenario.
Security Technical Implementation Guides (STIGs) are an excellent body of knowledge to leverage in securing your infrastructure. With the stig-rhel-7 module you can easily add inventory and remediation policy for RHEL 7 with CFEngine. Do note that as of March 2024 this module does not provide comprehensive coverage but rather an initial 10 findings are implemented.
Setup To start I installed CFEngine Enterprise on a local virtual machine, logged in and started a new Build project with the stig-rhel-7 module added and configured to enforce (as opposed to only warn).
For CFEngine we manage several public and private repositories of code in GitHub for our Open Source and Enterprise products. In order to ensure quality we run many checks on the code both with nightly builds as well as on each pull request. We use a Jenkins server for nightlies which also includes more extensive deployment tests on all of the platforms we support. Previously we had used Travis for many of these checks but that system started to show its age and limitations.