pyinfra is an extremely powerful tool for ad-hoc execution and management of remote servers.
As described in the getting started page, pyinfra needs an inventory and some operations. These are used with the CLI as below:
Usage: pyinfra [OPTIONS] INVENTORY OPERATIONS...
# INVENTORY
+ a file (inventory.py)
+ hostname (host.net)
+ Comma separated hostnames: host-1.net,host-2.net,@local
# OPERATIONS
# Run one or more deploys against the inventory
pyinfra INVENTORY deploy_web.py [deploy_db.py]...
# Run a single operation against the inventory
pyinfra INVENTORY server.user pyinfra home=/home/pyinfra
# Execute an arbitrary command on the inventory
pyinfra INVENTORY exec -- echo "hello world"
# Run one or more facts on the inventory
pyinfra INVENTORY fact server.LinuxName [server.Users]...
pyinfra INVENTORY fact files.File path=/path/to/file...
# Debug (print) inventory hosts, groups and data
pyinfra INVENTORY debug-inventory
By default pyinfra only prints high level information (this host connected, this operation started), this can be increased as follows:
-v
: print out facts collected as well as noop information (package X already installed)-vv
: as above plus print shell input to the remote host-vvv
as above plus print shell output from the remote host
When using pyinfra inventory can be provided directly via the command line or defined in a file. Both support the full range of connectors and multiple hosts. Some CLI examples:
# Load inventory hosts from a file
pyinfra inventory.py ...
# Execute via SSH against two servers
pyinfra my-server.net,my-other-server.net ...
# Execute on the local machine via subprocess
pyinfra @local ...
# Execute via local subprocess and a server over SSH
pyinfra my-server.net,@local ...
# Execute against a Docker container
pyinfra @docker/centos:8 ...
It is possible to limit the inventory at execution time using the --limit
argument. Multiple --limit
s can be provided. The value must either match a specific host by name or via glob style pattern, eg:
# Only execute against @local
pyinfra inventory.py deploy.py --limit @local
# Only execute against hosts in the `app_servers` group
pyinfra inventory.py deploy.py --limit app_servers
# Only execute against hosts with names matching db*
pyinfra inventory.py deploy.py --limit "db*"
# Combine multiple limits
pyinfra inventory.py deploy.py --limit app_servers --limit db-1.net
pyinfra can execute shell commands on remote hosts by using pyinfra exec
. For example:
pyinfra inventory.py exec -- my_command_goes_here --some-argument
Note:
Anything on the right hand side of the --
will be passed into the target
One of pyinfra's top design features is its ability to return remote command output in real-time. This can be used to debug N remote services, and is perfect for debugging distributed services.
For example - a large Elasticsearch cluster. It can be useful to stream the log of every instance in parallel, which can be achieved easily like so:
pyinfra inventory.py exec --sudo -- tail -f /var/log/elasticsearch/elasticsearch.log
In addition to executing simple commands, pyinfra can execute any of it's builtin operations on remote hosts direct via the CLI.
For example, here we ensure that nginx
is installed on the remote servers:
# Ubuntu example
pyinfra inventory.py apt.packages nginx update=true _sudo=true
# Centos example
pyinfra inventory2.py yum.packages nginx _sudo=true
Now that nginx is installed on the box, we can use pyinfra to control the nginx
service - here we ensure it's running and enabled to start on system boot:
pyinfra inventory.py init.service nginx running=true enabled=true
We can reboot instances a couple of ways using adhoc commands (assuming sudo is enabled in inventory.py):
# using server.reboot()
pyinfra inventory.py server.reboot reboot_timeout=0 delay=0
# using exec
pyinfra inventory.py exec -- reboot
For additional debug info, use one of these options:
--debug
Print debug info.--debug-facts
Print facts after generating operations and exit.--debug-operations
Print operations after generating and exit.
Add the following to your ~/.bash_profile
or ~/.profile
files:
- bash
source scripts/pyinfra-complete.sh
. - zsh
source scripts/pyinfra-complete.zsh
.
These files were generated using these commands:
env _PYINFRA_COMPLETE=bash_source pyinfra > pyinfra-complete.sh
env _PYINFRA_COMPLETE=zsh_source pyinfra > pyinfra-complete.zsh