fabric

Fabric is a small ruby app to perform tasks on servers via SSH. Built around net/ssh and taking heavy inspiration from Capistrano, it allows you to create policies for server management and perform sysadmin tasks without the need for a process/daemon/dependency or even ruby being installed on the remote server.

Its primary purpose at the moment is to manage user access and ssh keys across a large cluster.

Installation

gem install fabric

Usage

Fabric parses a ‘map’ of your servers. On the simplest level, this will look something like:

Map.draw do |map|
  map.role 'web server', '192.168.1.2'
  map.user 'sammy'
  map.grant 'sammy', 'web server'
end

Let’s take this apart:

Map.draw do |map|
  # Define a role called 'web server', and pass the IP of a host that is within the role
  map.role 'web server', '192.168.1.2'

  # Define a user - we'll look for sammy.pub in the key_repository (by default, './keys')
  map.user 'sammy'

  # Give the 'sammy' user access to all servers that are within the 'web server' role
  map.grant 'sammy', 'web server'
end

Save this file (let’s say you called it map.rb) and run it as so:

fab map.rb

For a detailed output of the process and commands being run, enable narration with:

fab map.rb --narrate

Or

fab map.rb -n

This will then execute the map file as pure Ruby, and perform the necessary operations

More complex mapping

Map.draw do |map|

  # Specify the directory to look for users' ssh keys:
  map.key_repository 'other_key_repository'

  # Pass multiple users if you like
  map.user 'sammy', 'joey'

  map.role 'file server', '2.3.4.5'
  map.role 'database', '1.2.3.4'

  # Grant all users access to all servers
  map.grant :all, :all

  # Create a namespace - this will contain all the users defined in the parent,
  # but any users and roles added will only exist within this block
  map.namespace do |cool_website|

    # pass multiple IPs to add multiple hosts to this role
    cool_website.role 'memcached', '1.1.1.1', '2.2.2.2'

    # This user will only exist within the current namespace
    cool_website.user 'timmy'

    # Add all our users, including from the parent, to the memcached server:
    grant :all, 'memcached'

    # Timmy isn't allowed onto the syslogging box :(
    cool_website.role 'syslog', '3.3.3.3'
    grant "timmy", :all, :except => ["syslog"]

  end
end

Testing Requirements

You want to get involved? Great! Grab the code and check dependencies with:

rake check_dependencies

Previously, bundler (github.com/wycats/bundler) was used to package dependencies; unfortunately this doesn’t seem to play that nicely with jeweler.

A lot of the tests this gem rely on being able to ssh to a target machine. This can be your development machine, but it’s easier if it’s a Virtual Machine (try out something from virtualbox.org). To run tests, copy the ‘test.yml.example’ to ‘test.yml’ file to point at a machine which can be safely used to test SSH commands.

Note: add the moment, the tests assume at various points a Linux, rather than an OS X, way of doing things.

Wishlist

Features

  • Ability to automatically create users that are granted a permission

  • Business-friendly report output to give current setup

Technical

  • More robust testing of executable and options

  • Better SSH error trapping

  • Threading/forking for speed

Copyright © 2009 Sam Phillips. See LICENSE for details.