Fabric is a Python library used to streamline and automate ssh workflows. It can be very useful in automating and scripting tedious, repetitive or complex tasks, deployments, installations and configurations on remote servers.
In this article we introduce Fabric, and show how to automate deployment of a Flask web app to Alibaba Cloud Elastic Compute Service.
Fabric - the introduction
Fabric is a tool which we can use to deploy or sync our local projects to remote server. We can also automate all operations we can achieve through SSH - we can configure our server, install or update our software stack, start, stop, update or restart our application.
This article presumes that the reader already created and configured a server on Alibaba Cloud to serve a Flask web app, and that it is operational.
In this blog post we can find a full guide to set up Ubuntu server on Alibaba ECS to serve a Flask app. If we follow this guide, our app will live under /var/www/flaskapp (we will use flaskapp
for the directory name here, but it can be changed to anything else).
According to the linked guide, our flaskapp will contain two files - uwsgi.ini and app.py.
Deployment Setup
App.py file will contain something basic, like this:
from flask import Flask
application = Flask(__name__)
@application.route('/')
def hello_world():
return 'Hello World!'
Now, to streamline our deployment, we will presume the same document structure both on our local development machine and on the server. We also presume that on our local machine we are using bash command line or something similar - on MS Windows we will use WSL shell.
If we start our (very basic) app locally, by doing flask run
in our flaskapp
directory, we will get a simple Hello World!
web page on our localhost:
Now we need to install fabric - we need only to install it locally, our production or development servers don't need anything installed:
pip install fabric
Depending on the OS we are running, we may also be able to install it with
sudo apt-get install fabric
Fabric dependencies are the Python versions 2.7 or 3.4+; Invoke task-execution library;
and Parmiko SSH library. Once we install fabric, we should be able to run the fab
command in our terminal:
As we can see, fab
command will immediately complain about the (lack of) presence of the fabfile
in the current directory, which should contain configuration and instructions for fabric to run its commands.
We will cd
into the parent directory of our flaskapp
project, and create our fabfile
. Fabfile is a simple python file with some imports, variables, and function definitions:
import sys
from fabric2 import Connection, task
from fabric2.config import Config
PROJECT_NAME = "fabtut"
REMOTE_PATH = "/var/www/flaskapp"
LOCAL_PATH = "/var/www/flaskapp"
def get_connection(ctx):
try:
with Connection(ctx.host, ctx.user, connect_kwargs=ctx.connect_kwargs) as conn:
return conn
except Exception as e:
return None
@task
def staging(ctx):
ctx.user = "root"
ctx.host = "xxx.xxx.xxx.xxx"
ctx.connect_kwargs.key_filename = "/home/user/.ssh/id_rsa"
@task
def production(ctx):
ctx.user = "root"
ctx.host = "yyy.yyy.yyy.yyy"
ctx.connect_kwargs.key_filename = "/home/user/.ssh/id_rsa_2"
@task
def push(ctx):
ctx.run("rsync -avzh --exclude '.git' -e 'ssh -i {}' {}/ {}@{}:{}/".format(ctx.connect_kwargs.key_filename, LOCAL_PATH, ctx.user, ctx.host, REMOTE_PATH))
@task
def pull(ctx):
ctx.run("rsync -avzh -e 'ssh -i {}' {}@{}:{}/ {}/".format(ctx.connect_kwargs.key_filename, ctx.user, ctx.host, REMOTE_PATH, LOCAL_PATH))
Once we save this file, in the same directory we can run fab staging push
and our local flaskapp directory will be synced with the one on our staging ECS server from Alibaba.
Some Notes About the Setup
For this guide to work, our fabfile
will need to contain real IP addresses in ctx.host
variables in the staging
and production
functions.
In this fabfile example we show one of the Fabric features - we can set up multiple environments, from development to staging and production.
We can also use multiple SSH keys for multiple server environments.
This setup also demonstrates how we can chain and combine commands, so in our case we can use staging
and production
interchangeably and combine them with pull
or push
as needed.
We could also define other tasks (in the fabfile we decorate them with @task
decorator), whether to preform some preliminary tasks localy or on the server, or to do some cleanup after the main task.
If we were working with Django framework, we could here define tasks to perform migrations, or, if our tasks alter the web / application server configuration, we could restart or reload the server after our task is finished.
Chaining of tasks comes handy here, and allows for defining very declarative and high-level workflows.
Since we rely on ssh authentication in this guide, we will need to have loaded our ssh public key on the ECS server. Alibaba Cloud has more documentation on how to set up SSH authentication here.
Conclusion
In this short guide, we set up Fabric deployment tool to define deployment workflows to Alibaba ECS server, and we explain how to work with Fabric. We use bash syntax combined with rsync
here, but we could be using any other linux commands like awk, sed, etc.
Fabric itself allows even more declarative workflows, but we find that using linux & bash commands allows for much greater flexibility and more sophisticated workflows.
Do you have anything to add to this? Let us know in the comments.
Top comments (0)