pyinfra Documentation

repository·3.x·Indexed 27 days ago

https://github.com/pyinfra-dev/pyinfra

pyinfra is a fast, agentless Python-based infrastructure automation tool used to automate, provision, manage, and deploy infrastructure. It allows users to turn Python code into shell commands to manage SSH servers, local machines, and Docker containers at scale. The tool supports declarative operations for system state management, custom inventory and executing connectors, and a programmatic Python API for orchestration.

Tokens
26K
Snippets
78
Records
169
Agent score
91%

What's inside pyinfra

  1. Understand pyinfra connector types

    3.x

    Connectors in pyinfra allow integration with external tools and fall into three functional categories:

    1. Command Execution: Implement how commands are executed on a target (e.g., @ssh, @local).
    2. Inventory Generation: Generate inventory hosts and data (e.g., @terraform, @vagrant).
    3. Hybrid: Perform both command execution and inventory generation (e.g., @docker, @podman).
  2. Understand pyinfra versioning and semver rules

    3.x

    pyinfra follows semantic versioning (semver) rules to provide compatibility guarantees:

    • Major versions: Contain breaking changes. Warnings for these changes will appear in the latest previous major version.
    • Minor versions: Introduce new operations, new APIs, and new global arguments. They may also include deprecation warnings.
    • Patch versions: Include bug fixes, documentation updates, and new arguments for existing operations.
  3. Understand Declarative vs Imperative Operations

    3.x

    pyinfra operations fall into two categories:

    • Declarative: Describes an end state (e.g., apt.packages, files.file, server.user). pyinfra checks the current state of the host first and only executes commands if the host does not match the target state. Re-running a deploy where nothing has drifted results in a no-op.
    • Imperative: Tells pyinfra to run a specific command unconditionally (e.g., server.shell, server.script, python.call). These always execute.

    Use declarative operations for most tasks to ensure idempotency.

  4. Use the pyinfra CLI for deployments and ad-hoc tasks

    3.x

    The pyinfra CLI is used to manage remote servers by providing an inventory and one or more operations.

    Basic Syntax: pyinfra [OPTIONS] INVENTORY OPERATIONS...

    Inventory types:

    • A Python file (e.g., inventory.py)
    • A hostname (e.g., host.net)
    • Comma-separated hostnames (e.g., host-1.net,host-2.net,@local)

    Common Task Patterns:

    • Run a deploy: Execute a Python deployment script.
    • Run a single operation: Execute a specific operation module directly.
    • Execute shell commands: Use exec to run arbitrary commands.
    • Run facts: Use fact to collect information from hosts.
    • Debug inventory: Use debug-inventory to inspect hosts and groups.
    # 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]...
    
    # Debug (print) inventory hosts, groups and data
    pyinfra INVENTORY debug-inventory
  5. Execute ad-hoc shell commands and operations

    3.x

    Pyinfra allows running shell commands or specific operation modules directly from the CLI without a deployment script.

    Shell Commands: Use exec -- to pass commands. Everything after the -- is passed directly to the target host. This is useful for real-time debugging, such as streaming logs.

    Built-in Operations: You can call operation modules (e.g., apt.packages, init.service) directly by passing their arguments as CLI arguments.

  6. Install pyinfra using uv (Recommended)

    3.x

    If you use uv, you can install pyinfra either as a standalone tool or as a dependency within a specific project.

    To install it as a global tool:

    uv tool install pyinfra

    To add it to your current project's dependencies:

    uv add pyinfra
    uv tool install pyinfra
  7. Create an inventory file

    3.x

    An inventory file is a Python file containing groups of hosts defined as list or tuple. Group names cannot start with an underscore (_).

    When you run pyinfra inventory.py OPERATIONS..., pyinfra automatically creates:

    • An all group containing every host.
    • A group named after the filename (e.g., hosts in inventories/production.py belong to the production group).

    Note: Files in the inventories/ directory are not automatically joined; they are a convention for organizing multiple related inventories.

    app_servers = [
        "app-1.net",
        "app-2.net"
    ]
    
    db_servers = (["db-1.net", "db-2.net", "db-3.net"], {})
  8. Install pyinfra on BSD

    3.x

    When installing on BSD, you must set specific environment variables to prevent gevent from building embedded versions of certain libraries. You must have c-ares, libev, and libuv installed on your system.

    Example using uv:

    env C_INCLUDE_PATH='/usr/local/include/' \
        GEVENTSETUP_EMBED_CARES=0 \
        GEVENTSETUP_EMBED_LIBEV=0 \
        GEVENTSETUP_EMBED_LIBUV=0 \
        uv tool install pyinfra
    env C_INCLUDE_PATH='/usr/local/include/' \
        GEVENTSETUP_EMBED_CARES=0 \
        GEVENTSETUP_EMBED_LIBEV=0 \
        GEVENTSETUP_EMBED_LIBUV=0 \
        uv tool install pyinfra
  9. Register a custom connector via pyproject.toml

    3.x

    To make pyinfra aware of your custom connector, add an entry point to your project's pyproject.toml file using the pyinfra.connectors group.

    [project.entry-points.'pyinfra.connectors']
    # Key = Entry point name
    # Value = module_path:class_name
    custom = 'pyinfra_custom_connector.connector:LoggingConnector'
  10. Use the pyinfra Core API to execute operations

    3.x

    To use pyinfra as a library rather than a CLI tool, follow this three-step workflow:

    1. Initialize State: Create an Inventory (containing Host objects and data), a Config (for global flags), and a State object that combines them.
    2. Define Operations: Use pyinfra.api.operation.add_op or pyinfra.api.add_deploy to define the tasks to be performed.
    3. Execute: Run the defined operations using pyinfra.api.operations.run_ops.
  11. Upgrade pyinfra from 1.x to 2.x

    3.x

    When upgrading from version 1.x to 2.x, note the following changes:

    1. Python Version Requirements: Python 2.7 and Python 3.5 support have been dropped. Python 3.6 is the minimum required version.
    2. Working Directory: The "deploy directory" concept has been removed. pyinfra now executes from the current working directory. To set a specific working directory before execution, use the new --chdir CLI flag.