Deployment

Compute part of the API exposes a simple deployment functionality through the libcloud.compute.base.NodeDriver.deploy_node() method. This functionality is there to help you bootstrap a new server. It allows you to perform tasks such as:

  • Install your public SSH key on the server
  • Install configuration management software
  • Add an initial user account
  • Install an initial set of SSL certificates and keys on the server

As noted above, this functionality is there to help you bootstrap a server and is not a replacement for a configuration management software such as Chef Puppet, Salt, CFEngine and others.

Once your server has been bootstrapped, libcloud.deploy task should be done and replaced by other tools such as previously mentioned configuration management software.

Deployment classes

Deployment module exposes multiple classes which make running common bootstrap tasks such as installing a file and running a shell command on a server easier.

All the available classes are listed below.

class libcloud.compute.deployment.SSHKeyDeployment(key)[source]

Installs a public SSH Key onto a server.

Parameters:key (str or File object) – Contents of the public key write or a file object which can be read.
class libcloud.compute.deployment.FileDeployment(source, target)[source]

Installs a file on the server.

Parameters:
  • source (str) – Local path of file to be installed
  • target (str) – Path to install file on node
class libcloud.compute.deployment.ScriptDeployment(script, args=None, name=None, delete=False)[source]

Runs an arbitrary shell script on the server.

This step works by first writing the content of the shell script (script argument) in a *.sh file on a remote server and then running that file.

If you are running a non-shell script, make sure to put the appropriate shebang to the top of the script. You are also advised to do that even if you are running a plan shell script.

Parameters:
  • script (str) – Contents of the script to run.
  • args (list) – Optional command line arguments which get passed to the deployment script file.
  • name (str) – Name of the script to upload it as, if not specified, a random name will be chosen.
  • delete (bool) – Whether to delete the script on completion.
class libcloud.compute.deployment.ScriptFileDeployment(script_file, args=None, name=None, delete=False)[source]

Runs an arbitrary shell script from a local file on the server. Same as ScriptDeployment, except that you can pass in a path to the file instead of the script content.

Parameters:
  • script_file (str) – Path to a file containing the script to run.
  • args (list) – Optional command line arguments which get passed to the deployment script file.
  • name (str) – Name of the script to upload it as, if not specified, a random name will be chosen.
  • delete (bool) – Whether to delete the script on completion.
class libcloud.compute.deployment.MultiStepDeployment(add=None)[source]

Runs a chain of Deployment steps.

Parameters:add (list) – Deployment steps to add.

Using deployment functionality

This section describes how to use deployment functionality and libcloud.compute.base.NodeDriver.deploy_node() method.

deploy_node method allows you to create a cloud server and run bootstrap commands on it. It works in the following steps:

  1. Create a server (same as create_node, in fact it calls create_node underneath)
  2. Wait for the server to come online and SSH server to become available
  3. Run provided bootstrap step(s) on the server

As noted above, second step waits for node to become available which means it can take a while. If for some reason deploy_node is timing out, make sure you are using a correct ssh_username. You can troubleshoot deployment issues using LIBCLOUD_DEBUG method which is described on the troubleshooting page.

libcloud.compute.base.NodeDriver.deploy_node() takes the same base keyword arguments as the libcloud.compute.base.NodeDriver.create_node() method and couple of additional arguments. The most important ones are deploy and auth:

  • deploy argument specifies which deployment step or steps to run after the server has been created.
  • auth arguments tells how to login in to the created server. If this argument is not specified it is assumed that the provider API returns a root password once the server has been created and this password is then used to log in. For more information, please see the create_node and deploy_node method docstring.

Some examples which demonstrate how this method can be used are displayed below.

Run a single deploy step using ScriptDeployment class

The example below runs a single step and installs your public key on the server.

from __future__ import with_statement

import os

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

# Path to the public key you would like to install
KEY_PATH = os.path.expanduser('~/.ssh/id_rsa.pub')

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

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

with open(KEY_PATH) as fp:
    content = fp.read()

# Note: This key will be added to the authorized keys for the root user
# (/root/.ssh/authorized_keys)
step = SSHKeyDeployment(content)

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=step)

Run multiple deploy steps using MultiStepDeployment class

The example below runs two steps on the server using MultiStepDeployment class. As a first step it installs you SSH key and as a second step it runs a shell script.

from __future__ import with_statement

import os

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

# Path to the public key you would like to install
KEY_PATH = os.path.expanduser('~/.ssh/id_rsa.pub')

# Shell script to run on the remote server
SCRIPT = '''#!/usr/bin/env bash
apt-get -y update && apt-get -y install puppet
'''

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

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

with open(KEY_PATH) as fp:
    content = fp.read()

# Note: This key will be added to the authorized keys for the root user
# (/root/.ssh/authorized_keys)
step_1 = SSHKeyDeployment(content)

# A simple script to install puppet post boot, can be much more complicated.
step_2 = ScriptDeployment(SCRIPT)

msd = MultiStepDeployment([step_1, step_2])

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)