title: How to dynamically edit env.roledefs in Fabric?
body: <p>I have checked <a href="https://stackoverflow.com/questions/2326797/how-to-set-target-hosts-in-fabric-file">this question</a> but it doesn't answer to my problem.</p>
  
  <p>I would like to do something like:</p>
  
  <pre><code>@task
  def setEnv(environment):
      if environment == 'prod':
          env.roledefs['nginx'] = [ 'www@tnginx01', 'www@tnginx02' ]
          env.roledefs['middle'] = [ 'www@tmiddle01', 'www@tmiddle02' ]
      elif environment == 'preprod':
          env.roledefs['nginx'] = [ 'www@pnginx01', 'www@pnginx02' ]
          env.roledefs['middle'] = [ 'www@pmiddle01', 'www@pmiddle02' ]
      else:
          puts(red("This environment doesn't exist. Possible values are 'preprod' and 'prod'", True))
          sys.exit()
  
      env.first_middle = env.roledefs['middle'][0]
  
  @task
  @roles(env.first_middle)
  def deploy():
      run('pwd')
  </code></pre>
  
  <p>But it seems that it's not possible to change the value of env.roledefs after the Fabfile has been loaded into memory.
  When you try to run <code>fab setEnv:prod deploy</code>, it won't work: </p>
  
  <blockquote>
    <p>No hosts found. Please specify (single) host string for connection</p>
  </blockquote>
  
  <p>Does anyone know how to do that? Note that I cannot use roledefs to represent environments. I already use roledefs to store servers belonging to a same 'cluster', and each environment has several clusters with several servers.</p>