Resources describe the desired state of your infrastructure. Each resource represents something to manage and is backed by a provider that implements platform-specific management logic.
Every resource has a type, a unique name, and resource-specific properties.
Resource Types
Archive - Download, extract and copy files from tar.gz and zip archives
Here we install zsh on all linux machines unless they are running inside a docker container.
The following table shows how the two conditions interact:
if
unless
Resource Managed?
(not set)
(not set)
Yes
true
(not set)
Yes
false
(not set)
No
(not set)
true
No
(not set)
false
Yes
true
true
No
true
false
Yes
false
true
No
false
false
No
About Names
Resources can be specified like:
/etc/motd:
ensure: present
This sets name to /etc/motd, in the following paragraphs we will refer to this as name.
Subsections of Resources
Archive
The archive resource downloads and extracts archives from HTTP/HTTPS URLs. It supports tar.gz, tgz, tar, and zip formats.
Note
The archive file path (name) must have the same archive type extension as the URL. For example, if the URL ends in .tar.gz, the name must also end in .tar.gz.
This downloads the archive, extracts it to /opt/app, and removes the archive file after extraction. Future runs skip the download if /opt/app/bin/app exists.
Ensure Values
Value
Description
present
The archive must be downloaded
absent
The archive file must not exist
Properties
Property
Description
name
Absolute path where the archive will be saved
url
HTTP/HTTPS URL to download the archive from
checksum
Expected SHA256 checksum of the downloaded file
extract_parent
Directory to extract the archive contents into
creates
File path; if this file exists, the archive is not downloaded or extracted
cleanup
Remove the archive file after successful extraction (requires extract_parent and creates)
owner
Owner of the downloaded archive file (username)
group
Group of the downloaded archive file (group name)
username
Username for HTTP Basic Authentication
password
Password for HTTP Basic Authentication
headers
Additional HTTP headers to send with the request (map of header name to value)
provider
Force a specific provider (http only)
Authentication
The archive resource supports two authentication methods:
The archive resource is idempotent through multiple mechanisms:
Checksum verification: If a checksum is provided and the existing file matches, no download occurs.
Creates file: If creates is specified and that file exists, neither download nor extraction occurs.
File existence: If the archive file exists with matching checksum and owner/group, no changes are made.
For best idempotency, always specify either checksum or creates (or both).
Cleanup Behavior
When cleanup: true is set:
The archive file is deleted after successful extraction
The extract_parent property is required
The creates property is required to track extraction state across runs
Supported Archive Formats
Extension
Extraction Tool
.tar.gz, .tgz
tar -xzf
.tar
tar -xf
.zip
unzip
Note
The extraction tools (tar, unzip) must be available in the system PATH.
Exec
The exec resource executes commands to bring the system into the desired state. It is idempotent when used with the creates property or refreshonly mode.
Warning
Specify commands with their full path, or use the path property to set the search path.
The shell provider passes the entire command string to /bin/sh -c, so shell quoting rules apply. The posix provider parses arguments using shell-like quoting but does not invoke a shell.
Properties
Property
Description
name
The command to execute (used as the resource identifier)
command
Alternative command to run instead of name
cwd
Working directory for command execution
environment (array)
Environment variables in KEY=VALUE format
path
Search path for executables as a colon-separated list (e.g., /usr/bin:/bin)
returns (array)
Exit codes indicating success (default: [0])
timeout
Maximum execution time (e.g., 30s, 5m); command is killed if exceeded
creates
File path; if this file exists, the command does not run
refreshonly (boolean)
Only run when notified by a subscribed resource
subscribe (array)
Resources to subscribe to for refresh notifications (type#name or type#alias)
logoutput (boolean)
Log the command output
provider
Force a specific provider (posix or shell)
File
The file resource manages files and directories, including their content, ownership, and permissions.
The APT provider preserves existing configuration files during package installation and upgrades. When a package is upgraded and the maintainer has provided a new version of a configuration file, the existing file is kept (--force-confold behavior).
Packages in a partially installed or config-files state (removed but configuration remains) are treated as absent. Reinstalling such packages will preserve the existing configuration files.
Note
The provider will not run apt update before installing a package. Use an exec resource to update the package index if necessary.
The provider runs non-interactively and suppresses prompts from apt-listbugs and apt-listchanges.
Scaffold
The scaffold resource renders files from a source template directory to a target directory. Templates have access to facts and Hiera data, enabling dynamic configuration generation from directory structures.
Warning
Target paths must be absolute and canonical (no . or .. components).
This renders templates from the templates/app directory into /etc/app using the Jet template engine, removing any files in the target not present in the source.
Tip
This is implemented using the github.com/choria-io/scaffold Go library, you can use this in your own projects or use the included scaffold CLI tool.
Ensure Values
Value
Description
present
Target directory must exist with rendered template files
absent
Managed files must be removed; target directory removed if empty
Properties
Property
Description
name
Absolute path to the target directory
source
Source template directory path (relative to working directory or absolute)
engine
Template engine: go or jet (default: jet)
skip_empty
Do not create empty files in rendered output
left_delimiter
Custom left template delimiter
right_delimiter
Custom right template delimiter
purge
Remove files in target not present in source
post
Post-processing commands: glob pattern to command mapping
provider
Force a specific provider (choria only)
Template Engines
Two template engines are supported:
Engine
Library
Default Delimiters
Description
go
Go text/template
{{ / }}
Standard Go templates
jet
Jet templating
[[ / ]]
Jet template language
The engine defaults to jet if not specified. Delimiters can be customized via left_delimiter and right_delimiter.
The post property defines commands to run on rendered files. Each entry is a map where the key is a glob pattern matched against the file’s basename and the value is a command to execute. Use {} in the command as a placeholder for the file’s full path; if omitted, the path is appended as the last argument.
Post-processing runs immediately after each file is rendered. Files skipped due to skip_empty are not post-processed.
Purge Behavior
When purge: true is set, files in the target directory that are not present in the source template directory are deleted during rendering. In noop mode, these deletions are logged but not performed.
When purge is disabled (the default), files not present in the source are tracked but not removed. They do not affect idempotency checks for ensure: present, meaning the resource is considered stable even if extra files exist in the target.
Removal Behavior
When ensure: absent, only managed files (changed and stable) are removed. Files not belonging to the scaffold (purged files) are left untouched. After removing managed files and empty subdirectories, the target directory itself is removed on a best-effort basis — it is only deleted if empty. If unrelated files remain, the directory is preserved and no error is raised.
Idempotency
The scaffold resource determines idempotency by rendering templates in noop mode and comparing results against the target directory.
For ensure: present:
Changed files: Files that would be created or modified. Any changed files make the resource unstable.
Stable files: Files whose content matches the rendered output. At least one stable file must exist for the resource to be considered stable.
Purged files: Files in the target not present in the source. These only affect stability when purge is enabled.
For ensure: absent, the status check filters Changed and Stable lists to only include files that actually exist on disk. This means after a successful removal, the scaffold is considered absent even if the target directory still exists with unrelated files. Purged files never affect the absent stability check.
Source Resolution
The source property is resolved relative to the manager’s working directory when it is a relative path. URL sources (with a scheme) are passed through unchanged. This allows manifests bundled with template directories to use relative paths.
Template Environment
Templates receive the full template environment, which provides access to:
facts - System facts for the managed node
data - Hiera-resolved configuration data
Template helper functions
Creating Scaffolds
A scaffold source is a directory tree where every file is a template. The directory structure is mirrored directly into the target, so the source layout becomes the output layout.
The Jet engine is the default because its [[ / ]] delimiters avoid conflicts with configuration files that use curly braces (YAML, JSON, systemd units). Use the Go engine when you need access to Sprig functions.
Partials
Files inside a _partials directory are reusable template fragments. They are rendered on demand using the render function but are excluded from the output.
This is useful for shared headers, repeated configuration blocks, or any content used across multiple files.
Two functions are available in both template engines:
render evaluates another template file from the source directory and returns its output as a string. The partial is rendered using the same engine and data as the calling template.
[[ render("_partials/database.conf", .) ]]
{{ render "_partials/database.conf" . }}
write creates an additional file in the target directory from within a template. This is useful for dynamically generating files based on data — for example, creating one configuration file per service.
[[ write("extra.conf", "generated content") ]]
{{ write "extra.conf" "generated content" }}
Sprig Functions
When using the Go template engine, all Sprig template functions are available. These provide string manipulation, math, date formatting, list operations, and more:
# Go engine example with Sprig functions
hostname: {{ .facts.hostname | upper }}
packages: {{ join ", " .data.packages }}
generated: {{ now | date "2006-01-02" }}
Example Scaffold
A complete scaffold for an application configuration:
log_level = info
log_file = /var/log/myapp/web01.log
[server]
bind = 0.0.0.0
port = 8080
workers = 4
Service
The service resource manages system services. Services have two independent properties: whether they are running and whether they are enabled to start at boot.
Warning
Use real service names, not virtual names or aliases.
Services can subscribe to other resources and restart when those resources change.