Published on 12 September 2013 by

This article is republished from the Rackspace Developers blog with the kind permission of our friends from Rackspace, who wanted to share how their customers can manage Cloud Servers with Puppet open source.

In my last post, I discussed a manual install of Puppet between a puppet master and client. Here, I will take that a step further and use Apache libcloud to bootstap a puppet agent node.

First Steps

First, follow the steps in my last article to set up your puppet master. The puppet agent portions are not required as we will bootstrap our agent servers. Now, let’s install the libcloud library:

pip install apache-libcloud==0.11.3

You may need to install other Python libraries like paramiko for deployments.

Create a Shell Script for Installing Puppet

You need to create a short shell script that will be executed on your new puppet agents. This script should install Puppet and configure the client to talk to your puppet master. All of the files I create here are in a local directory called “puppet-deploy.”

~/puppet-deploy/deploy-puppet.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash
# upgrade all packages
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get -y upgrade

# install PuppetLabs repo
wget http://apt.puppetlabs.com/puppetlabs-release-precise.deb
dpkg -i puppetlabs-release-precise.deb

# Install puppet
apt-get -y install puppet
service puppet stop

# Remove SSL directory (will be regenerated when restarted)
rm -rf /var/lib/puppet/ssl

# Configure Puppet to talk to our puppet master
cat >> /etc/puppet/puppet.conf <<-EOF
[agent]
server = puppet.cloudsrvr.info
EOF

# Start the puppet service
cat > /etc/default/puppet <<-EOF
# Defaults for puppet - sourced by /etc/init.d/puppet
# Start puppet on boot?
START=yes
# Startup options
DAEMON_OPTS=""
EOF
service puppet start

# Clean up
export DEBIAN_FRONTEND=dialog

Create a JSON File for Your Credentials

For security purposes, you can create a separate file with your Rackspace Cloud API credentials. Just replace the `username` and `apikey` values with those from your Rackspace Cloud account:

~/puppet-deploy/creds.json

1
2
3
4
{
"user": "username",
"key": "apikey"
}

Use libcloud to Deploy a Puppet Agent

Next we use libcloud to create a server with our SSH key and a puppet agent that is ready to get instructions from our puppet master.

Since I didn’t have the client SSL certificates installed, I’m electing to not verify the SSL certificate from Rackspace. This can open you up to man-in-the-middle attacks, so it’s best to install those. This is for testing only.

~/puppet-deploy/deploy.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env python
import json
import libcloud.security
import libcloud.compute.providers
import libcloud.compute.types
from libcloud.compute.deployment import MultiStepDeployment, ScriptDeployment, SSHKeyDeployment
import os.path

# Import username and API key from a separate JSON file
creds = json.loads(open('creds.json').read())

# Don't verify the SSL cert. USE AT YOUR OWN RISK
libcloud.security.VERIFY_SSL_CERT = False

# Create a connection to the Chicago Rackspace endpoint
RackspaceProvider = libcloud.compute.providers.get_driver(libcloud.compute.types.Provider.RACKSPACE_NOVA_ORD)
driver = RackspaceProvider(creds['user'], creds['key'],
    ex_force_auth_url='https://identity.api.rackspacecloud.com/v2.0/',
    ex_force_auth_version='2.0')

images = driver.list_images() # Get a list of images
sizes = driver.list_sizes() # Get a list of server sizes
size = [s for s in sizes if s.ram == 1024][0] # We want a 1GB server
image = [i for i in images if i.name == 'Ubuntu 12.04 LTS (Precise Pangolin)'][0] # We want Ubuntu 12.04

# Push our SSH key to /root/.ssh/authorized_keys
install_key = SSHKeyDeployment(open(os.path.expanduser("~/.ssh/id_rsa.pub")).read())

# Run the puppet install script
install_puppet = ScriptDeployment(open(os.path.expanduser("deploy-puppet.sh")).read())

# Multiple-step deployment that installs our SSH key and Puppet
multideploy = MultiStepDeployment([install_key, install_puppet])

# Creates our new server, runs deployment steps.
node = driver.deploy_node(name='puppet02', image=image, size=size, deploy=multideploy)

This script is basically authenticating with Rackspace using our API credentials, then creating a 1GB Ubuntu 12.04 server in Chicago with our SSH key. Our puppet install script is then run to upgrade packages and configure puppet. As soon as the server is online, the puppet agent will connect to the puppet master for instructions. The only thing left to do is sign the certificate on the puppet master:

puppet cert --list
"puppet02" (5A:A0:BB:FA:DF:2A:E6:24:70:24:63:85:67:2F:DC:08)
puppet cert --sign puppet02
notice: Signed certificate request for puppet02
notice: Removing file Puppet::SSL::CertificateRequest puppet02 at '/var/lib/puppet/ssl/ca/requests/puppet02.pem'

Your puppet agent will start getting manifests and modules from the puppet master and installing your application.

Learn More

  • Read up on libcloud, or follow the project on Twitter
  • Just getting started with Puppet technologies? [Download our docs as a convenient PDF][docs].
  • We recently unveiled [the Puppet Labs Workshop][online], a self-paced online learning environment where you can learn about Puppet Labs products and technologies no matter what your skill level.
Share via:
Tagged:
The content of this field is kept private and will not be shown publicly.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.