Deployment

This functionality depends on the paramiko library which is not installed by default when installing apache-libcloud package. You can be install it manually using pip - pip install paramiko.

Deployment functionality allows you to create a node and after it has been started install an SSH key and / or run arbitrary shell commands on it. It works by first calling create_node and then after the node has been fully started SSHing into the node and running a shell script on it.

We assume that a node has been fully started when a returned state is NodeState.RUNNING and when it has a public IP address assigned.

Keep in mind that Libcloud is not a replacement for a configuration management tool so it shouldn't be used as such.

Provider Images and Default Usernames

Libcloud uses root username when running a command on the remote server. A lot of images use a different default username (e.g. ubuntu for some ubuntu AWS AMI's, bitnatmi for some Bitnami AWS AMI's, etc.).

This means deployment will fail if you don't specify a correct username using the ssh_username keyword argument like it's shown in the example 2.

Example 1 - Deploying a Rackspace Node using password authentication and installing your SSH key and Puppet on it

from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.compute.deployment import MultiStepDeployment, ScriptDeployment, SSHKeyDeployment
import os

RACKSPACE_USER = 'your username'
RACKSPACE_KEY = 'your key'

Driver = get_driver(Provider.RACKSPACE)
conn = Driver(RACKSPACE_USER, RACKSPACE_KEY)

# read your public key in
# Note: This key will be added to the authorized keys for the root user
# (/root/.ssh/authorized_keys)
sd = SSHKeyDeployment(open(os.path.expanduser("~/.ssh/id_rsa.pub")).read())
# a simple script to install puppet post boot, can be much more complicated.
script = ScriptDeployment("apt-get -y install puppet")
# a task that first installs the ssh key, and then runs the script
msd = MultiStepDeployment([sd, script])

images = conn.list_images()
sizes = conn.list_sizes()

# deploy_node takes the same base keyword arguments as create_node.
node = conn.deploy_node(name='test', image=images[0], size=sizes[0], deploy=msd)
# <Node: uuid=..., name=test, state=3, public_ip=['1.1.1.1'], provider=Rackspace ...>
# the node is now booted, with your ssh key and puppet installed.

Example 2 - Deploying an EC2 Node using SSH key authentication and installing Puppet on it

from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.compute.deployment import ScriptDeployment

EC2_ACCESS_ID = 'your access key'
EC2_SECRET = 'your secret'

Driver = get_driver(Provider.EC2_US_EAST)
conn = Driver(EC2_ACCESS_ID, EC2_SECRET)

# a simple script to install puppet post boot, can be much more complicated.
script = ScriptDeployment("apt-get -y install puppet")

# Ubuntu 10.04
image = [i for i in driver.list_images() if i.id =='ami-09965860' ][0]
size = [s for s in driver.list_sizes() if s.id == 't1.micro'][0]

# Name of the SSH key which is automatically installed on the server.
# Key needs to be generated and named in the AWS control panel.
key_name = 'my_default'

# Path to the private key created using the AWS control panel.
key_path = '/home/user/path/to/key.pem'

# deploy_node takes the same base keyword arguments as create_node.
node = conn.deploy_node(name='test', image=image, size=size, deploy=script,
                        ssh_username='ubuntu', ssh_key=key_path,
                        ex_keyname=key_name)
# <Node: uuid=..., name=test, state=3, public_ip=['1.1.1.1'], provider=EC2 ...>
# the node is now booted, with puppet installed.