Multiple :app roles & deploy:setup

550 views
Skip to first unread message

jeyroz

unread,
Sep 28, 2010, 9:21:37 PM9/28/10
to Capistrano
Hello, I recently began experimenting with Capistrano. Deploying our
codebase to a single server (role :app, "ap-1") worked well, but once
I included a secondary application server to the list (role :app,
"ap-1", "ap-2"), things went sideways...

* executing `deploy:setup'
* executing "snip[...]"
servers: ["ap-1", "ap-2"]
Enter passphrase for /home/devuser/.ssh/id_dsa: Enter passphrase for /
home/devuser/.ssh/id_dsa:

You'll note the duplicate requests for a ssh-key "passphrase" in
succession. When provided, I'm prompted for it again, and again. If I
simply [enter] through the process numerous times, I receive the
following...

connection failed for: ap-1 (OpenSSL::PKey::DSAError: Neither PUB key
nor PRIV key:: nested asn1 error), ap-2 (NoMethodError: undefined
method `overwrite' for nil:NilClass)

Passphrase protected DSA keys are used to quickly log-in between all
of our servers. The "devuser" above has a public key registered as an
"authorized_key" with the "deployuser" used to deploy the application
on each server. The keys are set up appropriately and have been
verified. Again, I can successfully deploy to either server
individually using the users/keys in question, without issue, but not
both at once.

My deploy.rb file is embarrassingly simple at this point...

set :application, "appname"
set :repository, "http://domain.com/svn/appname/"
set :user, "deployuser"
set :use_sudo, false
set :scm, :subversion
set :scm_username, "svnuser"
set :scm_password, "svnpass"
set :deploy_to, "/path/to/#{application}"
role :app, "ap-1" # <= works
role :app, "ap-2" # <= works
role :app, "ap-1", "ap-2" # <= doesn't work

Any ideas where I have gone wrong at such an early stage?

Thanks for the help.

Best,

~ jeremy

jeyroz

unread,
Sep 29, 2010, 10:09:00 AM9/29/10
to Capistrano
To further clarify my deploy.rb example, the three "role" assignments
at the end have been applied exclusively. The final entry in the list
is the one that doesn't work.

# role :app, "ap-1" # <= works
# role :app, "ap-2" # <= works
role :app, "ap-1", "ap-2" # <= doesn't work

Thanks for the help and input.

~ jeremy

Rafael García

unread,
Sep 29, 2010, 10:39:42 AM9/29/10
to capis...@googlegroups.com
Try to write it as array[1].

  role :app, ["ap-1", "ap-2"]

Regards


--
* You received this message because you are subscribed to the Google Groups "Capistrano" group.
* To post to this group, send email to capis...@googlegroups.com
* To unsubscribe from this group, send email to capistrano+...@googlegroups.com For more options, visit this group at http://groups.google.com/group/capistrano?hl=en

jeyroz

unread,
Sep 29, 2010, 12:52:57 PM9/29/10
to Capistrano
Thanks for the suggestion Rafael. I attempted that as well (various
formats actually) but to no avail.

role :app, %w{ap-1, ap-2}
role :app, ["ap-1", "ap-2"]

Passing the nodes in as an array actually kicks back the following
error...
/path/to/gems/1.9.1/gems/capistrano-2.5.19/lib/capistrano/
server_definition.rb:16:in `initialize': undefined method `match' for
["ap-1", "ap-2"]:Array (NoMethodError)

Which led me to disregard the suggestion as I had seen several
different documented examples of ways to pass the nodes into "role".
The syntax I chose came from the docs below (also linked to from your
provided URI)...

-- From http://rdoc.info/github/capistrano/capistrano/master/Capistrano/Configuration/Roles
--
Usage:
snip[...]
role :app, "app1.example.com", "app2.example.com"
-- End --

That format seems to work (almost), aside from the pesky passphrase
requests and subsequent failure.
Am I missing something obvious?

Best,

~ jeremy
> > capistrano+...@googlegroups.com<capistrano%2Bunsubscribe@googlegrou ps.com>For more options, visit this group at
> >http://groups.google.com/group/capistrano?hl=en

jeyroz

unread,
Sep 29, 2010, 1:54:49 PM9/29/10
to Capistrano
The gentleman in the following StackOverflow post seems to have
experienced the same issue, however no helpful (permanent) resolution
exists...
http://stackoverflow.com/questions/2718314/capistrano-fails-for-multiple-host-deployments

Specifying the following does indeed allow all deployments to run
successfully, but the passphrase does need to be repeated for each
node.
default_run_options[:max_hosts] = 1

Using "ssh-agent" to cache my key passphrase alleviates the annoyance,
but only really covers up the core issue (about which I'm still
clueless).

Best,

~ j


On Sep 29, 9:52 am, jeyroz <jey.osb...@gmail.com> wrote:
> Thanks for the suggestion Rafael. I attempted that as well (various
> formats actually) but to no avail.
>
> role :app, %w{ap-1, ap-2}
> role :app, ["ap-1", "ap-2"]
>
> Passing the nodes in as an array actually kicks back the following
> error...
> /path/to/gems/1.9.1/gems/capistrano-2.5.19/lib/capistrano/
> server_definition.rb:16:in `initialize': undefined method `match' for
> ["ap-1", "ap-2"]:Array (NoMethodError)
>
> Which led me to disregard the suggestion as I had seen several
> different documented examples of ways to pass the nodes into "role".
> The syntax I chose came from the docs below (also linked to from your
> provided URI)...
>
> -- Fromhttp://rdoc.info/github/capistrano/capistrano/master/Capistrano/Confi...

Rafael García

unread,
Sep 29, 2010, 2:51:36 PM9/29/10
to capis...@googlegroups.com
I read badly your firsts emails, so sorry.

Could you test this task?

role :test_role, "ap-1", "ap-2"

desc "Execute task in all servers of a role"
task :role_with_several_servers, :roles => :test_role do
   run "uptime"
end

I executed it locally and worked fine. I'm trying to know why happen it.
* To unsubscribe from this group, send email to capistrano+...@googlegroups.com For more options, visit this group at http://groups.google.com/group/capistrano?hl=en

jeyroz

unread,
Sep 29, 2010, 3:38:54 PM9/29/10
to Capistrano
Thanks for the response, Rafael. Sure thing.

Executing that task with two nodes assigned to ":test_role" produced
the following...

* executing `role_with_several_servers'
* executing "uptime"
servers: ["ap-1", "ap-2"]
Enter passphrase for /home/devuser/.ssh/id_dsa: Enter passphrase for /
home/devuser/.ssh/id_dsa:
snip[...]
Enter passphrase for /home/devuser/.ssh/id_dsa:

connection failed for: ap-2 (OpenSSL::PKey::DSAError: Neither PUB key
nor PRIV key:: nested asn1 error), ap-1 (NoMethodError: undefined
method `overwrite' for nil:NilClass)


However, if I use ssh-agent to cache my passphrase, the task is
successful...

* executing `role_with_several_servers'
* executing "uptime"
servers: ["ap-1", "ap-2"]
[ap-1] executing command
[ap-2] executing command
** [out :: ap-2] 19:28:28 up 8 days, 18:54, 0 users, load average:
0.00, 0.00, 0.00
** [out :: ap-1] 19:28:28 up 8 days, 18:55, 1 user, load average:
0.16, 0.08, 0.02
command finished

If I then remove my passphrase from the cache, and run the same task
with only one node assigned (role :test_role, "ap-1"), it's
successful...

* executing `role_with_several_servers'
* executing "uptime"
servers: ["ap-1"]
Enter passphrase for /home/devuser/.ssh/id_dsa: <passphrase
successfully entered here>
[ap-1] executing command
** [out :: ap-1] 19:32:30 up 8 days, 18:59, 1 user, load average:
0.07, 0.04, 0.00
command finished

The short-term solution seems to be to keep my passphrase cached
(despite the security implications).

~ jeremy



On Sep 29, 11:51 am, Rafael García <r...@aspgems.com> wrote:
> I read badly your firsts emails, so sorry.
>
> Could you test this task?
>
> role :test_role, "ap-1", "ap-2"
>
> desc "Execute task in all servers of a role"
> task :role_with_several_servers, :roles => :test_role do
>    run "uptime"
> end
>
> I executed it locally and worked fine. I'm trying to know why happen it.
>
>
>
> On Wed, Sep 29, 2010 at 7:54 PM, jeyroz <jey.osb...@gmail.com> wrote:
> > The gentleman in the following StackOverflow post seems to have
> > experienced the same issue, however no helpful (permanent) resolution
> > exists...
>
> >http://stackoverflow.com/questions/2718314/capistrano-fails-for-multi...

Lee Hambley

unread,
Sep 29, 2010, 5:06:47 PM9/29/10
to capis...@googlegroups.com
If your key agent prompts you for same passphrase for one key multiple times, it is defective.

morris

unread,
Sep 30, 2010, 10:05:30 AM9/30/10
to Capistrano
I'm wondering the same thing.

I tried the task from above and I'm prompted to enter my passphrase
multiple times in one go (for each server) -- so it inevitably fails.

I'm using win7 + msysgit (which uses mingw32 as a console). The key
agent plays along nicely when working with git repos, never prompting
me for the passphrase. But with cap I'm always prompted at least
once.

