Automating application deployment using puppet in eucalyptus/aws cloud.




In this example a user can pass userdata parameter which would decide the role of the emi/ami that would be launched, and based on the role applications would be deployed by the 

puppet master.



 A working puppet master server

an ami/emi with puppet client installed.





On the ami/emi template update the rc.local as following:



curl –retry 3 –retry-delay 10 -o $TMP_FILE

if [ -s $TMP_FILE ]; then

echo “Downloaded user data in $TMP_FILE”

if [ “`head -c 2 $TMP_FILE`” = “#!” ]; then

chmod a+x $TMP_FILE

echo “User data is a script: executing it”



ROLE=`cat $TMP_FILE | grep role | cut -d= -f2 | col -b`

cat > /usr/lib/ruby/site_ruby/1.8/facter/bentest.rb  <<EOF

Facter.add(:role) do

  setcode do

    role = ‘$ROLE’




PUPPET=`cat $TMP_FILE | grep puppet | cut -d= -f2`

echo “$PUPPET puppet” >> /etc/hosts;




What this does is creates a custom fact in the vm called as ‘role’ and assigns a value to it, this fact would be read by the manifests in the puppet master to decide what recipes should be pushed to the node.

it also makes an entry of the puppet master on the client node.(This is optional as you can define a hostname in the emi template and make sure the dns points it to right puppet server).


On the puppet master:

The first thing that the puppet master needs to do is identify the node and pass appropriate configurations, for this as we mentioned above the puppet master would look at the facter ‘role’ and decide the configuration to be sent.


sample on how to accomplish that:






#Has all node configuration

import “nodes.pp”

import  “modules.pp”

# The filebucket option allows for file backups to the server

filebucket { main: server => ‘puppet’ }


# Set global defaults – including backing up all files to the main filebucket and adds a global path

File { backup => main }

Exec { path => “/usr/bin:/usr/sbin/:/bin:/sbin” }





node default{

include vmnodes::classifiers



module for vmode calssifers




import “classifiers.pp”


====Here it decides based on facter what configuration needs to be pushed.=============



class vmnodes::classifiers{


case $role {

“dbserver” : {

include mysql



case $role {

“appserver” : {

include httpd






import vmnodes