Marionetta
Marionetta is a ruby library for executing commands on one or more remote machines via SSH.
It provides puppet provisioning without the need for a puppet master and can also deploy your application code (with rollbacks) via rsync. With a RakeHelper you can integrate it into your workflow with ease.
Installing the gem is the best way to start using Marionetta. You can do this from command line:
gem install marionetta
Or – better yet – in your Gemfile:
source 'http://rubygems.org'
gem 'marionetta'
Documentation
Marionetta has annotated source that provides the bulk of documentation for Marionetta. Hopefully you'll find the annotations informative on how to use this library. If you feel they could be improved please create an issue on GitHub.
If you prefer looking at the code, check it out on github.
Using Marionetta in your Rakefile
Marionetta provides an easy mechanism to generate rake tasks for each of your groups.
In your Rakefile you can do something like so:
require 'marionetta/group'
require 'marionetta/rake_helper'
staging = Marionetta::Group.new(:staging)
staging.add_server do |s|
s[:hostname] = 'staging.example.com'
s[:ssh][:flags] << ['-i', 'keys/private.key']
s[:puppet][:manifest] = 'puppet/manifest.pp'
s[:deployer][:from] = '/my-app'
s[:deployer][:to] = '/home/staging/www'
end
Marionetta::RakeHelper.install_group_tasks(staging)
The tasks puppet:staging:install
, puppet:staging:update
,
deployer:staging:deploy
and deployer:staging:rollback
will now be available in your Rakefile.
Defining a group of servers
Marionetta allows you to describe and manipulate a number of servers in parallel via SSH. First you need to define a group of servers:
require 'marionetta/group'
servers = Marionetta::Group.new(:production)
servers.add_server do |s|
s[:hostname] = '[email protected]'
end
servers.add_server do |s|
s[:hostname] = '[email protected]'
s[:ssh][:flags] << ['-i', 'keys/private.key']
end
Looping over a group
Continuing on from our example of defining a group of servers above, we will now iterate over the servers:
# Each block executes in it's own asynchronous thread
servers.each_server do |s|
cmd = Marionetta::CommandRunner.new(s)
# Send a command via SSH
cmd.ssh('whoami') do |out, err|
puts out.read
end
# Get a file
cmd.get('/var/backups/database')
# Put a file
cmd.put('/etc/motd')
end
Playing puppet master
Instead of running a puppet master server you can use Marionetta to orchestrate a number instances.
require 'marionetta/group'
servers = Marionetta::Group.new(:production)
servers.add_server do |s|
s[:hostname] = '[email protected]'
s[:puppet][:manifest] = 'puppet/manifest.pp'
s[:puppet][:modules] = 'puppet/modules'
end
# Install and update puppet on each server according to
# each servers puppet settings
servers.manipulate_each_server(:puppet, :update)
Using the deployer
Also included is a deployment mechanism similar to capistrano. You can use this to deploy releases of folders from a local machine to a remote one over SSH.
require 'marionetta/group'
staging = Marionetta::Group.new(:staging)
staging.add_server do |s|
s[:hostname] = 'staging.example.com'
s[:deployer][:from] = '/my-app'
s[:deployer][:to] = '/home/staging/www'
end
staging.manipulate_each_server(:deployer, :deploy)
The deployer also supports listing releases:
staging.manipulate_each_server(:deployer, :releases) do |server, releases|
puts server[:hostname], releases
end
Oh and you can rollback to the last release too!
staging.manipulate_each_server(:deployer, :rollback)
Upcoming
- Add permissions with Manipulators::Deployer (v0.4.x)
- Remove rollback feature... we don't need rollbacks IMO. (v0.5.x)
- Remove Marionetta::Manipulators::Debloyer (v0.5.x)
- Use rye for commands (https://github.com/delano/rye) (v0.5.x)
- Use a single SSH connection per task (v0.5.x)
- Ensure concurrency is tested and therefore guaranteed (v0.5.x)
Author
Luke Morton a.k.a. DrPheltRight
Collaborating
Create an issue and send a pull request if you get any bright ideas or have a fix. Feel free to create an issue and not send one too, feedback is always welcome.
Testing
To test run this on your command line:
rake
You need to ensure spec/vagrant/key
has 0600
permissions.
Generating documentation
Generate documentation using the following command:
rake doc
Publishing the documentation to GitHub pages is a little messy to say the least. Try this:
rake doc
mv docs docs-new
git checkout gh-pages
rm -rf docs
mv -f docs-new docs
git add docs
git commit -m "Update documentation."
git push origin gh-pages
License
Licensed under MIT by Luke Morton, 2012.