At this point I'm chalking it up to the nuances msysgig/mingw32 trying
to replicate these behaviors.

Lee Hambley

unread,
Sep 30, 2010, 10:20:21 AM9/30/10
to capis...@googlegroups.com
On windows using anything other than the PuTTY password agent isn't supported, as it's too unreliable. (Predates my involvement here, but I can believe it.)

jeyroz

unread,
Sep 30, 2010, 11:58:04 AM9/30/10
to Capistrano
Hi Lee, thanks for the response. I'm not sure I agree that it's
"defective" per se, as the prompt (repeated or not) is expected when
not using a caching mechanism. The unexpected occurrence is the
duplicate prompt in rapid succession (with no opportunity to provide a
passphrase) prior to the deploy tasks.

Using ssh-agent to cache the passphrase works just fine and seems to
alleviate the problem, however, I'm still unclear as to why, without
it, I'm unable to simply provide the passphrase prior to each task -
an inconvenient method, but should work never-the-less.

Out of respect for your opinion, I've gone ahead and cleared/
regenerated all public and private DSA identities. Once reestablished,
all key-based communication between servers works as expected, but the
problem discussed here persists.

Thanks again for you input. I'll simply use ssh-agent and move forward
for now.

Best,

~ jeremy

jeyroz

unread,
Sep 30, 2010, 12:46:48 PM9/30/10
to Capistrano
I should clarify my final post and say that when using...
default_run_options[:max_hosts] = 1

I AM indeed given the opportunity to enter a passphrase prior to each
task, as expected. Without that option, caching the passphrase is
absolutely necessary as Capistrano carries out it's tasks across
multiple servers in parallel (as I understand it).

Best,

~ jeremy

Lee Hambley

unread,
Sep 30, 2010, 1:07:38 PM9/30/10
to capis...@googlegroups.com
Jeremy, caching the key (which is the default behaviour of the supported key agents) is indeed a requirement; whilst this may not suit your situation perfectly, it's the only way this can work. I will bear in mind to create successful connections first, that people might use multiple keys (also a problem...for which we don't have a solution) - this would solve you use-case, but regrettably isn't an easy fix.

Sorry I can't be more help, and you are right - calling a key agent defective is a little harsh; however the only practical use of the agent is to cache an unlocked key for easier access, which implies that it should store the key without re-prompting, any overview at the purpose of key agents should confirm this, without that - they aren't serving any purpose. (maybe your agent isn't even supported by Capistrano)

Earlier guides for Capistrano insisted that you use `ssh-agent add` (or your platform's equivalent) to add the relevant keys for your host to the agent prior to attempting a deploy.

- HTH, Lee

jeyroz

unread,
Sep 30, 2010, 2:39:10 PM9/30/10
to Capistrano
Hi Lee, thanks for the response, and I agree completely. You have
indeed been a help and I appreciate it.
Configuring "ssh-agent" is a no-brainer. I'm looking forward to
continuing to use Capistrano.

All the best,

~ jeremy

Lee Hambley

unread,
Sep 30, 2010, 3:34:27 PM9/30/10
to capis...@googlegroups.com
Jeremy,

Glad it helped, sorry for the slightly crappy attitude this morning, just re-read the thread, think I chose the wrong side of the bed this morning. Take care, good luck deploying!

- Lee

jeyroz

unread,
Sep 30, 2010, 5:07:23 PM9/30/10
to Capistrano
No problem at all, Lee.

Before this thread goes cold, I figured I'd contribute a final post to
share my (not "the") final solution. I may have been remiss in my
contribution of one piece of critical information. Within my group,
development takes place on a central development server (rather than
on local workstations). We all use DSA keys to access the server. A
separate user ("deployuser") was created for deployment purposes on
our production servers. No surprises there.

I (needlessly) generated a DSA key-pair for my user ("devuser") on the
development server and registered the public key with "deployuser",
allowing access to production for deployment purposes. It's on the
development server that I was running into the need for key-caching
(ssh-agent is not configured to cache keys by default). What I SHOULD
have done (and now have done) was enabled agent-forwarding
("ForwardAgent yes") and registered my local workstation's public key
with "deployuser". As is common (and as you mentioned, Lee), my local
ssh-agent caches decrypted keys by default, allowing me to sign-in
effortlessly. With agent-forwarding enabled, I'm able to log into the
development server and deploy to production, without re-providing my
passphrase. No need for "default_run_options[:max_hosts] = 1" in my
deploy.rb, and no need to run "ssh-agent add ~/path/to/key" on the
development server. Problem solved.

Thanks again for the back and forth.

Best,

~ jeremy
Reply all
Reply to author
Forward
0 new messages