Fabric tutorial 3 – Settings and roles

In this tutorial I’m going to concentrate on various different settings you can use in your fabfile.
These settings can be added to your environmental variables, as decorators or inside the tasks. With roles
we can define which machines are for example servers and which are workstations.

I hope you’ve also read previous tutorials 1 & 2:
http://awaseroot.wordpress.com/2012/04/23/fabric-tutorial-1-take-command-of-your-network/
http://awaseroot.wordpress.com/2012/04/25/fabric-tutorial-2-file-transfer-error-handling/

Environmental variables

Your default settings should be in the environmental variables right in the beginning of your fabfile.
These are the settings that are used in all of your tasks unless you define it otherwise. These
are the settings that we’ll modify in our tasks later. We have used these in the previous tutorials.

fabfile.py

env.hosts=["simo@10.10.10.10","webserver.local"]
env.user="hng"
env.password="password"
env.parallel=True
env.skip_bad_hosts=True
env.timeout=1
env.warn_only=True

You can find the full list of environmental variables from the official documentation here:
http://docs.fabfile.org/en/1.4.1/usage/env.html#full-list-of-env-vars

So every time we run a task, these environmental variables are used.

Decorators

We can use decorators to use a specific env. variable in a task. They’re used by adding @decorator above
the task.

@with_settings(warn_only=True)
@hosts("10.10.10.10")
def install(package="geany"):
    sudo("apt-get install %s" % package)

Now the install task would run only on host 10.10.10.10 and with the warn_only setting.

With decorators you can also separate tasks from normal functions:

@task
def cmd(cmd):
    run(cmd)

Now fab -l or fab –list would only show the tasks that have the @task decorator on them.

Full list of decorators can be found from the official documentation here:
http://docs.fabfile.org/en/1.4.1/api/core/decorators.html

Changing settings inside a task

You can change the settings inside a task by using “with settings” like this:

env.hosts=["10.10.10.10","webserver.local"]

def test():
    with settings(user="simo",host_string="webserver.local"):
        run("whoami")
    run("pwd")

Now whoami would be ran on webserver twice with user simo. The command pwd would be ran on 10.10.10.10
and webserver.local. The whoami is ran twice because the “with settings” part effects both hosts that the
task is run on. When it runs on 10.10.10.10 the setting tells Fabric to run the task on webserver instead.
Same happens on webserver so the command runs again.

You can also use “with cd” or “with lcd” to specify where your commands should be run.

def ssh_conf_backup():
    with cd("/etc/ssh/"):
        sudo("cp -b ssh_config ssh_config")

Use lcd instead of cd for local paths.

More information about settings can be found here:
http://docs.fabfile.org/en/1.4.1/api/core/context_managers.html#fabric.context_managers.settings

Roles

You can specify certain roles for your hosts also in the env. variables. This way you can run server
specific tasks on all of your servers while leaving workstations alone.

env.hosts=["10.10.10.10","webserver.local"]
env.roledefs={"server":["webserver.local"],"workstation":["10.10.10.10"]}

And you can use decorators to specify which tasks are ran on which roles.

@roles("server")
def apache():
    sudo("apt-get update")
    sudo("apt-get install -y apache2")
    sudo("a2enmod userdir")

You can also create a specific task to manage your hosts and settings. This way different settings are
easy to use with your tasks.

def test():
    env.hosts=["10.10.10.10"]
    env.user="test"
    env.warn_only=True
    env.parallel=True

def production():
    env.hosts=["webserver"]
    env.skip_bad_hosts=True

Now you can use these different env. variable settings in your tasks by running them like this:
fab test install:apache2
fab production install:apache2

So you can use different settings with same tasks by just running the task with the settings with the
actual task.

The fabfile for this tutorial:

fabfile.py

from fabric.api import *

env.hosts=["simo@10.10.10.10","webserver.local"]
env.roledefs={"server":["webserver.local"],"workstation":["10.10.10.10"]}
env.user="hng"
env.password="password"
env.parallel=True
env.skip_bad_hosts=True
env.timeout=1
env.warn_only=True

@with_settings(warn_only=True)
@hosts("10.10.10.10")
def install(package="geany"):
    sudo("apt-get install %s" % package)

@task
def cmd(cmd):
    run(cmd)

def test():
    with settings(user="simo",host_string="webserver.local"):
        run("whoami")
    run("pwd")

def ssh_conf_backup():
    with cd("/etc/ssh/"):
        sudo("cp -b ssh_config ssh_config")

@roles("server")
def apache():
    sudo("apt-get update")
    sudo("apt-get install -y apache2")
    sudo("a2enmod userdir")

def test():
    env.hosts=["10.10.10.10"]
    env.user="test"
    env.warn_only=True
    env.parallel=True

def production():
    env.hosts=["webserver"]
    env.skip_bad_hosts=True

Leave a comment if you have any questions.

Sources
http://fabfile.org
http://docs.fabfile.org/en/1.4.1/usage/env.html#full-list-of-env-vars
http://docs.fabfile.org/en/1.4.1/api/core/decorators.html
http://docs.fabfile.org/en/1.4.1/api/core/context_managers.html#fabric.context_managers.settings

About these ads

4 responses to “Fabric tutorial 3 – Settings and roles

  1. Pingback: Fabric tutorial 2 – File transfer & error handling « awaseroot

  2. hack4geek January 22, 2013 at 1:02 pm

    Awesome tutorial. It convers most the use cases :)
    Thanks a lot dude

  3. Joe May 4, 2013 at 8:58 am

    Thanks man. Clean, concise and effective explanations.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: