Skip to content

file

The file module handles file operations between the local machine and remote hosts via SFTP. It supports three modes: copy, template, and fetch.

Upload a local file to the remote host:

file "/etc/nginx/nginx.conf" {
src "files/nginx.conf"
owner "root"
group "root"
mode "0644"
}

Interpolate ${var} placeholders and expand ${for} loops before uploading:

file "/etc/myapp/config.toml" {
src "templates/config.toml"
template #true
owner "appuser"
mode "0600"
}

Template mode supports:

  • ${var-name} — simple variable interpolation
  • ${for item in collection}...${endfor} — loop over structured variables
  • ${@inventory.host.address}inventory references
  • ${for h in @group.name}...${endfor} — loop over hosts in an inventory group

See Template Loops for detailed examples.

Upload an entire directory tree to the remote host:

file "/etc/myapp/" src="configs/" recurse=#true owner="deploy" mode="0644"

All files under the local configs/ directory are uploaded to /etc/myapp/, preserving the directory structure. Remote directories are created automatically.

Recursive copy supports:

  • Idempotency — each file is compared by SHA256 checksum; only changed files are uploaded
  • Template mode — combine with template=#true to interpolate all files in the directory
  • Attributesowner, group, and mode are applied recursively to all files and directories

Download a remote file to the local machine:

file "backups/${host.name}-dump.sql" {
src "/var/backups/db.sql"
fetch #true
}
ParameterTypeDescription
(positional)stringDestination path (remote for copy/template, local for fetch)
srcstringSource file path (required)
templatebooleanInterpolate ${var} placeholders and expand ${for} loops before uploading
fetchbooleanDownload from remote instead of uploading
recursebooleanRecursively copy a directory tree
ownerstringRemote file owner
groupstringRemote file group
modestringRemote file permissions (e.g., "0644")

The src path is resolved relative to the plan file’s directory, not the current working directory. Absolute paths are used as-is.

Given this layout:

project/
├── inventory.kdl
├── plans/
│ ├── web.kdl ← plan file
│ └── files/
│ └── nginx.conf

A step in plans/web.kdl references the file relative to its own directory:

file "/etc/nginx/nginx.conf" src="files/nginx.conf"

This resolves to plans/files/nginx.conf regardless of where you run glidesh from.

Copy and template modes compare SHA256 checksums between the local and remote files. If they match, the transfer is skipped. When owner, group, or mode are specified, the module also checks the remote file’s attributes — if only permissions differ, the attributes are corrected without re-uploading the file. This applies to both single-file and recursive directory copies. Fetch mode always downloads.

See the web-server example for a template-based nginx deployment.