I want to use Fabric to deploy my web app code to development, staging and production servers. My fabfile:
def deploy_2_dev():
deploy(\'dev\')
def deploy_
I do this by declaring an actual function for each environment. For example:
def test():
env.user = 'testuser'
env.hosts = ['test.server.com']
def prod():
env.user = 'produser'
env.hosts = ['prod.server.com']
def deploy():
...
Using the above functions, I would type the following to deploy to my test environment:
fab test deploy
...and the following to deploy to production:
fab prod deploy
The nice thing about doing it this way is that the test
and prod
functions can be used before any fab function, not just deploy. It is incredibly useful.
Contrary to some other answers, it is possible to modify the env
environment variables within a task. However, this env
will only be used for subsequent tasks executed using the fabric.tasks.execute
function.
from fabric.api import task, roles, run, env
from fabric.tasks import execute
# Not a task, plain old Python to dynamically retrieve list of hosts
def get_stressors():
hosts = []
# logic ...
return hosts
@task
def stress_test():
# 1) Dynamically generate hosts/roles
stressors = get_stressors()
env.roledefs['stressors'] = map(lambda x: x.public_ip, stressors)
# 2) Wrap sub-tasks you want to execute on new env in execute(...)
execute(stress)
# 3) Note that sub-tasks not nested in execute(...) will use original env
clean_up()
@roles('stressors')
def stress():
# this function will see any changes to env, as it was wrapped in execute(..)
run('echo "Running stress test..."')
# ...
@task
def clean_up():
# this task will NOT see any dynamic changes to env
Without wrapping sub-tasks in execute(...)
, your module-level env
settings or whatever is passed from the fab
CLI will be used.
I'm totally new to fabric, but to get fabric to run the same commands on multiple hosts (e.g. to deploy to multiple servers, in one command) you can run:
fab -H staging-server,production-server deploy
where staging-server and production-server are 2 servers you want to run the deploy action against. Here's a simple fabfile.py that will display the OS name. Note that the fabfile.py should be in the same directory as where you run the fab command.
from fabric.api import *
def deploy():
run('uname -s')
This works with fabric 1.8.1 at least.