Getting Started

This guide should help describe the basics of deploying stuff with pyinfra.

Install pyinfra with pip or pipx (see full install instructions):

pip install pyinfra

To do something with pyinfra you need two things:


Hosts, groups and data. Hosts are targets for pyinfra to execute commands or state changes. Hosts can belong to one or more groups, and both groups and hosts can have data associated with them. Examples: an SSH server, a Docker container, the local machine.


Commands to execute or state to apply to the target hosts in the inventory. These can be simple shell commands (uptime) or state definitions such as “ensure the iftop apt package is installed”.

Ad-hoc commands with pyinfra

Let’s start off executing a simple ad-hoc shell command. The first argument always specifies the inventory and the following arguments the operations to execute:


# Execute an arbitrary shell command
pyinfra exec -- echo "hello world"

# Execute a shell command within a docker container
pyinfra @docker/ubuntu:18.04 exec -- bash --version

As you’ll see, pyinfra runs the echo command and prints the output. See the available command line options and examples of ad-hoc commands.

State definitions

Now that we can execute ad-hoc shell commands, let’s define some state to ensure. The key feature here is that when you run these commands for a second time, pyinfra won’t need to do execute anything because the target is already up to date. You can read more about how this works in Executing Deploys.

# Ensure a package is installed on a Centos 8 instance
pyinfra @docker/centos:8 dnf.packages vim sudo=true

# Ensure a package is installed on multiple instances
pyinfra @docker/ubuntu:18.04,@docker/debian:9 apt.packages vim sudo=true

# Stop a service on a remote host
pyinfra some_remote_host init.systemd httpd sudo=True running=False

Create a Deploy

A deploy is a collection of inventories and operations defined in Python files. These deploys can be saved and reused (committed to git, etc). Think of a deploy like Ansible’s playbook or Chef’s cookbook. We’ll now replicate the above hello world ad-hoc command as a deploy.

To get started let’s create an containing our hosts to target:

my_hosts = ['', '@docker/ubuntu:18.04']  # define a group as a list of hosts

Now we need a containing our operations to execute:

from pyinfra.operations import apt, server
    name='Run an ad-hoc command',  # optional name for the operation
    commands='echo "hello world"',

# Define some state - this operation will do nothing on subsequent runs
    name='Install vim via apt',
    sudo=True,  # use sudo when installing the packages

We can now execute this deploy like so:

pyinfra -v  # the optional verbose flag '-v' will print the command output

That’s the basics of pyinfra! Possible next steps: