diff --git a/scripts/deploy.js b/scripts/deploy.js
index 5e0943d6e0845a00ebbcedf6cd7a0b1940f088c2..dee25d15346a28d1a13902c380a31401cfe9d029 100755
--- a/scripts/deploy.js
+++ b/scripts/deploy.js
@@ -4,7 +4,9 @@ const
 aws = require('./deploy/aws.js');
 path = require('path');
 vm = require('./deploy/vm.js'),
-key = require('./deploy/key.js');
+key = require('./deploy/key.js'),
+ssh = require('./deploy/ssh.js'),
+git = require('./deploy/git.js');
 
 var verbs = {};
 
@@ -15,17 +17,47 @@ function checkErr(err) {
   }
 }
 
+function printInstructions(name, deets) {
+  console.log("Yay!  You have your very own deployment.  Here's the basics:\n");
+  console.log(" 1. deploy your code:  git push " + name + " <mybranch>:master");
+  console.log(" 2. visit your server on the web: https://" + name + ".hacksign.in");
+  console.log(" 3. test via a website: http://" + name + ".myfavoritebeer.org");
+  console.log(" 4. ssh in with sudo: ssh ec2-user@" + name + "hacksign.in");
+  console.log(" 5. ssh as the deployment user: ssh app@" + name + "hacksign.in\n");
+  console.log("enjoy!  Here's your server details", JSON.stringify(deets, null, 4));
+}
+
 verbs['deploy'] = function(args) {
   if (!args || args.length != 1) {
     throw 'missing required argument: name of instance';
   }
-
+  var name = args[0];
+  if (!/^[a-z][0-9a-z_\-]+$/.test(name)) {
+    throw "invalid name!  must be a valid dns fragment ([z-a0-9\-_])";
+  }
+  console.log("attempting to set up " + name + ".hacksign.in");
+      
   vm.startImage(function(err, r) {
     checkErr(err);
-    vm.waitForInstance(r.instanceId, function(err, r) {
+    console.log("   ... VM launched, waiting for startup (should take about 20s)");
+    vm.waitForInstance(r.instanceId, function(err, deets) {
       checkErr(err);
+      console.log("   ... Instance ready, setting name");
       vm.setName(r.instanceId, args[0], function(err) {
-        console.log(err, r);
+        checkErr(err);
+        console.log("   ... name set, waiting for ssh access and configuring");
+        var config = { public_url: "https://" + name + ".hacksign.in"};
+
+        ssh.copyUpConfig(deets.ipAddress, config, function(err, r) {
+          checkErr(err);
+          console.log("   ... victory!  server is accessible and configured");
+          git.addRemote(name, deets.ipAddress, function(err, r) {
+            checkErr(err);
+            console.log("   ... and your git remote is all set up");
+            console.log("");
+            printInstructions(name, deets);
+          });
+        });
       });
     });
   });
diff --git a/scripts/deploy/git.js b/scripts/deploy/git.js
new file mode 100644
index 0000000000000000000000000000000000000000..34b88c26be8b74f78d8b546da26ea7e99759de5b
--- /dev/null
+++ b/scripts/deploy/git.js
@@ -0,0 +1,7 @@
+const
+child_process = require('child_process');
+
+exports.addRemote = function(name, host, cb) {
+  var cmd = 'git remote add ' + name  + ' app@'+ host + ':git';
+  child_process.exec(cmd, cb);
+};
diff --git a/scripts/deploy/ssh.js b/scripts/deploy/ssh.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f76461c1520dc2ef8548c49513522a9bb7cbbc0
--- /dev/null
+++ b/scripts/deploy/ssh.js
@@ -0,0 +1,26 @@
+const
+child_process = require('child_process'),
+temp = require('temp'),
+fs = require('fs');
+
+const MAX_TRIES = 20;
+
+exports.copyUpConfig = function(host, config, cb) {
+  var tries = 0;
+  temp.open({}, function(err, r) {
+    fs.writeFileSync(r.path, JSON.stringify(config, null, 4));
+    var cmd = 'scp -o "StrictHostKeyChecking no" ' + r.path + ' app@' + host + ":config.json";
+    function oneTry() {
+      child_process.exec(cmd, function(err, r) {
+        if (err) {
+          if (++tries > MAX_TRIES) return cb("can't connect via SSH.  stupid amazon");
+          console.log("   ... nope.  not yet.  retrying.");
+          setTimeout(oneTry, 5000);
+        } else {
+          cb();
+        }
+      });
+    }
+    oneTry();
+  });
+};