Fabric Basics

Fabric is a Python package which may be used along with SSH to run commands on (and copy files to) a target machine, among other things.

The idea is to install Fabric (and related things) to your local/dev machine, and from there you can run Fabric commands as needed to build out various other machines. Fabric will connect to each machine over SSH and then execute shell commands, copy files etc.

The target machine need not run any special service for this to work. It’s just like you connected to the target machine via SSH and then ran commands manually, only this way is (ideally) automated and self-documenting.

Supported Platforms

There are two “sides” to the equation, which must be addressed separately.

Your local (e.g. dev) machine is where you’ll run Fabric itself. This machine must have Python 3 installed, and must be able to make SSH client connections to other machines.

Todo

I believe it should be possible to do this on Windows, but I’ve not tried as I only use Linux desktop.

Should confirm if it works on Windows; maybe document setup.

The target machine however is in all cases assumed to be Linux, either Debian or Ubuntu. It must run a SSH service.

Note

Fabric supports more target platforms than just Debian/Ubuntu; most likely anything with SSH would work. But within the Rattail Project those are the only 2 being used in production.

Note about Versions

TL;DR - we use fabric2 instead of just fabric, to be explicit

Fabric v1 was created when Python 2 was prevalent. Later on, Python 3 became prevalent, and Fabric v2 came out to support that.

Fabric v2 is a total rewrite and not compatible with v1. If you’re just getting started you’ll use only v2 and will not need to know about v1.

But for historical reasons, the Rattail Project still supports both versions of Fabric.

Because of this background, and to be extra clear which version of Fabric is in use, the Rattail Project uses the name fabric2 when referencing Fabric v2 in code etc.

For more on this see the following Fabric docs:

The fab2 command

When using Fabric to operate on a target machine, you will - on your (local) machine - run one or more fab2 commands.

Each fab2 command specifies a particular task, which is defined in your fabfile.py (see below).

The command also specifies which machine it should act on. Fabric then will connect to the machine via SSH, and execute the task logic on the target machine.

For example, to run the bootstrap_all task on “myserver” might be:

fab2 -e -H myserver.example.com bootstrap-all

Note that even though the task is actually (in Python) named bootstrap_all, it must be specified with hyphen as bootstrap-all on the fab2 command line.

Also note the -e (--echo) flag which causes Fabric to emit (to local STDOUT) the full command being ran on the target machine, as it goes along. (Most tasks execute several commands on the target machine, so this can be helpful to make sense of output.)

The “fabfile”

Fabric is rather flexible but here in the Rattail Project we’ll set some guidelines for usage, for simplicity’s sake.

When running the fab2 command, there should be a file named fabfile.py in the current directory.

This “fabfile” will contain a number of “tasks” - each of which may contain multiple commands to be ran on the target machine, etc.

In our context, normally one “fabfile” contains all task logic for building out a particular machine.

For more on how Fabric locates the fabfile (and therefore, tasks), see https://docs.fabfile.org/en/stable/cli.html#seeking-loading-tasks

A simple yet complete fabfile.py example:

from fabric2 import task

@task
def hello_world(c):

    # nb. this runs locally on *your* machine
    print("hello world")

    # nb. this runs on target machine
    c.run('bash -c "echo my name is `whoami`"')

This contains one task, but as you can see does not specify which machine it targets. You always must specify that yourself when running fab2 commands.

rattail-fabric2

Rattail offers some utilitiy functions for use with Fabric, in rattail-fabric2.

The “machine bundle”

The general idea then, is for you to create and maintain a “fabric bundle” for each machine you wish to manage in this way. Bundles are described elsewhere, but the gist is, they contain all necessary commands and config files to build out the machine.

See Machine Bundles for more about these.