# Quickstart

Register one server, run a one-step plan against it, and read the result. About ten minutes, and nothing is installed on the host.

Source: https://opafra.com/docs/quickstart

---

Register one server, run a one-step plan against it, and read the result. This takes
about ten minutes and installs nothing on the machine you target.

By the end you will have:

- A registered host that Opafra can reach over SSH
- A plan of one step, drafted from a sentence
- A dry run showing what it would do, and a real run showing what it did
- Both on the audit record

## Before you begin

- A Linux host that answers SSH, and a user on it you can reach
- That user able to run the command you want, with `sudo -n` if it needs privilege
- An Opafra workspace, which you get on your first sign-in

> **Note**
>
> Opafra never installs an agent. Everything in this tutorial runs over the same SSH your
> own terminal uses, with the credential you supply.

## 1. Register the host

Open **Inventory**, choose **Add server**, and give it a hostname, a user, and a
credential. If you do not already have a key Opafra can use, generate one in the
**SSH keys** tab and install its public half on the host:

```bash title="on your machine"
ssh-copy-id -i ~/.ssh/opafra_ed25519.pub ops@web-01.example.com
```

Opafra runs a connection check as soon as you save. You should see the server land in
the list with a green check and its detected OS family:

```text title="connection check"
DNS resolves          ok
TCP :22 reachable     ok
auth accepted         ok
sudo available        ok
facts gathered        ok    Debian 12 · openssh 9.2p1
```

If the check fails, the error names the cause rather than the symptom: a refused
connection, a rejected key, or a host key that does not match what we saw before.

## 2. Write a one-step plan

Go to **Plans**, choose **New plan**, and describe what you want in one sentence:

```text title="request"
Check the nginx version on web-01
```

The composer drafts the plan against your inventory. For a request this small it will
produce a single step using a read-only tool:

```yaml title="drafted plan"
name: Check the nginx version
targets:
  - web-01.example.com
steps:
  - name: Read the installed version
    tool: command.run
    args:
      command: nginx -v
```

Read the step before you go on. The composer is drafting against your real inventory,
and reviewing what it wrote is the habit this product is built around.

## 3. Dry run it

Choose **Dry run**. Opafra connects to the host and reports what each step would do
without doing it. For a read-only step the answer is that nothing changes.

You should see:

```text title="dry run"
web-01.example.com
  Read the installed version   would run: nginx -v
  0 changes, 0 destructive
```

> **Tip**
>
> A dry run is per host. When a plan targets an environment, you get one of these blocks
> for every host in it, so a host that would behave differently shows up here rather than
> halfway through a real run.

## 4. Run it

Choose **Run**. The console streams each step as it executes, per host.

You should see:

```text title="run"
web-01.example.com
  Read the installed version   unchanged   0.4s
    nginx version: nginx/1.25.3
completed   1 step   0 errors   logged to audit
```

You now have a run on the record: what was asked, what was drafted, what it did, and on
which host.

## Clean up

Nothing was changed on the host, so there is nothing to undo there. To reset Opafra
itself, delete the plan and then the server from **Inventory**. The run record and the
audit entries remain, which is the intended behaviour: history outlives the objects it
describes.

## What you built

A registered host, a plan drafted from a sentence, a dry run that proved what it would
do, and a real run with an audit entry behind it. That is the whole shape of the product
on the smallest possible example.

## Next steps

- [Core concepts](/docs/concepts) for the vocabulary this tutorial used without
  explaining
- [Dry runs](/docs/running/dry-run) for what a preview can and cannot prove
