file
Manage file contents, permissions, and ownership.
The file resource manages files on remote hosts. For content and template modes it compares content using SHA-256 checksums. source mode currently transfers the local file during apply(), but check() does not hash the local source file.
Input
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
path | string | — | Yes | Absolute path on the remote host |
content | string | — | No | Inline file content |
source | string | — | No | Local file path to copy via SCP |
template | (vars: TemplateContext) => string | — | No | Template function |
mode | string | — | No | File mode (e.g. "0644") |
owner | string | — | No | File owner |
group | string | — | No | File group |
state | "present" | "absent" | "present" | No | Whether the file should exist |
To avoid ambiguous behavior, pass only one of content, source, or template. The current precedence is content, then template, then source.
If you're only managing attributes (mode, owner, group), the file must already exist.
Output
| Field | Type | Description |
|---|---|---|
path | string | The file path |
checksum | string | SHA-256 checksum of the file content |
changed | boolean | Whether the file was modified |
Behavior
Content modes
Treat the three content modes as mutually exclusive:
| Mode | Source | Transfer method |
|---|---|---|
content | Inline string | Written via cat > with stdin |
source | Local file | Transferred via scp |
template | Template function | Evaluated with ctx.vars, written via cat > |
Check phase
- Tests file existence with
test -f. - For
state: "absent"— in desired state if the file doesn't exist. - For
state: "present"— forcontentandtemplate, computes SHA-256 of the remote file content withsha256sumand compares against the expected content. - For
source, checks existence and attributes, but does not currently compare the remote file against the local source checksum. - Checks file mode, owner, and group via
statif specified.
Apply phase
state: "present": writes content to the file, sets mode/owner/group if specified.state: "absent": removes the file withrm -f.- After writing, computes the final SHA-256 checksum.
Annotations
| Property | Value |
|---|---|
| Nature | Declarative |
| Idempotent | Yes for content/template; source has a current check limitation |
| Destructive | Yes (when state: "absent") |
| Read-only | No |
| Required capabilities | exec; source also needs transfer during apply |
Examples
Write static content
await file({
path: "/etc/app.conf",
content: "key=value\nport=8080\n",
mode: "0644",
})Use a template
await file({
path: "/etc/nginx/sites-available/app.conf",
template: (vars) => `
server {
listen ${vars.port ?? 80};
server_name ${vars.domain};
}`,
mode: "0644",
})Copy a local file
await file({
path: "/opt/app/config.json",
source: "./configs/production.json",
mode: "0600",
owner: "app",
})This uses scp to transfer the file and requires the transfer transport capability.
Current limitation: source-mode changes are not detected by check() via a local checksum. If only the local file contents change, Ignition may still report ok.
Remove a file
await file({ path: "/tmp/old-config.conf", state: "absent" })Set ownership and permissions
await file({
path: "/var/log/app.log",
content: "",
mode: "0640",
owner: "app",
group: "app",
})Gotchas
- For predictable behavior, pass exactly one of
content,source, ortemplate. sourcemode requires thetransfercapability (usesscp). The other modes only needexec.- Templates receive
ctx.vars— the merged variables from inventory, CLI--varflags, and recipe-set variables. - SHA-256 comparison applies to
contentandtemplate.sourcemode does not currently compare the local file checksum duringcheck(). - The
modefield should be an octal string like"0644", not a number.