1

Is it possible to force the user to enter their password when they deploy to production?

I was deploying to staging, but accidentally hit tab on the CL to production instead and almost made a huge mistake! Needless to say I will never use autocomplete for fab ... ever ever again.

UPDATE:

Below is what our fabfile essentially looks like. Each host, like application-staging or application-production, is saved in the ssh config.

from fabric import colors
from fabric.api import *
from fabric.contrib.project import *

import git

env.app = '{{ project_name }}'
env.dest = "/var/www/%(app)s" % env
env.use_ssh_config = True

def reload_processes():
    sudo("kill -HUP `cat /tmp/%(app)s.pid`" % env)

def sync():
    repo = git.Repo(".")
    sha = repo.head.commit.hexsha
    with cd(env.dest):
        run("git fetch --all")
        run("git checkout {} -f".format(sha))

    if "production" in env.host_string:
        with cd(env.dest):
            run("compass compile")

            with prefix(". /home/ubuntu/environments/%(app)s/bin/activate" % env):
                run("%(dest)s/manage.py syncmedia" % env)

def deploy():
    sync()
    link_files()
    reload_processes()
    add_commit_sha()

def link_files():
    print(colors.yellow("Linking settings."))
    env.label = env.host_string.replace("%(app)s-", "")
    with cd(env.dest):
        sudo("rm -f local_settings.py")
        sudo("ln -s conf/settings/%(label)s.py local_settings.py" % env)

        sudo("rm -f conf/gunicorn/current.py")
        sudo("ln -s %(label)s.py conf/gunicorn/current.py" % env)

        sudo("rm -f celeryconfig.py")
        sudo("ln -s conf/settings/celery/%(label)s.py celeryconfig.py" % env)

        sudo("rm -f conf/supervisor/programs.ini" % env)
        sudo("ln -s %(label)s.ini conf/supervisor/programs.ini" % env)

def reload_processes(reload_type="soft"):
    print(colors.yellow("Reloading processes."))

    env.label = env.host_string.replace("%(app)s-", "")
    with cd(env.dest):
        sudo("kill -HUP `cat /tmp/gunicorn.%(app)s.%(label)s.pid`" % env)

def add_commit_sha():
    repo = git.Repo(".")
    sha = repo.head.commit.hexsha
    sed("{}/settings.py".format(env.dest), "^COMMIT_SHA = .*$", 'COMMIT_SHA = "{}"'.format(sha), backup="\"\"", use_sudo=True)
tzenderman
  • 2,523
  • 3
  • 21
  • 24

2 Answers2

0

I mean yeah. You could remove all of their ssh keys and make them use passwords every time. You could also use stdlib prompts to ask the user if they meant production. You can also have only certain users write to production using basic ACLs. There are any number of ways of slowing the deployment process down, it's mostly going to come down to what you and your devs prefer.

Morgan
  • 4,143
  • 27
  • 35
0

I use this pattern, where you set up the staging/prod configurations in their own tasks:

@task
def stage():
  env.deployment_location = 'staging'
  env.hosts = ['staging']

@task
def prod():
  env.deployment_location = 'production'
  env.hosts = ['prod1', 'prod2']

@task
def deploy():
  require('deployment_location', used_for='deployment. \
  You need to prefix the task with the location, i.e: fab stage deploy.')

  confirm("""OK. We're about to deploy to:

    Location: {env.deployment_location}

    Is that cool?""".format(env=env))

  # deployment tasks down here

In this case, you have to type fab prod deploy and say yes to the confirmation message in order to deploy to production.

Just typing fab deploy is an error, because the deployment_location env variable isn't set.

It doesn't prevent total idiocy, but it does prevent accidental typos and so far it's worked well.

Rachel Sanders
  • 5,734
  • 1
  • 27
  • 36
  • Nice, I didn't know about require(), looking into it now. Question: why do you define your fabric functions as celery tasks? I have actually tried that for something else and wasn't able to make it work... – tzenderman Aug 06 '13 at 23:24
  • Oh sorry, they're not Celery tasks, Fabric has a @task decorator to mark tasks that can be run by themselves: http://fabric.readthedocs.org/en/1.7/api/core/decorators.html#fabric.decorators.task – Rachel Sanders Aug 07 '13 at 23:04
  • Sometimes I just want to run the build part, or just the deployment part (and so on) and by marking the function with @task I can. – Rachel Sanders Aug 07 '13 at 23:07
  • Cool, I didn't know about those. I'm accepting your answer as it led me in the right direction. Thanks! – tzenderman Aug 08 '13 at 16:22