0

It might look silly to have several scripts instead of just one, but there are a reasons for it.

  • Modularity and reusable code: I have different deployment scripts that make use of the same task-related sub-scripts.

  • Security: One of those task-related scripts is the one that exports the keys of my application as OS environment variables. You are supposed to ask the admin for that script (It is out of version control for security reasons) and copy paste it where you are told before the deployment. That's easier and cleaner than copy-pasting its code at a certain line of a gigantic script with duplicated code.

This is the script that works for me currently. The problem I want to solve is that I have to enter the ssh password several times (5 in this case) and I would like to do it just once at the beginning:

#!/usr/bin/env bash

set -e

PROJECT_PARENT_DIR=/srv/webapps
PROJECT_DIR_NAME=example
PROJECT_REPO_URL=https://github.com/user/example.git
VIRTUALENV_PARENT_DIR=/srv/virtualenvs
VIRTUALENV_DIR_NAME=example

ssh root@serverip "bash -s" < setup/download_project.sh $PROJECT_PARENT_DIR $PROJECT_DIR_NAME $PROJECT_REPO_URL
ssh root@serverip "bash -s" < setup/create_virtualenv.sh $VIRTUALENV_PARENT_DIR $VIRTUALENV_DIR_NAME
ssh root@serverip "bash -s" < setup/export_production_keys.sh production $VIRTUALENV_PARENT_DIR $VIRTUALENV_DIR_NAME
ssh root@serverip "bash -s" < setup/configure_project.sh production $PROJECT_PARENT_DIR $PROJECT_DIR_NAME $VIRTUALENV_PARENT_DIR $VIRTUALENV_DIR_NAME
ssh root@serverip "bash -s" < setup/configure_server.sh production $PROJECT_PARENT_DIR $PROJECT_DIR_NAME $VIRTUALENV_PARENT_DIR $VIRTUALENV_DIR_NAME

echo -e "\e[32mPRODUCTION DEPLOYMENT IS FINISHED! LISTENING AT http://example.com\e[0m"
echo ""

I was not able to find a similar question/answer on Stack Overflow or other internet sources to help me with this.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
  • [`man ssh-keygen`](https://www.freebsd.org/cgi/man.cgi?query=ssh-keygen) and [`man ssh-agent`](https://www.freebsd.org/cgi/man.cgi?query=ssh-agent). Also, consider learning about [Chef](https://www.chef.io/), [cfengine](http://cfengine.com/), [Puppet](https://puppetlabs.com/) or [Saltstack](http://saltstack.com/). – ghoti Aug 20 '15 at 18:36
  • Also, and I speak from personal experience, you might want to avoid doing this sort of thing as root. Run your deploys as an unprivileged user, setting only the permissions required to get your project live. An accidental scripting error can hose a server MUCH more easily if it runs as root. – ghoti Aug 20 '15 at 18:42
  • This might be possible with a Here Document. http://stackoverflow.com/a/3872762/5174237 http://tldp.org/LDP/abs/html/here-docs.html – jwde Aug 20 '15 at 19:07
  • @ghoti Thanks for the advice, I already have some stuff done with Vagrant and Puppet is the next step I'm going to take. This is the script I use to configure the server from scratch and it is meant to be executed only once on a clean server. For regular deployments I have another script with an application-specific user and different tasks. But the problem above applies on both. – Carlos Ruiz Lantero Aug 20 '15 at 19:12

1 Answers1

0

Create a script on the server side that receives all the variables, then have that single script invoke all the others.

Remake your script on client side to receive the 10 variables you pass in. So you run the ssh command once, typing the password once, passing all the variables in one shot. Then the rest is done on the server side.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335