search by tags

for the user

adventures into the land of the command line

capistrano vs ssh for-loops

capistrano was the first remote automation and deployment tool i was exposed to. it is written in ruby, and utilises the rake dsl. you can define your environments (called a stage). you can write up a ruby script (called a task). and then on the command line, you can tell it to run your task on remote hosts in a stage.

there’s a bit of overhead in setting up though. you need to designate a server that will be your capistrano server. this could be your local machine if you just want to muck about.

you also need to specify a user that capistrano will use to login to the remote hosts you want to manage with it. you can use your own or create a new deploy user. and it’s also a good idea to set up that user to use ssh keys to authenticate to these remote hosts.

once you have somewhere to play, install capistrano (requires ruby version 2.0 or higher)

$ gem install capistrano

this will put a capistrano directory somewhere.., and inside it normally looks like this:

|-- Capfile
|-- config
|   |-- deploy
|   |   |-- my_funky_environment.rb
|   |   `-- sample_production.rb
|   `-- deploy.rb
`-- lib
    `-- capistrano
        `-- tasks
            |-- my_funky_task1.cap
            `-- my_funky_task2.rake

inside the files in the deploy directory you can specify hosts like this:

server 'myhost1', roles: %w{webserver}
server 'myhost2', roles: %w{database}

you can specify a server by hostname, and also assign it a role. then in your cap files (or rake files), you create a script essentially, that will do stuff on these servers for you. it could be as simple as:

namespace :host_checker do

        desc "Check connectivity to remote hosts"
        task :checking do
                on roles(:all), in: :sequence do |host|
                        puts "+ Checking.."
                        execute ("hostname")

but you can get as complicated as you want, deploying packages, changing config files with erb templates, etc.

to run capistrano from the command line, you have to go to the root of the capistrano directory, the one with the Capfile in it.

[[email protected] capistrano]$ cap -T
cap host_checker:checking   # Check connectivity to remote hosts

this will show me a list of all available tasks that can be run to run it, the syntax is:

[[email protected] capistrano]$ cap stage task
[[email protected] capistrano]$ cap my_funky_environment host_checker

this will run every task in the namespace :host_checker (there’s only one task called :checking, but you can have more in the same namespace), on every server in my_funky_environment.rb

you can specify a specific host or environment as well

$ cap my_funky_environment host_checker:checking --host myhost1

so … capistrano aye? pretty nifty, i think it’s nice, and good tool if you manage a smallish number of servers and you are comfortable with ruby.

however, after a while i found myself using capistrano to do tasks that i had to do to once or twice on every server, such as change a config file, restart a service, check storage space, check this, check that. sometimes i was lazy to write a new task, especially when i knew i was only going to use it a few times.

then i met a guy named marcus, and he taught me an awesome thing called an ssh for loop, and i’ve been using it ever since for these once off many server jobs. obviously you need to already have your ssh keys set up on the remote hosts, then you can smash them like so.

hostlist="myhost1 myhost2 myhost3"
for host in $hostlist; do
ssh -qt $host "hostname"
printf "

crude and awesome. the best!