Cleanup temporary files in Puppet

Cleanup temporary files in Puppet In a Puppet manifest, you sometimes need to make a temporary file. For example, a configuration file to be passed to an installer. Naturally, you want to clean up behind you. But in the end, something as simple as this turns out to be rather complicated. Unnecessary complicated. So that’s why we made a solution for that.

Why not ensure => absent?

Puppet allows you to manage a resource only once. This is to ensure consistent manifests and configuration results. Usually, that is excellent. But it hurts us for this use case. Because you can only add a file once to a manifest, you cannot use the Puppet file resource to both create and remove the file in the same manifest.

Let’s use tidy

At first glance, the tidy resource looks like the solution. But under the hood, tidy resource add’s file resources. To the existing manifest (generate). If your manifest already contains a file => ensure, The tidy generator will not (it can’t) create a file => absent resource to the same manifest. The annoying thing is that it doesn’t tell you about it.

A simple exec will do the job.

A simple way around these shortcomings is to use the exec resource and issue the /bin/rm -f command. One of the downsides of doing this is that it is OS-dependent. If you want your manifest to work on multiple OS-es, you might have to write a lot of code to remove the correct file.

Another downside of using an exec resource might be ordering. You will have to ensure that the file is removed only after it is used. If it is used multiple times in the manifest and in different if blocks, your ordering can become a bit complicated. At least too difficult for something simple as removing your trash.

The cleanup resource

The easy_type module contains a solution for the dilemma. The cleanup resource. As the name implies, it cleans up. Let’s see how we can use this.

file { '/data/my_temporary_file':
  ensure => 'present',
  content => 'my_data = true',
}

cleanup { '/data/my_temporary_file':}

This example shows the basic usage of the cleanup resource in combination with creating a temporary file. At the end of the Puppet run, the cleanup resource will ensure that the file /data/my_temporary_file is removed. Because the cleanup resource is in no way connected to the Puppet file resource, you can use them both together without a chance of duplicate resources.

No ordering?

Yes no ordering! That was not a typo. The cleanup resource removes the files after all of the Puppet code has been applied. To show you how this works, let’s use this contrived example:

cleanup { '/a.a':
  loglevel => 'notice',
}

When we run this manifest you get this output:

Notice: Compiled catalog for oradb.example.com in environment production in 0.01 seconds
Notice: Applied catalog in 0.01 seconds
Notice: /Stage[main]/Main/Cleanup[/a.a]: Cleaning files marked for cleanup.
Notice: /Stage[main]/Main/Cleanup[/a.a]: File /a.a not found, skipping cleanup...

Two things are worth noticing. The first thing is:: the cleanup starts after the whole manifest is applied (e.g. the message Notice: Applied catalog in 0.01 seconds). There is no message during the application of the manifest. The second thing is that it will not fail when the file is not available. This means that you can be flexible with when and how often you a cleanup resource.

Multiple file cleanup

Like all Puppet resources, you can use an array of strings as a title. See this example:

$files_to_cleanup = [
  '/tmp/my_config_file',
  '/tmp/my_tmp_dir',
  '/tmp/my_second_tmp/*.txt',
]
cleanup { $files_to_cleanup: }

Here you can see the usage of an array as a title and the use of different file specs to be used for cleanup of files.

Meaningful title

Although the cleanup resource doesn’t give any messages during normal operation (e.g., default loglevel is debug), it might still be useful to use a more meaningful text as a title. You can!

$files_to_cleanup = [
  '/tmp/my_config_file',
  '/tmp/my_tmp_dir',
  '/tmp/my_second_tmp/*.txt',
]
cleanup { 'All the temporary stuff':
  file_name => $files_to_cleanup,
  loglevel => 'notice',
}

Here is the output of this code:

Notice: Compiled catalog for oradb.example.com in environment production in 0.01 seconds
Notice: Applied catalog in 0.01 seconds
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: Cleaning files marked for cleanup.
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: File /tmp/my_config_file not found, skipping cleanup...
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: File /tmp/my_tmp_dir not found, skipping cleanup...
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: File /tmp/my_second_tmp/*.txt not found, skipping cleanup...

As you can see, the title now contains a meaningful text.

Where is the cleanup resource defined?

The cleanup custom types are defined in the enterprisemodules-easy_type module. The enterprisemodules-easy_type module is a collection of functions, custom types, and other Puppet goodies we use for all of our commercial modules. You are free to install and use it. Check the documentation on the Puppet forge.

Conclusion

Something simple as cleaning up behind you was unnecessarily tricky before. But with the introduction of the cleanup resource it has become as easy as it should be.

If you could use a hand, we are here to help. Making good Puppet code is our bread and butter at Enterprise Modules. But besides developing our own modules, we are also helping customers build the best possible Puppet code. Do you think you could need some assistance? Don’t hesitate to contact us at info@enterprisemodules.com or by phone: +31 (0)30-601 6000 for some consultancy.

About us

Enterprise modules is the leading developer of enterprise-ready puppet modules for Oracle databases,Oracle WebLogic, and IBM MQ software. Our puppet modules help sysadmins and DBAs to automate the installation, configuration, and management of their databases and application server systems. These modules allow them to make managed, consistent, repeatable, and fast changes to their infrastructure and automatically enforce the consistency. We are a proud member of the Conclusion family. Conclusion is thé multidisciplinary service provider in the field of Business Transformation and IT Services. Our tagline? Business Done Differently. Our 1250 specialists and professionals live up to that every day by truly combining our IT knowledge with business and domain know-how. With dedication, creativity, and flexibility, we take responsibility for the social and mission-critical business processes and systems of our customers and enable organizations to digitally transform their business model. Our primary focus is on the Dutch market and more specifically on the domains of Public Transport, Healthcare, Finance, and Industry. Conclusion. Business Done Differently