---
title: Write a file on a machine
description: "Have Ysra write a whole text file on a machine after you approve the exact diff, with a backup and a check afterwards."
new_in: "2.2"
---

**Writing a file** puts a complete text file on a [machine](overview.md) — an
nginx site, a systemd unit, an application’s configuration — after you
approve the exact content as a diff. Before you start, the machine must be in
[change mode](overview.md#modes). For a whole folder, see
[Deploy a folder](deploy-folder.md).

## Steps

1. Ask in a thread:

    ```text
    › put this nginx site on web-01 as /etc/nginx/sites-available/app.conf
    ```

2. Read the card. Its title is **Write */path* on *machine*?** for a file that
   exists, or **Create */path* on *machine*?** for a new one.

    | The card shows | Example |
    |---|---|
    | What, size and mode | *Replaces /etc/nginx/sites-available/app.conf on web-01 · 812 bytes · mode 0644* |
    | The **diff** | Old and new line numbers |
    | **On**, **Why**, **Expect**, **Undo** | As on any [change card](overview.md#approvals) |
    | Backup | *The current file is kept as /path.ysra-bak.<time>.* |

3. Choose **Run it** or **Skip**. Only you can answer; auto mode never does.
   On a production machine, a file that controls access (SSH files,
   `sudoers`) also needs the machine’s name typed.

The file is in place, and the write appears in the machine’s list of what ran
as `write /path` and in the gateway’s [log](overview.md#logs). There is no
separate success message.

## How the file is written

| Step | Detail |
|---|---|
| In one step | The new file replaces the old one whole; a half-written file is never left in place |
| Backup | The old file is kept beside it as `<path>.ysra-bak.<time>`, for example `app.conf.ysra-bak.20261006T115448` |
| Check | Ysra compares the file on the machine with what you approved, by checksum |
| Undo | Copy the backup back, or ask Ysra to (it asks first) |

## Which approval kind it counts as

For [signed approvals](approvals.md):

| File | Kind |
|---|---|
| Most files | **config** |
| SSH files, such as `authorized_keys` or `sshd_config` | **access** |
| `sudoers`, `passwd` and similar | **users** |

## If it doesn’t work

| Case | Ysra says |
|---|---|
| A secret file | *That’s a secret file (keys, passwords, credentials); I don’t write those on machines.* |
| A symbolic link | */path is a link (to …); I write only the file itself, so name that instead.* |
| Not a regular file | */path isn’t a regular file, so I didn’t write it.* |
| Content over 256 KB | Refused. Split it, or copy the file yourself |
| A look-only machine | *web-01 is in observe mode, so I only look there. Switching it to change mode is your call (`ysra machines mode web-01 change`).* |
| You chose **Skip**, or didn’t answer | *You didn’t approve that, so I didn’t write it.* |

## Related

- [How machines work](overview.md) — how every change is approved.
- [Deploy a folder to a machine](deploy-folder.md) — a whole built site or app.
- [Runbooks](runbooks.md) — several changes in order, each checked.
