# Deploy Process

When you run a pyinfra deploy via the CLI or API, these are the high level steps taken:

- Connect to each of the target hosts
- Generate operations for each host as defined by the user, gathering facts as required
- The operations are executed on the remote hosts, in a configurable manner

## Connecting

To connect to the target hosts, pyinfra uses an inventory. This contains metadata on all of the target machines, in addition to any user defined data for the deploy. Using this SSH connections are attempted in parallel until all hosts are either connected or have failed.

## Generating Operations

Operations define the desired state of the target hosts. When operations are added to a deploy, facts/state is read from each of the hosts, for example `directory:/opt/my_app`. Based on these facts and the desired state, operations output a list of commands per target host.

The list of commands contains:

- simple shell commands
- local/remote filenames for uploading files
- Python functions which serve as mid-deploy callbacks

## Executing Operations

After all the operations & associated commands have been added to the deploy they are executed in parallel on the remote hosts. By default they are run in order, waiting between each operation for all hosts to complete or error. This behaviour can be changed to skip waiting by using `--no-wait`, or all operations can be run one host after the other, using `--serial`. Serial can also be applied on a per-operation level by setting `serial=True`.