Streamline Deployments With Fabric
Fabric can execute system commands on your local computer where fabric is installed, and also can execute commands on remote computers via normal SSH connection.
for a typical use case, normally when I am working with a project and it’s time to deploy an update, I do the following:
- I commit and push the changes to github
- connect to the production server via SSH
- navigate to the project folder
- pull changes from the github repository
- backing up databases to some folder (when critical changes)
- do the migrations
- updating static files
- … (other tasks depending on the project)
this process becomes very boring and slows you down from doing the creative work
imagine if you can automate all that with something like a wizard on your local computer. fabric let’s you build that wizard.
let’s install and use this awsome tool to demonstrate all this.
Installation
I’ll be using a linux machine for this demonstration (specificly Ubuntu 16.04), but you can use Windows also.
you can install using the ubuntu apt-get command:
sudo apt-get install fabric
or using the python package manager, pip (you’ll need pip installed):
pip install fabric
that’s all, fabric is now setup and installed.
Usage
Now, in your projects directory, (whatever type of project). you create a file and name it fabfile.py. inside this python scripy you define a group of Tasks however you like.
take a look at the follwing code block as it represents the simplist fabfile:
from fabric.api import * def reboot_server(): pass def another_task(argument=''): pass
and then to run a specific task (rebooting a remote server for example), from the linux console run:
fab reboot_server
you can also give it some custom arguments and read them inside the script:
fab another_task argument:"some_value"
and this will execute that specific task.
Note: the fabfile.py file is best placed at the root directory of your project.
and how exactly to write the fabfile.py?, keep reading.
Fabric Operations
to implement the fabric tasks you’ll need a set of operations provided by the fabric.operations module. some of the most used ones include:
run
result = run("ls ~/project")
this will execute the provided command string to a remote server (will use an SSH connection), and will return a string as the console output from the command. this string will also expose the following attributes:
result.failed
(True if failed)
result.succeeded
(True if executed without errors)
result.command
(the actual run command)
sudo
result = sudo("apt-get install cowsay")
very similar to run, but executes the command with sudo privileges, and also returns the console output.
local
local(ls ~/project")
similar to run, but the execution happens at the local computer (running fabric). and doesn’t return the console output
local is built on top of a python module called “subprocess”, to do more advanced execution on the local computer consider using subprocess.
these are the most used commands, however you can find many more usefull commands like … and others form the official fabric documentation
Fabric Context Managers
Context managers are helpers you can use when writing the fabric script, the most used ones are, cd, lcd and settings. context managers live in the fabric.context_managers module. to demonstrate thier usage, take a look at the following examples:
fabric.context_managers.cd
: this will change the state of the current directory of the remote server, and each operation inside it's block code will be prefixed by "cd <path>".
so instead of saying:
run('cd /var/www') run('ls') run('mkdir dir')
you can do it like this:
with cd('/var/www'): run('ls') # Turns into "cd /var/www && ls" run('mkdir dir') # Turns into "cd /var/www && mkdir dir"
fabric.context_managers.lcd
: this will operate just like cd, but on the local computer, so within the wrapped block you will use local for example and not run
Env Variables
The environment dictionary env is single dictionary object shared between all of your fabric tasks, it lives under fabric.state.env
, and is included in fabric.api
for convenience. you will mostly use this to set some variables for the working environment. variables like the username of the remote server, the password and list of remote hosts that fabric will execute upon.
these settings live under env.hosts[]
, env.user
and env.password
attributes.
to domonstrate all what you’ve learned so far, take a look at the following complete example fabfile:
from fabric.api import * env.hosts = [ 'www.example.com', # you can add other hosts as well ] # Set the username env.user = "username" # Set the password # it's not recommended to set passwords like this # you can configure an SSH connection, see fabric docs # env.password = "password" def first_task(): """ update the system packages """ run("sudo apt-get update") run("sudo apt-get -y upgrade") def second_task(): """ create 2 directories inside /var """ with cd('/var'): run('mkdir dir1') run('mkdir dir2')
The cool thing is that this script is written in python, on of the most diverse languages.
you can call both tasks from the command line like this:
fab first_task second_task
Conclusion
This article servers as a simple introduction to what fabric is and what is does. basically, you will benifit from using fabric if you have some repititive task that you can automate to cut time and not having to do work that a computer can do. however, there’s a lot more for fabric, and I advise you to take a look at thier own documentation. I will also be covering another related post that shows how to use fabric in a more professional and secure way. and by usign two files; the fabfile.py and a JSON file fabric.config.json, the later one I use to store some project configurations for fabric.