Build a file from a template.

⚙️ Compatible targets: Linux


source_templateSource file containing a template to be expanded (absolute path on the target node).

This parameter is required.
pathDestination file (absolute path on the target node).

This parameter is required.
template_typeTemplate type (cfengine, jinja2 or mustache).

This parameter is required.

Outcome conditions

You need to replace ${path} with its actual canonified value.

  • ✅ Ok: file_from_template_${path}_ok
    • ☑️ Already compliant: file_from_template_${path}_kept
    • 🟨 Repaired: file_from_template_${path}_repaired
  • ❌ Error: file_from_template_${path}_error


method: file_from_template_type
  template_type: VALUE
  path: VALUE
  source_template: VALUE


These methods write a file based on a provided template and the data available to the agent.


To use these methods (file_from_template_*), you need to have:

  • a template file
  • data to fill this template

The template file should be somewhere on the local file system, so if you want to use a file shared from the policy server, you need to copy it first (using file_copy_from_remote_source).

It is common to use a specific folder to store those templates after copy, for example in ${sys.workdir}/tmp/templates/.

The data that will be used while expanding the template is the data available in the agent at the time of expansion. That means:

  • Agent's system variables (${sys.*}, ...) and conditions (linux, ...)
  • data defined during execution (result conditions of generic methods, ...)
  • conditions based on condition_ generic methods
  • data defined in ncf using variable_* generic methods, which allow for example to load data from local json or yaml files.

Template types

ncf currently supports three templating languages:

  • mustache templates, which are documented in file_from_template_mustache
  • jinja2 templates, which are documented in file_from_template_jinja2
  • CFEngine templates, which are a legacy implementation that is here for compatibility, and should not be used for new templates.


Here is a complete example of templating usage:

The (basic) template file, present on the server in /PATH_TO_MY_FILE/ntp.conf.mustache (for syntax reference, see file_from_template_mustache):

server {{{vars.configuration.ntp.hostname}}}
server hardcoded.server.example

And on your local node in /tmp/ntp.json, the following json file:

{ "hostname": "my.hostname.example" }

And the following policy:

# Copy the file from the policy server
file_copy_from_remote_source("/PATH_TO_MY_FILE/ntp.conf.mustache", "${sys.workdir}/tmp/templates/ntp.conf.mustache")
# Define the `ntp` variable in the `configuration` prefix from the json file
variable_dict_from_file("configuration", "ntp", "/tmp/ntp.json")
# Expand your template
file_from_template_type("${sys.workdir}/tmp/templates/ntp.conf.mustache", "/etc/ntp.conf", "mustache")
# or
# file_from_template_mustache("${sys.workdir}/tmp/templates/ntp.conf.mustache", "/etc/ntp.conf")

The destination file will contain the expanded content, for example on a Linux node:

server my.hostname.example