How to make snaps and configuration management tools work together

by Igor Ljubuncic on 1 October 2020

In environments with large numbers of client machines, configuration management tools are often used to simplify and standardize the target state of each host in a seamless, automated and consistent manner. Software like CFEngine, Chef, Ansible, and others offer a high degree of granular control over software packaging and system configurations.

You may wonder how snaps fit into this story. Since snaps come with automatic updates, with their own cadence and automation, at a first glance, it may appear there is potential for conflict as the two distinct mechanisms compete to maintain and align the system software state. However, this does not have to be. Far from it. In this article, we want to show you how to create a well-orchestrated environment, without any overlaps or conflicts between snaps and configuration management tools.

Snap update management

The snapd service will check for snap updates four times a day by default, and refresh any snap that has updates available in the Snap Store. But this default cadence can be changed. We have discussed the different methods by which you can set or defer snaps updates. The refresh hold functionality allows you to postpone snap updates for up to 60 days.

sudo snap set system refresh.hold=2020-10-01T13:00:00+01:00
sudo snap get system refresh.hold
2020-10-01T13:00:00+01:00

On the other hand, typically, configuration management tools run on a frequent basis, sometimes as little as one minute apart between two subsequent runs, but generally once an hour or so. This means that if you defer snap updates to a frequency that is lower than the configuration management runs schedule, you can fully control when your snaps update.

Snaps and configuration management combined

For example, you have 100 client machines that have the snap kubelet installed. You could then:

  • Set the refresh.hold value to 60 days on the client machines.
  • Integrate the snapd functionality into the configuration management tools. At the very least, the tools would simply execute the relevant snap command(s) as part of their own scheduled run.

    snap refresh kubelet
  • Perform a bi-weekly snap refresh check on a small group of hosts (say 10). This could be your pilot group of systems that are not used for critical tasks, but are instead used to validate the installation of new software packages and/or patches (not exclusive to snaps).
  • Once the snap is refreshed (provided there are updates) on each client in the pilot group, you could let these systems run for say 7 days and perform additional sanity and health checks, to make sure there are no regressions or problems (including potentially application logic bugs). The testing could be automated or manual or both.
  • Once you are satisfied the snap refresh works as intended, you could roll the updates gradually to additional hosts, say 20 hosts/day, until the entire pool of systems has been updated.
  • Change the refresh.hold value to a new future date.
  • Repeat the process.

The values in the example above are completely arbitrary.

Existing integrations – Puppet, Chef, Ansible

You will be pleased to hear that snap integration is already available for various configuration management tools, including official and community contributions. For instance, for Puppet, you can use the snapd module from Puppet Forge to manage snaps. Once the module is installed and configured, a sample usage would then be:

package { ['phpstorm', 'atom']:
  ensure   => latest,
  provider => snap,
}

package { 'spotify':
  ensure   => purged,
  provider => snap,
}

You can check more details on what the package resource does in the official documentation, including the value of the ensure property. For instance, in this case, ensure => latest allows you to install the latest version of specified package(s), without having to manually specify the version string. Similarly, you can also remove packages.

Similarly, Chef has the snap_package resource available, which comes with a flexible configuration template. Most notably, you can specify the action property (by default install), including the :upgrade value, which allows you to upgrade installed software to the latest version, exactly what we set out to do in this article.

snap_package 'name' do
  channel           String # default value: "stable"
  options           String, Array
  package_name      String, Array
  source            String
  timeout           String, Integer
  version           String, Array
  action            Symbol # defaults to :install if not specified
end

Likewise, you can accomplish the same set of installs and upgrades with Ansible. The community.general.snap module allows you to govern snaps on your clients, including the channel, classic confinement, as well as whether to install or remove packages.

# Install a snap with classic confinement
- name: Install "foo" with option --classic
  community.general.snap:
    name: foo
    classic: yes

# Install a snap with from a specific channel
- name: Install "foo" with option --channel=latest/edge
  community.general.snap:
    name: foo
    channel: latest/edge

The tip of the iceberg

This is far from a comprehensive list of available integrations or tools you could use to configure your environment in a seamless, safe way. For example, you could use JuJu to manage your systems, or you could set up a Snap Proxy, especially if you have specific network requirements. Last but not the least, if you’re not using any existing commercial tools, you could manually configure snap refreshes using the refresh.hold value and cron jobs.

Summary

Snaps works well alongside configuration management tools. Of course, you do need to make some adjustments to the default setup to make sure everything is orchestrated correctly. The availability and integration of modules and packages for the likes of Chef, Ansible and others make snap deployment easier, as you have better situational awareness of software changes in your (entire) environment.

If you have any other ideas or suggestions or perhaps even practical examples on how to combine the use of snaps with other tools to maintain system and application baseline configurations or roll out changes in an efficient way, please join our forum and share your thoughts. We are fairly certain these insights will be useful to a large number of people.

Photo by Birmingham Museums Trust on Unsplash.

Related posts

Canonical and OpenAirInterface to collaborate on open source telecom network infrastructure

Canonical is excited to announce that we are collaborating with OpenAirInterface (OAI) to drive the development and promotion of open source software for open radio access networks (Open RAN). Canonical will bring automation in software lifecycle management to OAI’s RAN stack, alongside additional infrastructure capabilities. This will be […]

Kubernetes backups just got easier with the CloudCasa charm from Catalogic

For a native integration for Canonical’s Kubernetes platform, Juju was the perfect fit, and the charm makes consuming CloudCasa seamless for users. […]

What is a Kubernetes operator?

Kubernetes is the open source, industry-standard platform for deploying, managing and scaling containerized applications – and applications on Kubernetes are easier with operators. […]